asadesignsystem
One source

Tokens

Every value below is read from tokens/tokens.json. Style Dictionary turns that file into CSS variables, a Tailwind v4 theme and a JS module; this page, the components and the artifact all use those.

Colour

31 tokens, each with a light and a dark value. The swatches use the value itself, not the current theme.

--bglight #f6f8fddark #12131cPage ground behind cards, a light blue-grey. Light is the committed theme; dark is optional.
--surfacelight #ffffffdark #1c1f2bCards, panels, menus, modals. Lifts off bg by contrast plus shadow-card, not by a heavy border.
--surface-2light #eef2fbdark #232735Table header, hover rows, inset wells, the segmented track.
--surface-3light #e5e9f2dark #2b3040Secondary button fill, neutral pills and chips, avatar ground, progress track.
--inklight #34364adark #eef0f6Headings and body text on bg, surface, surface-2 and surface-3 (9.7:1 or better). Dark navy-slate, never pure black.
--mutedlight #636a79dark #a6abc0Secondary copy, labels, captions on surface and surface-2 (4.8:1 light, 6.5:1 dark).
--faintlight #9aa3b2dark #6e7488Placeholder, disabled and decorative icons only. Never body copy.
--linelight #e8edf7dark #2e3242Hairline borders, row dividers, input outline.
--controllight #868fa3dark #737a8fBorders of form controls (input, checkbox, radio) and the off track of a switch: 3.2:1 on surface light, 3.8:1 dark, so an empty control is still visible.
--accentlight #3d58ffdark #6b80ffRoyal blue, the identity colour. Focus rings, progress bars, switch on, active tab underline, the one accent role. Swap this group (accent, accent-strong, accent-deep, accent-ink, accent-soft) to reuse the system for another brand.
--accent-stronglight #1b37d9dark #8fa0ffHover and pressed state of an accent fill (one step deeper than accent-deep).
--accent-deeplight #2447f9dark #4a63ffSolid accent FILL with on-accent text: primary button, count badge, checked box. Light #2447f9 is BWA's measured button blue (white on it 6.3:1); dark 4.65:1.
--accent-inklight #2447f9dark #a9b6ffAccent TEXT and icons: links, eyebrows, tonal button label, on surface or accent-soft (5.4:1 light, 7.5:1 dark).
--accent-softlight #eaeeffdark #1f2550Soft blue fill: tonal button, accent pill, code chip, selected row, info banner.
--on-accentlight #ffffffdark #ffffffText and icons on accent-deep.
--navylight #110843dark #1b1452The signature header bar (rounded bottom) and other always-dark hero surfaces. Dark value is lifted so the bar still reads on the dark ground.
--on-navylight #ffffffdark #ffffffTitles and icons on navy (18:1).
--navy-mutedlight rgba(255,255,255,0.72)dark rgba(255,255,255,0.72)Subtitles and meta on navy.
--navy-accentlight #8fa0ffdark #8fa0ffEyebrow text on navy (7.6:1).
--inverselight #110843dark #2c2366Always-dark small surfaces that do not flip with the theme: toast, tooltip, dark button. Never use ink as a background.
--on-inverselight #ffffffdark #ffffffText and icons on inverse.
--danger-solidlight #d13438dark #d13438Solid destructive fill (delete, revoke) with white text, 4.9:1 in both themes.
--oklight #23805bdark #35c57fSuccess text and icons: live, passed, done.
--ok-bglight #e2f5eedark #123726Success pill and banner surface.
--ok-inklight #1f7a55dark #7ee0a8Success text on ok-bg (4.7:1 light).
--dangerlight #d13438dark #f08a8aError and destructive text and icons, invalid field border.
--danger-bglight #fdececdark #3a1e1eError pill and banner surface.
--danger-inklight #b8292fdark #f3a3a3Error text on danger-bg (5.4:1 light).
--warnlight #a8650fdark #e0a64aWarning and in-progress text and icons.
--warn-bglight #fbf0dddark #352c12Warning pill and banner surface.
--warn-inklight #8a5a12dark #e8be7aWarning text on warn-bg (5.2:1 light).

Type

Poppins for everything, JetBrains Mono for hashes, IDs and commands. Body is light 300; eyebrows are title case, never uppercase.

display
32px / 48px / 700
Product status for every lane
h1
26px / 39px / 700
Product status for every lane
h2
24px / 36px / 700
Product status for every lane
title
20px / 30px / 700
Product status for every lane
eyebrow
18px / 27px / 600
Dev web
body
16px / 24px / 400
Product status for every lane
body-light
16px / 24px / 300
Product status for every lane
label
16px / 24px / 500
Product status for every lane
meta
14px / 21px / 400
Product status for every lane
button
16px / 24px / 600
Product status for every lane
mono
13px / 18px / 400
a1f3c9e · PR 41 · npm run tokens

