Theming
Every value an Atlas component draws — color, radius, shadow, type, spacing — comes from a CSS variable. You restyle Atlas by giving those variables new values, never by out-specifying a component's rules.
The variables are named after the Tailwind variable they feed (--color-primary,
--radius-input, --font-heading), so every token is also a utility:
bg-primary, rounded-input, font-heading. Values live in
:root and .dark in the theme file; this page reads that file from the
installed package, so what you see below is what Atlas ships.
Token convention
Colors come in pairs: a fill and its -foreground, the color that is legible on
that fill. The fill is used for the background and the foreground for text and icons on it.
Never pick a text color by hand on a colored background; use the pair.
:root {
--color-primary: #615fff;
--color-primary-foreground: #ffffff;
}
.my-banner {
background-color: var(--color-primary);
color: var(--color-primary-foreground);
}
The bridge turns every pair into utilities:
<div class="bg-primary text-primary-foreground">…</div> <div class="bg-card text-card-foreground">…</div> <p class="text-muted-foreground">…</p>
A few structural tokens have no pair: --color-border, --color-input and
--color-ring, and the three mix tokens hover states are built from.
Theme tokens
Every token in the default theme, with its light and dark value and the components that read
it. Change a value in your own :root or .dark and everything listed
under Used by follows.
Abstract colors
| Token | Light | Dark | Use for | Used by |
|---|---|---|---|---|
--color-shade |
black
|
black
|
The dark end of a color-mix(): black by default |
badge, button, pill-filter |
--color-tint |
white
|
white
|
The light end of a color-mix(): white by default |
badge, button, pill-filter |
--color-mix |
var(--color-shade)
|
var(--color-tint)
|
What hover states mix towards: shade in light mode, tint in dark | badge, button, pill-filter |
Surface colors
| Token | Light | Dark | Use for | Used by |
|---|---|---|---|---|
--color-background |
#f4f4f5
|
#27272a
|
The page. The <body> background; every other surface sits above or below it |
base styles |
--color-foreground |
#27272a
|
#f4f4f5
|
Text and icons on the page, and the default text color | badge, button, base styles |
--color-raised |
#fafafa
|
#2c2c2e
|
One step up. Regions of the page layout set off from the page: sections, side columns | — |
--color-raised-foreground |
#27272a
|
#ffffff
|
Text and icons on raised | — |
--color-card |
#ffffff
|
#303033
|
Elevated. Cards, dashboard panels and settings panels, with their content; on the page or on raised | — |
--color-card-foreground |
#27272a
|
#ffffff
|
Text and icons on card | — |
--color-overlay |
#ffffff
|
#353538
|
Floating. Popovers, dropdown menus, tooltips and other overlays; the select option list | employee-card, select |
--color-overlay-foreground |
#27272a
|
#ffffff
|
Text and icons on overlay | employee-card, select |
--color-muted |
#ececee
|
#232325
|
Below the page. Sunken bands and wells, disabled fields | badge, button, input, input-choice |
--color-muted-foreground |
#6a6a74
|
#9f9fa9
|
Lower-emphasis text on any surface: descriptions, placeholders, captions | description, input, select |
Brand colors
| Token | Light | Dark | Use for | Used by |
|---|---|---|---|---|
--color-primary |
#615fff
|
#a3b3ff
|
Main actions, links, active states | badge, button, checkbox, contact-list, hamburger, icon, input, input-choice, list, pill-filter, swiper, tabs, text-link, toggle |
--color-primary-foreground |
#ffffff
|
#1e1a4d
|
Text and icons on primary | badge, button, pill-filter, tabs, toggle |
--color-secondary |
#6f68a6
|
#716b98
|
Supporting actions, tags | badge, button, contact-list, icon, pill-filter, text-link |
--color-secondary-foreground |
#ffffff
|
#ffffff
|
Text and icons on secondary | badge, button, pill-filter |
--color-accent |
#fe9a00
|
#fee685
|
Highlights, call-outs, decorative emphasis | badge, button, contact-list, icon, pill-filter, text-link |
--color-accent-foreground |
#000000
|
#461901
|
Text and icons on accent | badge, button, pill-filter |
Status colors
| Token | Light | Dark | Use for | Used by |
|---|---|---|---|---|
--color-info |
#0069a8
|
#80d3ef
|
Informational messages and tips | badge, button, pill-filter, text-link |
--color-info-foreground |
#ffffff
|
#052f4a
|
Text on info | badge, button, pill-filter |
--color-success |
#007a55
|
#5ee9b5
|
Confirmation, positive outcomes | badge, button, pill-filter, text-link |
--color-success-foreground |
#ffffff
|
#00422b
|
Text on success | badge, button, pill-filter |
--color-warning |
#ca3500
|
#ffb86a
|
Caution, non-blocking issues | badge, button, pill-filter, text-link |
--color-warning-foreground |
#ffffff
|
#7e2a0c
|
Text on warning | badge, button, pill-filter |
--color-danger |
#e7000b
|
#ffa2a2
|
Errors, invalid fields, destructive actions | badge, button, error, pill-filter, text-link |
--color-danger-foreground |
#ffffff
|
#75070f
|
Text on danger | badge, button, pill-filter |
Structural colors
| Token | Light | Dark | Use for | Used by |
|---|---|---|---|---|
--color-border |
#c4c6cc
|
#5c5c63
|
Borders and dividers, form controls included; the default border color of every element | accordion, checkbox, image, input, input-choice, list, tabs, toggle, base styles |
--color-input |
transparent
|
color-mix(in oklab, var(--color-shade) 10%, transparent)
|
Form control fill; transparent, so a field shows the surface it sits on | checkbox, input, input-choice |
--color-ring |
var(--color-primary)
|
var(--color-primary)
|
Focus rings; follows primary unless a theme sets its own | input, base styles |
Font families
| Token | Value | Use for | Used by |
|---|---|---|---|
--font-sans |
ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"
|
The sans-serif stack | — |
--font-serif |
ui-serif, Georgia, Cambria, "Times New Roman", Times, serif
|
The serif stack | — |
--font-mono |
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace
|
The monospace stack | — |
--font-heading |
var(--font-sans)
|
Headings; defaults to --font-sans |
heading |
--font-body |
var(--font-sans)
|
Body text and controls; defaults to --font-sans |
badge, button, input, pill-filter, base styles |
Type scale
| Token | Value | From 64rem | Use for | Used by |
|---|---|---|---|---|
--text-display |
var(--text-6xl)
|
var(--text-7xl) |
Display size; text-display |
heading |
--text-display--line-height |
1
|
|
Display line height | heading |
--text-display--font-weight |
700
|
|
Display weight | heading |
--text-h1 |
var(--text-5xl)
|
var(--text-6xl) |
h1 size; text-h1 |
heading |
--text-h1--line-height |
1
|
|
h1 line height | heading |
--text-h1--font-weight |
700
|
|
h1 weight | heading |
--text-h2 |
var(--text-4xl)
|
var(--text-5xl) |
h2 size; text-h2 |
heading |
--text-h2--line-height |
1.125
|
|
h2 line height | heading |
--text-h2--font-weight |
700
|
|
h2 weight | heading |
--text-h3 |
var(--text-3xl)
|
var(--text-4xl) |
h3 size; text-h3 |
heading |
--text-h3--line-height |
1.25
|
|
h3 line height | heading |
--text-h3--font-weight |
700
|
|
h3 weight | heading |
--text-h4 |
var(--text-2xl)
|
var(--text-3xl) |
h4 size; text-h4 |
heading |
--text-h4--line-height |
1.25
|
|
h4 line height | heading |
--text-h4--font-weight |
700
|
|
h4 weight | heading |
--text-h5 |
var(--text-xl)
|
var(--text-2xl) |
h5 size; text-h5 |
heading |
--text-h5--line-height |
1.25
|
|
h5 line height | heading |
--text-h5--font-weight |
700
|
|
h5 weight | heading |
--text-h6 |
var(--text-lg)
|
var(--text-xl) |
h6 size; text-h6 |
heading |
--text-h6--line-height |
1.25
|
|
h6 line height | heading |
--text-h6--font-weight |
700
|
|
h6 weight | heading |
Spacing
| Token | Value | Use for | Used by |
|---|---|---|---|
--spacing |
0.25rem
|
The base unit of every spacing utility: p-4 is calc(var(--spacing) * 4) |
badge, button, card, checkbox, employee-card, input, input-choice, list, pill-filter, tabs, toggle |
Radius
| Token | Value | Use for | Used by |
|---|---|---|---|
--radius |
0.25rem
|
The base unit of the radius scale | — |
--radius-input |
var(--radius-sm)
|
Buttons, inputs, selects, textareas, tabs | button, checkbox, input, pill-filter, tabs, textarea |
--radius-selector |
var(--radius-sm)
|
Badges, checkboxes | badge, input-choice |
--radius-card |
var(--radius-xl)
|
Cards, videos, images | card, employee-card, image, video |
Shadows
| Token | Value | Use for | Used by |
|---|---|---|---|
--shadow-color |
#000000
|
The color mixed into every shadow size | — |
--shadow-2xs |
0 1px color-mix(in oklab, var(--shadow-color) 5%, transparent)
|
Hairline shadow | — |
--shadow-xs |
0 1px 2px 0 color-mix(in oklab, var(--shadow-color) 5%, transparent)
|
Hovered inputs and choices | input, input-choice |
--shadow-sm |
0 1px 3px 0 color-mix(in oklab, var(--shadow-color) 10%, transparent), 0 1px 2px -1px color-mix(in oklab, var(--shadow-color) 10%, transparent)
|
The toggle thumb | toggle |
--shadow-md |
0 4px 6px -1px color-mix(in oklab, var(--shadow-color) 10%, transparent), 0 2px 4px -2px color-mix(in oklab, var(--shadow-color) 10%, transparent)
|
Hovered cards | card, employee-card |
--shadow-lg |
0 10px 15px -3px color-mix(in oklab, var(--shadow-color) 10%, transparent), 0 4px 6px -4px color-mix(in oklab, var(--shadow-color) 10%, transparent)
|
Larger floating elements | — |
--shadow-xl |
0 20px 25px -5px color-mix(in oklab, var(--shadow-color) 10%, transparent), 0 8px 10px -6px color-mix(in oklab, var(--shadow-color) 10%, transparent)
|
Larger floating elements | — |
--shadow-2xl |
0 25px 50px -12px color-mix(in oklab, var(--shadow-color) 25%, transparent)
|
The deepest shadow | — |
--shadow |
var(--shadow-sm)
|
The default hover shadow of buttons, badges and pills; an alias of --shadow-sm |
badge, button, checkbox, pill-filter |
Opacity
| Token | Value | Use for | Used by |
|---|---|---|---|
--opacity-disabled |
0.5
|
Every disabled state | badge, button, checkbox, pill-filter, radio, text-link, toggle |
Surfaces
Surface tokens are levels, from below the page up to floating. Pick the level by what the element is:
--color-background— the page itself.--color-raised— one step up: regions of the page layout, such as sections and side columns.--color-card— elevated surfaces and their content: cards, dashboard panels, settings panels. A card works on a raised section too.--color-overlay— floating surfaces and their content: popovers, dropdown menus, tooltips and other overlays.--color-muted— below the page: sunken bands, wells, disabled fields.
Each has a -foreground. --color-muted-foreground is the exception that
reads on every surface: use it for lower-emphasis text anywhere.
--color-muted
--color-background
--color-raised
--color-card
--color-overlay
Text on a surface
Set a surface's fill and its -foreground together, on the element that draws the
surface. Components that draw text or a glyph with no background of their own — heading,
label, inactive tab, hamburger, swiper bullet — take currentColor, so they
follow whatever surface they land on. A text link is primary by default; give it
an empty color and it follows the surface too:
<section class="bg-primary text-primary-foreground">
<x-atlas::heading :level="2">Ready to order?</x-atlas::heading>
<x-atlas::text-link href="/contact" color="">Talk to us</x-atlas::text-link>
</section>
The button and badge draw their own fill, so they keep the text color paired with it and look
the same on every surface. Set a hook such as --atlas-heading-color to pin a
color regardless of the surface.
Component hooks
Theme tokens change every component at once. Each component also declares its own variables, component hooks, that default to theme tokens. Override a hook to restyle one component, or one component in one place, without touching the rest.
Hooks are named --atlas-[component]-[property]-[state]:
--atlas-button-bg-color, --atlas-input-border-color-hover,
--atlas-card-radius. Variants reassign hooks rather than repeating declarations, and
derived states are computed from them:
.atlas-button {
--atlas-button-bg-color: var(--color-muted);
--atlas-button-color: var(--color-foreground);
--atlas-button-radius: var(--radius-input);
--atlas-button-bg-color-hover: color-mix(in oklab, var(--atlas-button-bg-color) 90%, var(--color-mix));
background-color: var(--atlas-button-bg-color);
color: var(--atlas-button-color);
border-radius: var(--atlas-button-radius);
}
.atlas-button--primary {
--atlas-button-bg-color: var(--color-primary);
--atlas-button-color: var(--color-primary-foreground);
}
.atlas-button:hover {
background-color: var(--atlas-button-bg-color-hover);
}
So a pill-shaped button in one section is a single line:
.hero .atlas-button {
--atlas-button-radius: 9999px;
}
vendor/webreact/atlas/dist/atlas.core.css.
Hover states
Atlas has no hover tokens. A hover color is the base color mixed 10% towards
--color-mix:
color-mix(in oklab, var(--atlas-button-bg-color) 90%, var(--color-mix))
--color-mix is --color-shade (black) in light mode and
--color-tint (white) in dark mode, so the same rule darkens in light mode and
lightens in dark mode, and it follows any color a variant or a theme sets.
Form controls
Inputs, textareas, selects, the checkbox and radio boxes and the checkbox group fill with
--color-input and draw their border in --color-border. As in shadcn, a
control has no fill by default: --color-input is transparent and the
text is currentColor, so a field takes the surface it sits on. For filled fields,
set the fill in both modes:
:root {
--color-input: #ffffff;
}
.dark {
--color-input: #1c1c1f;
}
If the surface text does not read on that fill, set the text color too, with the
--atlas-input-color hook.
Radius scale
One base value, --radius, drives the whole scale. The bridge derives
--radius-xs to --radius-4xl from it, and three role radii pick from the
scale:
@theme inline {
--radius-xs: calc(var(--radius) * 0.5);
--radius-sm: var(--radius);
--radius-md: calc(var(--radius) * 1.5);
--radius-lg: calc(var(--radius) * 2);
--radius-xl: calc(var(--radius) * 3);
--radius-2xl: calc(var(--radius) * 4);
--radius-3xl: calc(var(--radius) * 6);
--radius-4xl: calc(var(--radius) * 8);
}
:root {
--radius: 0.25rem;
--radius-input: var(--radius-sm);
--radius-selector: var(--radius-sm);
--radius-card: var(--radius-xl);
}
Change --radius and every corner scales with it; change a role radius to reshape
one kind of element.
--radius-input
--radius-selector
--radius-card
Typography
Heading sizes are tokens, which is what lets Heading separate
the semantic level from the visual size. Each level has a size, a --line-height and
a --font-weight, and steps up one size from 64rem.
--text-display
--text-h1
--text-h2
--text-h3
--text-h4
--text-h5
--text-h6
The scale is also a set of Tailwind utilities, text-display and text-h1
to text-h6, which set the size, line height and weight together. Pair them with
font-heading or font-body:
<p class="font-heading text-h3">Styled like an h3</p> <p class="font-body text-sm">Body text, one step down</p>
Shadows
Shadows are Tailwind's sizes, --shadow-2xs to --shadow-2xl, with
--shadow-color mixed in. Set that one token, --shadow-color: #1e1a4d say,
and every size takes the tint at its own opacity.
--shadow-xs
--shadow-sm
--shadow-md
--shadow-lg
--shadow-xl
Adding new tokens
Add the value to :root and .dark in your own stylesheet, after Atlas,
and register it in your own @theme inline block to get utilities. Tailwind merges
your block with the Atlas bridge.
:root {
--color-highlight: #fff3c4;
--color-highlight-foreground: #5c4400;
}
.dark {
--color-highlight: #5c4400;
--color-highlight-foreground: #fff3c4;
}
@theme inline {
--color-highlight: var(--color-highlight);
--color-highlight-foreground: var(--color-highlight-foreground);
}
<mark class="bg-highlight text-highlight-foreground">New</mark>
:root or a theme file, not in @theme: a value there lands
in Tailwind's theme layer and loses to the Atlas :root.
The Tailwind bridge
The theme file ends in an @theme inline block that registers each token with
Tailwind by pointing it at itself: --color-primary: var(--color-primary). That is
what makes bg-primary resolve to the live value, including after a theme switch at
runtime.
Tailwind emits the bridge in its theme layer, and the values in :root,
.dark and theme files outrank it, so the self-reference is never used. That holds
as long as those blocks stay outside any cascade layer, or in one ordered after
theme.
Themes
The quickest retheme is a handful of tokens after the import. Every component follows, including the ones you have not looked at yet:
@import 'tailwindcss';
@import '../../vendor/webreact/atlas/dist/atlas.css';
:root {
--color-primary: #f49506;
--color-primary-foreground: #1f1300;
--radius: 0.5rem;
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
}
For a complete theme of your own, scaffold one with every token in :root and
.dark, and load it with the core stylesheet, which ships the components without the
default values:
php artisan atlas:theme corporate
@import 'tailwindcss'; @import '../../vendor/webreact/atlas/dist/atlas.core.css'; @import './themes/corporate.css';
To switch between themes at runtime, scaffold an extension instead. It copies every token under
[data-theme="corporate"]; keep what the theme changes and delete the rest, which then
falls back to the active theme:
php artisan atlas:theme corporate --extend
/* resources/css/themes/corporate.css */
[data-theme="corporate"] {
--color-primary: #0a5fd1;
--color-primary-foreground: #ffffff;
--radius: 0.75rem;
}
.dark [data-theme="corporate"],
[data-theme="corporate"].dark {
--color-primary: #7fb3ff;
--color-primary-foreground: #04224d;
}
Switch with Atlas.theme = 'corporate' (see the JavaScript
guide), or set 'theme' => 'corporate' in config/atlas.php. The
themes page shows every component under the active theme.
To start from something other than the default look, add --random to either command.
It fills the file with a generated palette and style instead of the Atlas values: surfaces that
step up from the page, a -foreground on every filled color that meets WCAG AA, status
colors that keep their meaning, and one rolled profile (shape, density, depth and type voice) for
radius, spacing, shadows and fonts. Fonts are system stacks, so nothing has to load. Not your style?
Run it again with --force.
php artisan atlas:theme corporate --random --extend
Dark mode
The .dark block redefines every color token and flips --color-mix to
--color-tint, so hover states lighten instead of darken. Fonts, radii, spacing and
shadows are defined once, in :root.
Atlas manages the mode. The default is system, which follows
prefers-color-scheme; set it in the published config or switch at runtime:
Atlas.appearance = 'dark' // or 'light', or 'system'
The choice persists in localStorage under atlas.appearance. Add the
directive to the <head> of your layout: it
applies the saved mode before the first paint, so the page never flashes the wrong colors.
.dark class on <html>. Atlas adds and
removes it when you use the appearance feature; if your application manages dark mode itself,
make sure it toggles that class.
Default theme CSS
The complete default theme, read from the installed package. Copy it as the starting point for a
theme of your own, or run php artisan atlas:theme, which writes the same tokens to a
file for you.
themes/atlas.css
/*
* Keep these blocks outside any cascade layer, or in one ordered after
* Tailwind's `theme`. The @theme inline bridge below points each
* Tailwind variable at itself, so the values declared here must outrank
* the bridge in @layer theme.
*/
:root {
/* Abstract colors */
--color-shade: black;
--color-tint: white;
--color-mix: var(--color-shade);
/* Surface colors */
--color-background: #f4f4f5; /* the page */
--color-foreground: #27272a;
--color-raised: #fafafa; /* one step up: sections, side columns */
--color-raised-foreground: #27272a;
--color-card: #ffffff; /* two steps up: cards and tiles */
--color-card-foreground: #27272a;
--color-overlay: #ffffff; /* floating: modals, popovers, dropdowns */
--color-overlay-foreground: #27272a;
--color-muted: #ececee; /* below the page: sunken bands, wells, disabled fields */
--color-muted-foreground: #6a6a74; /* lower-emphasis text on any surface */
/* Brand colors */
--color-primary: #615fff;
--color-primary-foreground: #ffffff;
--color-secondary: #6f68a6;
--color-secondary-foreground: #ffffff;
--color-accent: #fe9a00;
--color-accent-foreground: #000000;
/* Status colors */
--color-info: #0069a8;
--color-info-foreground: #ffffff;
--color-success: #007a55;
--color-success-foreground: #ffffff;
--color-warning: #ca3500;
--color-warning-foreground: #ffffff;
--color-danger: #e7000b;
--color-danger-foreground: #ffffff;
/* Structural colors */
--color-border: #c4c6cc;
--color-input: transparent; /* the field shows the surface it sits on */
--color-ring: var(--color-primary);
/* Font families */
--font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
--font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
--font-heading: var(--font-sans);
--font-body: var(--font-sans);
/* Type scale: size, line height and weight per level */
--text-display: var(--text-6xl);
--text-display--line-height: 1;
--text-display--font-weight: 700;
--text-h1: var(--text-5xl);
--text-h1--line-height: 1;
--text-h1--font-weight: 700;
--text-h2: var(--text-4xl);
--text-h2--line-height: 1.125;
--text-h2--font-weight: 700;
--text-h3: var(--text-3xl);
--text-h3--line-height: 1.25;
--text-h3--font-weight: 700;
--text-h4: var(--text-2xl);
--text-h4--line-height: 1.25;
--text-h4--font-weight: 700;
--text-h5: var(--text-xl);
--text-h5--line-height: 1.25;
--text-h5--font-weight: 700;
--text-h6: var(--text-lg);
--text-h6--line-height: 1.25;
--text-h6--font-weight: 700;
/* Spacing: base unit for Tailwind spacing utilities */
--spacing: 0.25rem;
/* Radius: base unit for the radius scale, plus per-role radii */
--radius: 0.25rem;
--radius-input: var(--radius-sm); /* button, input, select, textarea */
--radius-selector: var(--radius-sm); /* badge, checkbox */
--radius-card: var(--radius-xl); /* card, video, image */
/* Shadows */
--shadow-color: #000000;
--shadow-2xs: 0 1px color-mix(in oklab, var(--shadow-color) 5%, transparent);
--shadow-xs: 0 1px 2px 0 color-mix(in oklab, var(--shadow-color) 5%, transparent);
--shadow-sm: 0 1px 3px 0 color-mix(in oklab, var(--shadow-color) 10%, transparent), 0 1px 2px -1px color-mix(in oklab, var(--shadow-color) 10%, transparent);
--shadow-md: 0 4px 6px -1px color-mix(in oklab, var(--shadow-color) 10%, transparent), 0 2px 4px -2px color-mix(in oklab, var(--shadow-color) 10%, transparent);
--shadow-lg: 0 10px 15px -3px color-mix(in oklab, var(--shadow-color) 10%, transparent), 0 4px 6px -4px color-mix(in oklab, var(--shadow-color) 10%, transparent);
--shadow-xl: 0 20px 25px -5px color-mix(in oklab, var(--shadow-color) 10%, transparent), 0 8px 10px -6px color-mix(in oklab, var(--shadow-color) 10%, transparent);
--shadow-2xl: 0 25px 50px -12px color-mix(in oklab, var(--shadow-color) 25%, transparent);
--shadow: var(--shadow-sm);
/* Opacity */
--opacity-disabled: 0.5;
/* Type scale from --breakpoint-lg (64rem/1024px) */
@media (min-width: 64rem) {
--text-display: var(--text-7xl);
--text-h1: var(--text-6xl);
--text-h2: var(--text-5xl);
--text-h3: var(--text-4xl);
--text-h4: var(--text-3xl);
--text-h5: var(--text-2xl);
--text-h6: var(--text-xl);
}
}
.dark {
/* Abstract colors */
--color-mix: var(--color-tint);
/* Surface colors */
--color-background: #27272a;
--color-foreground: #f4f4f5;
--color-raised: #2c2c2e;
--color-raised-foreground: #ffffff;
--color-card: #303033;
--color-card-foreground: #ffffff;
--color-overlay: #353538;
--color-overlay-foreground: #ffffff;
--color-muted: #232325;
--color-muted-foreground: #9f9fa9;
/* Brand colors */
--color-primary: #a3b3ff;
--color-primary-foreground: #1e1a4d;
--color-secondary: #716b98;
--color-secondary-foreground: #ffffff;
--color-accent: #fee685;
--color-accent-foreground: #461901;
/* Status colors */
--color-info: #80d3ef;
--color-info-foreground: #052f4a;
--color-success: #5ee9b5;
--color-success-foreground: #00422b;
--color-warning: #ffb86a;
--color-warning-foreground: #7e2a0c;
--color-danger: #ffa2a2;
--color-danger-foreground: #75070f;
/* Structural colors */
--color-border: #5c5c63;
--color-input: color-mix(in oklab, var(--color-shade) 10%, transparent);
--color-ring: var(--color-primary);
}
@theme inline {
/* Tailwind bridge: exposes the tokens as utilities */
/* Abstract colors */
--color-shade: var(--color-shade);
--color-tint: var(--color-tint);
--color-mix: var(--color-mix);
/* Surface colors */
--color-background: var(--color-background);
--color-foreground: var(--color-foreground);
--color-raised: var(--color-raised);
--color-raised-foreground: var(--color-raised-foreground);
--color-card: var(--color-card);
--color-card-foreground: var(--color-card-foreground);
--color-overlay: var(--color-overlay);
--color-overlay-foreground: var(--color-overlay-foreground);
--color-muted: var(--color-muted);
--color-muted-foreground: var(--color-muted-foreground);
/* Brand colors */
--color-primary: var(--color-primary);
--color-primary-foreground: var(--color-primary-foreground);
--color-secondary: var(--color-secondary);
--color-secondary-foreground: var(--color-secondary-foreground);
--color-accent: var(--color-accent);
--color-accent-foreground: var(--color-accent-foreground);
/* Status colors */
--color-info: var(--color-info);
--color-info-foreground: var(--color-info-foreground);
--color-success: var(--color-success);
--color-success-foreground: var(--color-success-foreground);
--color-warning: var(--color-warning);
--color-warning-foreground: var(--color-warning-foreground);
--color-danger: var(--color-danger);
--color-danger-foreground: var(--color-danger-foreground);
/* Structural colors */
--color-border: var(--color-border);
--color-input: var(--color-input);
--color-ring: var(--color-ring);
/* Font families */
--font-sans: var(--font-sans);
--font-serif: var(--font-serif);
--font-mono: var(--font-mono);
--font-heading: var(--font-heading);
--font-body: var(--font-body);
/* Type scale */
--text-display: var(--text-display);
--text-display--line-height: var(--text-display--line-height);
--text-display--font-weight: var(--text-display--font-weight);
--text-h1: var(--text-h1);
--text-h1--line-height: var(--text-h1--line-height);
--text-h1--font-weight: var(--text-h1--font-weight);
--text-h2: var(--text-h2);
--text-h2--line-height: var(--text-h2--line-height);
--text-h2--font-weight: var(--text-h2--font-weight);
--text-h3: var(--text-h3);
--text-h3--line-height: var(--text-h3--line-height);
--text-h3--font-weight: var(--text-h3--font-weight);
--text-h4: var(--text-h4);
--text-h4--line-height: var(--text-h4--line-height);
--text-h4--font-weight: var(--text-h4--font-weight);
--text-h5: var(--text-h5);
--text-h5--line-height: var(--text-h5--line-height);
--text-h5--font-weight: var(--text-h5--font-weight);
--text-h6: var(--text-h6);
--text-h6--line-height: var(--text-h6--line-height);
--text-h6--font-weight: var(--text-h6--font-weight);
/* Radius scale, derived from --radius */
--radius-xs: calc(var(--radius) * 0.5);
--radius-sm: var(--radius);
--radius-md: calc(var(--radius) * 1.5);
--radius-lg: calc(var(--radius) * 2);
--radius-xl: calc(var(--radius) * 3);
--radius-2xl: calc(var(--radius) * 4);
--radius-3xl: calc(var(--radius) * 6);
--radius-4xl: calc(var(--radius) * 8);
--radius-input: var(--radius-input); /* button, input, select, textarea */
--radius-selector: var(--radius-selector); /* badge, checkbox */
--radius-card: var(--radius-card); /* card, video, image */
/* Shadows */
--shadow-2xs: var(--shadow-2xs);
--shadow-xs: var(--shadow-xs);
--shadow-sm: var(--shadow-sm);
--shadow-md: var(--shadow-md);
--shadow-lg: var(--shadow-lg);
--shadow-xl: var(--shadow-xl);
--shadow-2xl: var(--shadow-2xl);
--shadow: var(--shadow);
/* Opacity */
--opacity-disabled: var(--opacity-disabled);
}
@layer base {
* {
@apply border-border outline-ring;
}
:focus-visible {
@apply outline-2 outline-offset-2;
}
body {
@apply font-body bg-background text-foreground;
}
}