Admiral UI Kit
Admiral UI kit for admin panels. One component set for every project; one 8-line brand file per client (colours, logo, font, radius, density). Everything else, light and dark included, is derived from those inputs.
Status: v0.5.1, not adopted anywhere yet. See CHANGELOG.md. Laravel package tested on Laravel 10-13.
Try it
Open the playground: a working sample admin with a theme builder. Change the brand colour, radius, density and light or dark mode and see every screen follow.
Open the component gallery: every component, live, with its Blade and HTML to copy.
Install
Before you start: the repo is private and the package isn’t on Packagist, so ask the kit’s owner for GitHub access first. Without it, every install command below fails.
Laravel (10, 11, 12, 13). One command after Composer; see docs/LARAVEL.md.
Point Composer at the private repo first:
composer config repositories.admiral-ui '{"type":"vcs","url":"https://github.com/yeppymp/admiral-ui-kit","no-api":true}'
# The repo is private and not on Packagist: you need GitHub access, then point Composer at it first.
composer config repositories.admiral-ui '{"type":"vcs","url":"https://github.com/yeppymp/admiral-ui-kit","no-api":true}'
composer require admiral/ui-kit:^0.5
php artisan admin-ui:install --name="Northwind Admin" --brand=7c3aed
php artisan admin-ui:page Segment --model --fields="name,status:select[draft|live]"
Anything else (Node, Nuxt, React, Python, Go, Rails, Craft, plain HTML). Add two files, write the same class names. The HTML for every component is in the gallery.
npm install github:yeppymp/admiral-ui-kit#v0.5.1
import "@admiral/ui-kit/admiral-ui.css";
import "@admiral/ui-kit/admiral-ui.js";
No bundler? Copy everything in laravel/resources/dist/ into one folder and link admiral-ui.css and admiral-ui.js. The JS loads admiral-ui.fields.js from the same folder when a page needs it. Add class="adm-root" to <body>, then one brand file.
React or Vue: import { Button, Combobox } from "@admiral/ui-kit/react" (or /vue). See docs/REACT-AND-VUE.md.
Docs site: run vendor/bin/phpunit, then cd docs-site && npm ci && npm run build, and open docs-site/dist/index.html.
With Tailwind v4: @import "@admiral/ui-kit/tailwind.css"; @import "tailwindcss"; (kit first) gives bg-base text-subtle border-line.
With shadcn: import @admiral/ui-kit/tokens.css, @admiral/ui-kit/shadcn-bridge.css, then a brand file, all after your shadcn CSS (import them in main.tsx). shadcn components then follow the brand, including its .dark class. Tested in a real project made with the shadcn CLI.
3. Themes included
| File | Use |
|---|---|
brands/admiral.css | Default. Matches Admiral UI’s existing tokens (--ad-blue #2a7de1, --ad-action #2168bd, Roboto). |
brands/twt.css | TWT Admin: navy sidebar, teal accent (from the “Version B” prototype). |
brands/example-harbor.css, example-ember.css, example-graphite.css | Examples showing the range: compact teal, light amber (black button text), monochrome. |
brands/_template.css | Start here for a new client. |
4. Update colours, logo, font for a client
Everything a client changes is in one brand file (8 lines):
[data-brand="acme"] {
--ad-brand: #7c3aed; /* identity: logo mark, active nav, single-series charts */
--ad-action: #6d28d9; /* buttons, links, focus (or initial = brand) */
--ad-sidebar: initial; /* or a colour, e.g. #061b2c for a navy sidebar */
--ad-logo: url("/brand/acme-logo.svg"); /* or initial and put <img>/<svg> in the logo slot */
--ad-font-sans: "Roboto", ui-sans-serif, system-ui, sans-serif;
--ad-radius: 8px;
--ad-density: 1;
--ad-neutral-tint: 0.006;
}
Three ways to produce it:
- Visually: open the demo, go to Brand & tokens → Theme builder, pick colours, upload the logo, choose font/radius/density, and press Copy. Contrast is checked live.
- By hand: copy
brands/_template.css. - Laravel:
.env(ADMIN_UI_BRAND="#7c3aed",ADMIN_UI_LOGO=/brand/acme.svg). Quote the colour: an unquoted#starts a comment in.env. See docs/LARAVEL.md.
Then check it:
node scripts/check-contrast.mjs brands/acme.css
The script fails if button text, links, focus rings or the sidebar would miss WCAG AA. Example: Admiral’s #2a7de1 alone gives white button text only 3.9:1, which is why Admiral keeps a darker --ad-action.
Naming: follows Kumo and shadcn
- Tokens use Kumo’s roles:
canvas / base / elevated / recessed,text-strong / text / text-subtle / text-inactive,line / hairline,brand / danger / warning / success / info. - Variants use the names Kumo and shadcn share:
primary, secondary, outline, ghost, destructive, link. Sizes:xs, sm, (base), lg. Shapes:square, circle. - Card follows shadcn’s anatomy:
__header, __title, __description, __content, __footer. - CSS variables extend Admiral’s
--ad-*. Old names (--ad-blue,--ad-ink,--ad-muted,--ad-border) keep working. - Classes use
adm-, notad-, because ad blockers hide.ad-*elements.
Light / dark
The default follows the OS. Force a mode with data-mode="light" or data-mode="dark" on any element, including a single panel.
There are no dark: classes. Every token is a light-dark() pair.
Scoping
data-brand="acme" works on any element, not just <html>. A multi-tenant admin can therefore show a client preview inside its own chrome.
Keep it clean: CI check
node scripts/check-raw-colors.mjs resources/views app/components
The script exits with code 1 on hex/rgb literals, raw Tailwind palette classes (bg-blue-500) or dark: variants.
Each of these is a place where the next client re-skin would need a code edit. Today a real client admin has 85.
Browser support
The system needs CSS relative colour syntax and light-dark(): Chrome/Edge 123+, Safari 18+, Firefox 128+. That’s fine for internal admin tools.
For anything public-facing, check the audience’s browsers first.
Not done yet
- No npm or Packagist release. Install from the private GitHub repo.
- Not adopted in a live product yet. German and French text still needs a native check.