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.

--color-muted

Ready to order?

Talk to us Email
Badge
--color-background

Ready to order?

Talk to us Email
Badge
--color-raised

Ready to order?

Talk to us Email
Badge
--color-card

Ready to order?

Talk to us Email
Badge
--color-overlay

Ready to order?

Talk to us Email
Badge
--color-primary

Ready to order?

Talk to us Email
Badge

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;
}

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.

Aa --text-display
Aa --text-h1
Aa --text-h2
Aa --text-h3
Aa --text-h4
Aa --text-h5
Aa --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>

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.

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;
  }
}