Spacing

A 4px step. Card padding is space-5.

space-14px
space-28px
space-312px
space-416px
space-520px
space-624px
space-832px
space-card30px

Radius

Soft: 16px cards, pill controls, a 22px bottom on the navy header.

radius-sm8px
radius-md12px
radius-lg16px
radius-header22px
radius-panel26px
radius-pill100px

Shadow

Lift comes from a soft navy-tinted spread, not from borders. On hover the shadow grows and nothing moves.

--shadow-cardLift for floating things only: menus, popovers, a hovered card. Resting cards carry NO shadow and no border; they sit white on bg (measured on BWA's dashboard).
--shadow-smControls and the selected segment.
--shadow-hoverHover on an interactive card or quiet button. The shadow grows, nothing moves.

The generated files

Copy the one that fits the project. Never edit them by hand; change tokens.json and run npm run tokens.

variables.css · plain HTML, no build

/* asadesignsystem. GENERATED by scripts/build-tokens.mjs from tokens/tokens.json, do not edit.
   Fonts: https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&family=JetBrains+Mono&display=swap */
:root, [data-theme="light"] {
  --bg: #f6f8fd; /** Page ground behind cards, a light blue-grey. Light is the committed theme; dark is optional. */
  --surface: #ffffff; /** Cards, panels, menus, modals. Lifts off bg by contrast plus shadow-card, not by a heavy border. */
  --surface-2: #eef2fb; /** Table header, hover rows, inset wells, the segmented track. */
  --surface-3: #e5e9f2; /** Secondary button fill, neutral pills and chips, avatar ground, progress track. */
  --ink: #34364a; /** Headings and body text on bg, surface, surface-2 and surface-3 (9.7:1 or better). Dark navy-slate, never pure black. */
  --muted: #636a79; /** Secondary copy, labels, captions on surface and surface-2 (4.8:1 light, 6.5:1 dark). */
  --faint: #9aa3b2; /** Placeholder, disabled and decorative icons only. Never body copy. */
  --line: #e8edf7; /** Hairline borders, row dividers, input outline. */
  --control: #868fa3; /** Borders of form controls (input, checkbox, radio) and the off track of a switch: 3.2:1 on surface light, 3.8:1 dark, so an empty control is still visible. */
  --accent: #3d58ff; /** Royal blue, the identity colour. Focus rings, progress bars, switch on, active tab underline, the one accent role. Swap this group (accent, accent-strong, accent-deep, accent-ink, accent-soft) to reuse the system for another brand. */
  --accent-strong: #1b37d9; /** Hover and pressed state of an accent fill (one step deeper than accent-deep). */
  --accent-deep: #2447f9; /** Solid accent FILL with on-accent text: primary button, count badge, checked box. Light #2447f9 is BWA's measured button blue (white on it 6.3:1); dark 4.65:1. */
  --accent-ink: #2447f9; /** Accent TEXT and icons: links, eyebrows, tonal button label, on surface or accent-soft (5.4:1 light, 7.5:1 dark). */
  --accent-soft: #eaeeff; /** Soft blue fill: tonal button, accent pill, code chip, selected row, info banner. */
  --on-accent: #ffffff; /** Text and icons on accent-deep. */
  --navy: #110843; /** The signature header bar (rounded bottom) and other always-dark hero surfaces. Dark value is lifted so the bar still reads on the dark ground. */
  --on-navy: #ffffff; /** Titles and icons on navy (18:1). */
  --navy-muted: rgba(255,255,255,0.72); /** Subtitles and meta on navy. */
  --navy-accent: #8fa0ff; /** Eyebrow text on navy (7.6:1). */
  --inverse: #110843; /** Always-dark small surfaces that do not flip with the theme: toast, tooltip, dark button. Never use ink as a background. */
  --on-inverse: #ffffff; /** Text and icons on inverse. */
  --danger-solid: #d13438; /** Solid destructive fill (delete, revoke) with white text, 4.9:1 in both themes. */
  --ok: #23805b; /** Success text and icons: live, passed, done. */
  --ok-bg: #e2f5ee; /** Success pill and banner surface. */
  --ok-ink: #1f7a55; /** Success text on ok-bg (4.7:1 light). */
  --danger: #d13438; /** Error and destructive text and icons, invalid field border. */
  --danger-bg: #fdecec; /** Error pill and banner surface. */
  --danger-ink: #b8292f; /** Error text on danger-bg (5.4:1 light). */
  --warn: #a8650f; /** Warning and in-progress text and icons. */
  --warn-bg: #fbf0dd; /** Warning pill and banner surface. */
  --warn-ink: #8a5a12; /** Warning text on warn-bg (5.2:1 light). */
  --shadow-card: 0 9px 30px rgba(17,8,67,0.06), 0 2px 6px rgba(17,8,67,0.03); /** Lift for floating things only: menus, popovers, a hovered card. Resting cards carry NO shadow and no border; they sit white on bg (measured on BWA's dashboard). */
  --shadow-sm: 0 1px 2px rgba(17,8,67,0.06); /** Controls and the selected segment. */
  --shadow-hover: 0 14px 34px rgba(17,8,67,0.10); /** Hover on an interactive card or quiet button. The shadow grows, nothing moves. */
  --space-1: 4px; /** Icon-to-label gap, tight insets. */
  --space-2: 8px; /** Chip padding, small gaps. */
  --space-3: 12px; /** Control padding, list-row gap. */
  --space-4: 16px; /** Default card padding, field gap. */
  --space-5: 20px; /** Small card and list padding. */
  --space-6: 24px; /** Section gap. */
  --space-8: 32px; /** Page gutter, block separation. */
  --space-card: 30px; /** Card padding (measured on BWA's dashboard cards); 24px (space-6) on dense grids of small cards. */
  --radius-sm: 8px; /** Inputs, small chips, menu items. */
  --radius-md: 12px; /** Icon buttons, alerts, menus, toasts. */
  --radius-lg: 16px; /** Cards, panels, modals. Also the Tailwind --radius base. */
  --radius-header: 22px; /** Bottom corners of the navy page header. */
  --radius-panel: 26px; /** Large white panels such as the sidebar card (measured on BWA). */
  --radius-pill: 100px; /** Buttons, status pills, segmented control, toggles. */
  --font-sans: "Poppins", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-size-display: 32px;
  --line-height-display: 48px;
  --font-weight-display: 700;
  --font-size-h1: 26px;
  --line-height-h1: 39px;
  --font-weight-h1: 700;
  --font-size-h2: 24px;
  --line-height-h2: 36px;
  --font-weight-h2: 700;
  --font-size-title: 20px;
  --line-height-title: 30px;
  --font-weight-title: 700;
  --font-size-eyebrow: 18px;
  --line-height-eyebrow: 27px;
  --font-weight-eyebrow: 600;
  --font-size-body: 16px;
  --line-height-body: 24px;
  --font-weight-body: 400;
  --font-size-body-light: 16px;
  --line-height-body-light: 24px;
  --font-weight-body-light: 300;
  --font-size-label: 16px;
  --line-height-label: 24px;
  --font-weight-label: 500;
  --font-size-meta: 14px;
  --line-height-meta: 21px;
  --font-weight-meta: 400;
  --font-size-button: 16px;
  --line-height-button: 24px;
  --font-weight-button: 600;
  --font-size-mono: 13px;
  --line-height-mono: 18px;
  --font-weight-mono: 400;
}

[data-theme="dark"], .dark {
  --bg: #12131c; /** Page ground behind cards, a light blue-grey. Light is the committed theme; dark is optional. */
  --surface: #1c1f2b; /** Cards, panels, menus, modals. Lifts off bg by contrast plus shadow-card, not by a heavy border. */
  --surface-2: #232735; /** Table header, hover rows, inset wells, the segmented track. */
  --surface-3: #2b3040; /** Secondary button fill, neutral pills and chips, avatar ground, progress track. */
  --ink: #eef0f6; /** Headings and body text on bg, surface, surface-2 and surface-3 (9.7:1 or better). Dark navy-slate, never pure black. */
  --muted: #a6abc0; /** Secondary copy, labels, captions on surface and surface-2 (4.8:1 light, 6.5:1 dark). */
  --faint: #6e7488; /** Placeholder, disabled and decorative icons only. Never body copy. */
  --line: #2e3242; /** Hairline borders, row dividers, input outline. */
  --control: #737a8f; /** Borders of form controls (input, checkbox, radio) and the off track of a switch: 3.2:1 on surface light, 3.8:1 dark, so an empty control is still visible. */
  --accent: #6b80ff; /** Royal blue, the identity colour. Focus rings, progress bars, switch on, active tab underline, the one accent role. Swap this group (accent, accent-strong, accent-deep, accent-ink, accent-soft) to reuse the system for another brand. */
  --accent-strong: #8fa0ff; /** Hover and pressed state of an accent fill (one step deeper than accent-deep). */
  --accent-deep: #4a63ff; /** Solid accent FILL with on-accent text: primary button, count badge, checked box. Light #2447f9 is BWA's measured button blue (white on it 6.3:1); dark 4.65:1. */
  --accent-ink: #a9b6ff; /** Accent TEXT and icons: links, eyebrows, tonal button label, on surface or accent-soft (5.4:1 light, 7.5:1 dark). */
  --accent-soft: #1f2550; /** Soft blue fill: tonal button, accent pill, code chip, selected row, info banner. */
  --navy: #1b1452; /** The signature header bar (rounded bottom) and other always-dark hero surfaces. Dark value is lifted so the bar still reads on the dark ground. */
  --inverse: #2c2366; /** Always-dark small surfaces that do not flip with the theme: toast, tooltip, dark button. Never use ink as a background. */
  --ok: #35c57f; /** Success text and icons: live, passed, done. */
  --ok-bg: #123726; /** Success pill and banner surface. */
  --ok-ink: #7ee0a8; /** Success text on ok-bg (4.7:1 light). */
  --danger: #f08a8a; /** Error and destructive text and icons, invalid field border. */
  --danger-bg: #3a1e1e; /** Error pill and banner surface. */
  --danger-ink: #f3a3a3; /** Error text on danger-bg (5.4:1 light). */
  --warn: #e0a64a; /** Warning and in-progress text and icons. */
  --warn-bg: #352c12; /** Warning pill and banner surface. */
  --warn-ink: #e8be7a; /** Warning text on warn-bg (5.2:1 light). */
  --shadow-card: 0 9px 30px rgba(0,0,0,0.35), 0 2px 6px rgba(0,0,0,0.25); /** Lift for floating things only: menus, popovers, a hovered card. Resting cards carry NO shadow and no border; they sit white on bg (measured on BWA's dashboard). */
  --shadow-hover: 0 14px 34px rgba(0,0,0,0.5); /** Hover on an interactive card or quiet button. The shadow grows, nothing moves. */
}

tailwind-theme.css · Tailwind v4 + shadcn/ui

/* asadesignsystem. GENERATED by scripts/build-tokens.mjs from tokens/tokens.json, do not edit.
   Fonts: https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&family=JetBrains+Mono&display=swap In globals.css: @import "tailwindcss"; @import "tw-animate-css"; @import "shadcn/tailwind.css"; then this file. */
:root, [data-theme="light"] {
  --bg: #f6f8fd; /** Page ground behind cards, a light blue-grey. Light is the committed theme; dark is optional. */
  --surface: #ffffff; /** Cards, panels, menus, modals. Lifts off bg by contrast plus shadow-card, not by a heavy border. */
  --surface-2: #eef2fb; /** Table header, hover rows, inset wells, the segmented track. */
  --surface-3: #e5e9f2; /** Secondary button fill, neutral pills and chips, avatar ground, progress track. */
  --ink: #34364a; /** Headings and body text on bg, surface, surface-2 and surface-3 (9.7:1 or better). Dark navy-slate, never pure black. */
  --muted: #636a79; /** Secondary copy, labels, captions on surface and surface-2 (4.8:1 light, 6.5:1 dark). */
  --faint: #9aa3b2; /** Placeholder, disabled and decorative icons only. Never body copy. */
  --line: #e8edf7; /** Hairline borders, row dividers, input outline. */
  --control: #868fa3; /** Borders of form controls (input, checkbox, radio) and the off track of a switch: 3.2:1 on surface light, 3.8:1 dark, so an empty control is still visible. */
  --accent: #3d58ff; /** Royal blue, the identity colour. Focus rings, progress bars, switch on, active tab underline, the one accent role. Swap this group (accent, accent-strong, accent-deep, accent-ink, accent-soft) to reuse the system for another brand. */
  --accent-strong: #1b37d9; /** Hover and pressed state of an accent fill (one step deeper than accent-deep). */
  --accent-deep: #2447f9; /** Solid accent FILL with on-accent text: primary button, count badge, checked box. Light #2447f9 is BWA's measured button blue (white on it 6.3:1); dark 4.65:1. */
  --accent-ink: #2447f9; /** Accent TEXT and icons: links, eyebrows, tonal button label, on surface or accent-soft (5.4:1 light, 7.5:1 dark). */
  --accent-soft: #eaeeff; /** Soft blue fill: tonal button, accent pill, code chip, selected row, info banner. */
  --on-accent: #ffffff; /** Text and icons on accent-deep. */
  --navy: #110843; /** The signature header bar (rounded bottom) and other always-dark hero surfaces. Dark value is lifted so the bar still reads on the dark ground. */
  --on-navy: #ffffff; /** Titles and icons on navy (18:1). */
  --navy-muted: rgba(255,255,255,0.72); /** Subtitles and meta on navy. */
  --navy-accent: #8fa0ff; /** Eyebrow text on navy (7.6:1). */
  --inverse: #110843; /** Always-dark small surfaces that do not flip with the theme: toast, tooltip, dark button. Never use ink as a background. */
  --on-inverse: #ffffff; /** Text and icons on inverse. */
  --danger-solid: #d13438; /** Solid destructive fill (delete, revoke) with white text, 4.9:1 in both themes. */
  --ok: #23805b; /** Success text and icons: live, passed, done. */
  --ok-bg: #e2f5ee; /** Success pill and banner surface. */
  --ok-ink: #1f7a55; /** Success text on ok-bg (4.7:1 light). */
  --danger: #d13438; /** Error and destructive text and icons, invalid field border. */
  --danger-bg: #fdecec; /** Error pill and banner surface. */
  --danger-ink: #b8292f; /** Error text on danger-bg (5.4:1 light). */
  --warn: #a8650f; /** Warning and in-progress text and icons. */
  --warn-bg: #fbf0dd; /** Warning pill and banner surface. */
  --warn-ink: #8a5a12; /** Warning text on warn-bg (5.2:1 light). */
  --shadow-card: 0 9px 30px rgba(17,8,67,0.06), 0 2px 6px rgba(17,8,67,0.03); /** Lift for floating things only: menus, popovers, a hovered card. Resting cards carry NO shadow and no border; they sit white on bg (measured on BWA's dashboard). */
  --shadow-sm: 0 1px 2px rgba(17,8,67,0.06); /** Controls and the selected segment. */
  --shadow-hover: 0 14px 34px rgba(17,8,67,0.10); /** Hover on an interactive card or quiet button. The shadow grows, nothing moves. */
  --space-1: 4px; /** Icon-to-label gap, tight insets. */
  --space-2: 8px; /** Chip padding, small gaps. */
  --space-3: 12px; /** Control padding, list-row gap. */
  --space-4: 16px; /** Default card padding, field gap. */
  --space-5: 20px; /** Small card and list padding. */
  --space-6: 24px; /** Section gap. */
  --space-8: 32px; /** Page gutter, block separation. */
  --space-card: 30px; /** Card padding (measured on BWA's dashboard cards); 24px (space-6) on dense grids of small cards. */
  --radius-sm: 8px; /** Inputs, small chips, menu items. */
  --radius-md: 12px; /** Icon buttons, alerts, menus, toasts. */
  --radius-lg: 16px; /** Cards, panels, modals. Also the Tailwind --radius base. */
  --radius-header: 22px; /** Bottom corners of the navy page header. */
  --radius-panel: 26px; /** Large white panels such as the sidebar card (measured on BWA). */
  --radius-pill: 100px; /** Buttons, status pills, segmented control, toggles. */
  --font-sans: "Poppins", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-size-display: 32px;
  --line-height-display: 48px;
  --font-weight-display: 700;
  --font-size-h1: 26px;
  --line-height-h1: 39px;
  --font-weight-h1: 700;
  --font-size-h2: 24px;
  --line-height-h2: 36px;
  --font-weight-h2: 700;
  --font-size-title: 20px;
  --line-height-title: 30px;
  --font-weight-title: 700;
  --font-size-eyebrow: 18px;
  --line-height-eyebrow: 27px;
  --font-weight-eyebrow: 600;
  --font-size-body: 16px;
  --line-height-body: 24px;
  --font-weight-body: 400;
  --font-size-body-light: 16px;
  --line-height-body-light: 24px;
  --font-weight-body-light: 300;
  --font-size-label: 16px;
  --line-height-label: 24px;
  --font-weight-label: 500;
  --font-size-meta: 14px;
  --line-height-meta: 21px;
  --font-weight-meta: 400;
  --font-size-button: 16px;
  --line-height-button: 24px;
  --font-weight-button: 600;
  --font-size-mono: 13px;
  --line-height-mono: 18px;
  --font-weight-mono: 400;
}

[data-theme="dark"], .dark {
  --bg: #12131c; /** Page ground behind cards, a light blue-grey. Light is the committed theme; dark is optional. */
  --surface: #1c1f2b; /** Cards, panels, menus, modals. Lifts off bg by contrast plus shadow-card, not by a heavy border. */
  --surface-2: #232735; /** Table header, hover rows, inset wells, the segmented track. */
  --surface-3: #2b3040; /** Secondary button fill, neutral pills and chips, avatar ground, progress track. */
  --ink: #eef0f6; /** Headings and body text on bg, surface, surface-2 and surface-3 (9.7:1 or better). Dark navy-slate, never pure black. */
  --muted: #a6abc0; /** Secondary copy, labels, captions on surface and surface-2 (4.8:1 light, 6.5:1 dark). */
  --faint: #6e7488; /** Placeholder, disabled and decorative icons only. Never body copy. */
  --line: #2e3242; /** Hairline borders, row dividers, input outline. */
  --control: #737a8f; /** Borders of form controls (input, checkbox, radio) and the off track of a switch: 3.2:1 on surface light, 3.8:1 dark, so an empty control is still visible. */
  --accent: #6b80ff; /** Royal blue, the identity colour. Focus rings, progress bars, switch on, active tab underline, the one accent role. Swap this group (accent, accent-strong, accent-deep, accent-ink, accent-soft) to reuse the system for another brand. */
  --accent-strong: #8fa0ff; /** Hover and pressed state of an accent fill (one step deeper than accent-deep). */
  --accent-deep: #4a63ff; /** Solid accent FILL with on-accent text: primary button, count badge, checked box. Light #2447f9 is BWA's measured button blue (white on it 6.3:1); dark 4.65:1. */
  --accent-ink: #a9b6ff; /** Accent TEXT and icons: links, eyebrows, tonal button label, on surface or accent-soft (5.4:1 light, 7.5:1 dark). */
  --accent-soft: #1f2550; /** Soft blue fill: tonal button, accent pill, code chip, selected row, info banner. */
  --navy: #1b1452; /** The signature header bar (rounded bottom) and other always-dark hero surfaces. Dark value is lifted so the bar still reads on the dark ground. */
  --inverse: #2c2366; /** Always-dark small surfaces that do not flip with the theme: toast, tooltip, dark button. Never use ink as a background. */
  --ok: #35c57f; /** Success text and icons: live, passed, done. */
  --ok-bg: #123726; /** Success pill and banner surface. */
  --ok-ink: #7ee0a8; /** Success text on ok-bg (4.7:1 light). */
  --danger: #f08a8a; /** Error and destructive text and icons, invalid field border. */
  --danger-bg: #3a1e1e; /** Error pill and banner surface. */
  --danger-ink: #f3a3a3; /** Error text on danger-bg (5.4:1 light). */
  --warn: #e0a64a; /** Warning and in-progress text and icons. */
  --warn-bg: #352c12; /** Warning pill and banner surface. */
  --warn-ink: #e8be7a; /** Warning text on warn-bg (5.2:1 light). */
  --shadow-card: 0 9px 30px rgba(0,0,0,0.35), 0 2px 6px rgba(0,0,0,0.25); /** Lift for floating things only: menus, popovers, a hovered card. Resting cards carry NO shadow and no border; they sit white on bg (measured on BWA's dashboard). */
  --shadow-hover: 0 14px 34px rgba(0,0,0,0.5); /** Hover on an interactive card or quiet button. The shadow grows, nothing moves. */
}
:root {
  --radius: var(--radius-lg);
  --sc-background: var(--bg);
  --sc-foreground: var(--ink);
  --sc-card: var(--surface);
  --sc-card-foreground: var(--ink);
  --sc-popover: var(--surface);
  --sc-popover-foreground: var(--ink);
  --sc-primary: var(--accent-deep);
  --sc-primary-foreground: var(--on-accent);
  --sc-secondary: var(--surface-3);
  --sc-secondary-foreground: var(--ink);
  --sc-muted: var(--surface-2);
  --sc-muted-foreground: var(--muted);
  --sc-accent: var(--accent-soft);
  --sc-accent-foreground: var(--accent-ink);
  --sc-destructive: var(--danger-solid);
  --sc-border: var(--line);
  --sc-input: var(--control);
  --sc-ring: var(--accent);
  --sc-chart-1: var(--accent);
  --sc-chart-2: var(--ok);
  --sc-chart-3: var(--warn);
  --sc-chart-4: var(--ink);
  --sc-chart-5: var(--danger);
  --sc-sidebar: var(--surface);
  --sc-sidebar-foreground: var(--ink);
  --sc-sidebar-primary: var(--accent-deep);
  --sc-sidebar-primary-foreground: var(--on-accent);
  --sc-sidebar-accent: var(--accent-soft);
  --sc-sidebar-accent-foreground: var(--accent-ink);
  --sc-sidebar-border: var(--line);
  --sc-sidebar-ring: var(--accent);
  /* shadcn's raw names (not accent / muted: those are this system's own tokens; use --sc-accent, --sc-muted) */
  --background: var(--bg);
  --foreground: var(--ink);
  --card: var(--surface);
  --card-foreground: var(--ink);
  --popover: var(--surface);
  --popover-foreground: var(--ink);
  --primary: var(--accent-deep);
  --primary-foreground: var(--on-accent);
  --secondary: var(--surface-3);
  --secondary-foreground: var(--ink);
  --muted-foreground: var(--muted);
  --accent-foreground: var(--accent-ink);
  --destructive: var(--danger-solid);
  --border: var(--line);
  --input: var(--control);
  --ring: var(--accent);
  --chart-1: var(--accent);
  --chart-2: var(--ok);
  --chart-3: var(--warn);
  --chart-4: var(--ink);
  --chart-5: var(--danger);
  --sidebar: var(--surface);
  --sidebar-foreground: var(--ink);
  --sidebar-primary: var(--accent-deep);
  --sidebar-primary-foreground: var(--on-accent);
  --sidebar-accent: var(--accent-soft);
  --sidebar-accent-foreground: var(--accent-ink);
  --sidebar-border: var(--line);
  --sidebar-ring: var(--accent);
}
/* Keys Tailwind must know by name; the value is the light one, the unlayered :root / dark variables win at runtime. */
@theme {
  --font-sans: "Poppins", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --radius-pill: 100px;
  --shadow-card: 0 9px 30px rgba(17,8,67,0.06), 0 2px 6px rgba(17,8,67,0.03);
  --shadow-hover: 0 14px 34px rgba(17,8,67,0.10);
}
@theme inline {
  --radius-sm: calc(var(--radius) - 8px);
  --radius-md: calc(var(--radius) - 4px);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) + 4px);
  --color-background: var(--sc-background);
  --color-foreground: var(--sc-foreground);
  --color-card: var(--sc-card);
  --color-card-foreground: var(--sc-card-foreground);
  --color-popover: var(--sc-popover);
  --color-popover-foreground: var(--sc-popover-foreground);
  --color-primary: var(--sc-primary);
  --color-primary-foreground: var(--sc-primary-foreground);
  --color-secondary: var(--sc-secondary);
  --color-secondary-foreground: var(--sc-secondary-foreground);
  --color-muted: var(--sc-muted);
  --color-muted-foreground: var(--sc-muted-foreground);
  --color-accent: var(--sc-accent);
  --color-accent-foreground: var(--sc-accent-foreground);
  --color-destructive: var(--sc-destructive);
  --color-border: var(--sc-border);
  --color-input: var(--sc-input);
  --color-ring: var(--sc-ring);
  --color-chart-1: var(--sc-chart-1);
  --color-chart-2: var(--sc-chart-2);
  --color-chart-3: var(--sc-chart-3);
  --color-chart-4: var(--sc-chart-4);
  --color-chart-5: var(--sc-chart-5);
  --color-sidebar: var(--sc-sidebar);
  --color-sidebar-foreground: var(--sc-sidebar-foreground);
  --color-sidebar-primary: var(--sc-sidebar-primary);
  --color-sidebar-primary-foreground: var(--sc-sidebar-primary-foreground);
  --color-sidebar-accent: var(--sc-sidebar-accent);
  --color-sidebar-accent-foreground: var(--sc-sidebar-accent-foreground);
  --color-sidebar-border: var(--sc-sidebar-border);
  --color-sidebar-ring: var(--sc-sidebar-ring);
  /* every token is a utility too: bg-navy, text-navy-accent, bg-ok-bg, text-danger-ink, bg-accent-soft ... */
  --color-bg: var(--bg);
  --color-surface: var(--surface);
  --color-surface-2: var(--surface-2);
  --color-surface-3: var(--surface-3);
  --color-ink: var(--ink);
  --color-faint: var(--faint);
  --color-line: var(--line);
  --color-control: var(--control);
  --color-accent-strong: var(--accent-strong);
  --color-accent-deep: var(--accent-deep);
  --color-accent-ink: var(--accent-ink);
  --color-accent-soft: var(--accent-soft);
  --color-on-accent: var(--on-accent);
  --color-navy: var(--navy);
  --color-on-navy: var(--on-navy);
  --color-navy-muted: var(--navy-muted);
  --color-navy-accent: var(--navy-accent);
  --color-inverse: var(--inverse);
  --color-on-inverse: var(--on-inverse);
  --color-danger-solid: var(--danger-solid);
  --color-ok: var(--ok);
  --color-ok-bg: var(--ok-bg);
  --color-ok-ink: var(--ok-ink);
  --color-danger: var(--danger);
  --color-danger-bg: var(--danger-bg);
  --color-danger-ink: var(--danger-ink);
  --color-warn: var(--warn);
  --color-warn-bg: var(--warn-bg);
  --color-warn-ink: var(--warn-ink);
}
@custom-variant dark (&:is(.dark *, [data-theme="dark"] *));
@layer base {
  *, ::before, ::after { border-color: var(--color-border); outline-color: color-mix(in oklab, var(--color-ring) 50%, transparent); }
}

tokens.js · JavaScript

// GENERATED by scripts/build-tokens.mjs from tokens/tokens.json, do not edit.
// The second theme only lists the tokens that differ from the first.
export const tokens = {
  "light": {
    "bg": "#f6f8fd",
    "surface": "#ffffff",
    "surface-2": "#eef2fb",
    "surface-3": "#e5e9f2",
    "ink": "#34364a",
    "muted": "#636a79",
    "faint": "#9aa3b2",
    "line": "#e8edf7",
    "control": "#868fa3",
    "accent": "#3d58ff",
    "accent-strong": "#1b37d9",
    "accent-deep": "#2447f9",
    "accent-ink": "#2447f9",
    "accent-soft": "#eaeeff",
    "on-accent": "#ffffff",
    "navy": "#110843",
    "on-navy": "#ffffff",
    "navy-muted": "rgba(255,255,255,0.72)",
    "navy-accent": "#8fa0ff",
    "inverse": "#110843",
    "on-inverse": "#ffffff",
    "danger-solid": "#d13438",
    "ok": "#23805b",
    "ok-bg": "#e2f5ee",
    "ok-ink": "#1f7a55",
    "danger": "#d13438",
    "danger-bg": "#fdecec",
    "danger-ink": "#b8292f",
    "warn": "#a8650f",
    "warn-bg": "#fbf0dd",
    "warn-ink": "#8a5a12",
    "shadow-card": "0 9px 30px rgba(17,8,67,0.06), 0 2px 6px rgba(17,8,67,0.03)",
    "shadow-sm": "0 1px 2px rgba(17,8,67,0.06)",
    "shadow-hover": "0 14px 34px rgba(17,8,67,0.10)",
    "space-1": "4px",
    "space-2": "8px",
    "space-3": "12px",
    "space-4": "16px",
    "space-5": "20px",
    "space-6": "24px",
    "space-8": "32px",
    "space-card": "30px",
    "radius-sm": "8px",
    "radius-md": "12px",
    "radius-lg": "16px",
    "radius-header": "22px",
    "radius-panel": "26px",
    "radius-pill": "100px",
    "font-sans": "\"Poppins\", system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif",
    "font-mono": "\"JetBrains Mono\", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
    "font-size-display": "32px",
    "line-height-display": "48px",
    "font-weight-display": "700",
    "font-size-h1": "26px",
    "line-height-h1": "39px",
    "font-weight-h1": "700",
    "font-size-h2": "24px",
    "line-height-h2": "36px",
    "font-weight-h2": "700",
    "font-size-title": "20px",
    "line-height-title": "30px",
    "font-weight-title": "700",
    "font-size-eyebrow": "18px",
    "line-height-eyebrow": "27px",
    "font-weight-eyebrow": "600",
    "font-size-body": "16px",
    "line-height-body": "24px",
    "font-weight-body": "400",
    "font-size-body-light": "16px",
    "line-height-body-light": "24px",
    "font-weight-body-light": "300",
    "font-size-label": "16px",
    "line-height-label": "24px",
    "font-weight-label": "500",
    "font-size-meta": "14px",
    "line-height-meta": "21px",
    "font-weight-meta": "400",
    "font-size-button": "16px",
    "line-height-button": "24px",
    "font-weight-button": "600",
    "font-size-mono": "13px",
    "line-height-mono": "18px",
    "font-weight-mono": "400"
  },
  "dark": {
    "bg": "#12131c",
    "surface": "#1c1f2b",
    "surface-2": "#232735",
    "surface-3": "#2b3040",
    "ink": "#eef0f6",
    "muted": "#a6abc0",
    "faint": "#6e7488",
    "line": "#2e3242",
    "control": "#737a8f",
    "accent": "#6b80ff",
    "accent-strong": "#8fa0ff",
    "accent-deep": "#4a63ff",
    "accent-ink": "#a9b6ff",
    "accent-soft": "#1f2550",
    "navy": "#1b1452",
    "inverse": "#2c2366",
    "ok": "#35c57f",
    "ok-bg": "#123726",
    "ok-ink": "#7ee0a8",
    "danger": "#f08a8a",
    "danger-bg": "#3a1e1e",
    "danger-ink": "#f3a3a3",
    "warn": "#e0a64a",
    "warn-bg": "#352c12",
    "warn-ink": "#e8be7a",
    "shadow-card": "0 9px 30px rgba(0,0,0,0.35), 0 2px 6px rgba(0,0,0,0.25)",
    "shadow-hover": "0 14px 34px rgba(0,0,0,0.5)"
  }
};
export default tokens;