01

Design Foundation

Design Tokens

Single source of truth for all visual decisions. All values are exposed as CSS custom properties on :root. Use token names (not raw values) in all implementation work.

Color Palette

All 13 approved brand colors. Each has a named token and defined semantic role. No off-palette colors permitted.

Alpine
#23403b
--color-alpine
Primary dark, nav BG, headings, secondary button
Salt
#f6f4ed
--color-salt
Primary page background, text on dark
White
#ffffff
--color-white
Pure white surface — cards, modals, popovers, data-table rows
BSI Yellow
#f1f14d
--color-bsi-yellow
On Alpine: icons, text, accents (9.33:1 AAA). As .btn-primary-dark fill + Carbon text (17.43:1 AAA). Never on white or Salt surfaces.
Carbon
#000000
--color-carbon
Footer, type on BSI Yellow. Reserved.
Arches
#b47351
--color-arches
Section labels, eyebrows, warning states
Canyonlands
#6c372e
--color-canyonlands
Error states, danger buttons, subheads
Timpanogos
#3f2d39
--color-timpanogos
Deep accent, editorial moments
Sage
#a2a882
--color-sage
Muted secondary UI, subtle labels
Uinta
#43573d
--color-uinta
Success states, positive indicators
Bonneville
#9ebbd0
--color-bonneville
Informational, light interactive elements
Wasatch
#5a87c3
--color-wasatch
Links, focus rings, interactive blue
Albion
#fff1b0
--color-albion
Contained highlight surfaces only
AI Usage Rule: Only use these 13 approved colors. BSI Yellow (#f1f14d) is accent-only — never use as a page background, and never as text or icon color on Salt or white surfaces. Carbon (#000) is reserved for footer and type only. White (#fff) is the canonical surface for cards / modals / popovers / data-table rows; Salt is the page background. All other background choices should use Salt, Alpine, or White.

Semantic Text & Gray Tokens

The approved neutral scale used for typography, icons, borders, and separators. These tokens cover every gray in the system — never use raw hex grays (e.g. #555, #888) in components. White (#ffffff) anchors the lightest end of the scale as the canonical surface for cards, modals, popovers, and data-table rows.

White
#ffffff
--color-white
Surface anchor — cards, modals, popovers, table rows
Heading
#111
--text-heading
Page titles, modal titles, strong labels
Primary
#222
--text-primary
Primary text, form labels, active breadcrumb
Body
#444
--text-body
Body copy, task labels
Secondary
#666
--text-secondary
Descriptions, secondary info, hints
Muted
#777
--text-muted
Tertiary text, thinking states
Chart Label
#888
--chart-label
Chart axes, form hints, metadata, timestamps
Disabled
#aaa
--text-disabled
Disabled text, placeholders, step labels, muted icons, inactive breadcrumb
Placeholder
#bbb
--text-placeholder
Very muted text, input placeholders
Border Muted
#ccc
--border-muted
Subtle borders, separators, draft status dots
Rule: Always reference the token, never the hex. The gray scale is single-purpose — text and icons share the same neutrals. If a darker disabled state is needed for icons specifically, escalate the proposal rather than introducing an off-token value.

BSI Yellow — Accessibility & Contrast Audit

BSI Yellow (#f1f14d) is a high-luminance color (relative luminance 0.822). This makes it exceptional on dark surfaces but creates near-zero contrast against light ones. All usage must be evaluated against its background. WCAG 2.1 thresholds: 4.5:1 AA text · 3:1 AA large text / non-text UI · 7:1 AAA text.

Yellow on…RatioWCAGVerdictCorrect usage
Alpine #23403b 9.33:1 AAA ✓ ✅ Yellow on Alpine — all uses permitted Nav icons, send button icon, agent avatar, cover accents, code sample syntax — any yellow element sitting directly on Alpine
Yellow bg + Carbon #000 17.43:1 AAA ✓ ✅ Yellow bg with Carbon text — all uses permitted .btn-primary-dark (dark surface primary button), chip-yellow, badge-brand, new-badge
White #ffffff 1.20:1 FAIL ✗ ❌ Never use Yellow as text, icon, or indicator on white Use Alpine (#23403b) instead — 11.24:1 on white
Salt #f6f4ed 1.09:1 FAIL ✗ ❌ Never use Yellow on Salt — effectively invisible Salt and Yellow share almost identical luminance (0.904 vs 0.822). Use Alpine instead — 10.22:1 on Salt

Contrast demonstration

Yellow on Alpine Label text
9.33:1 — AAA ✓
Yellow bg / Carbon Button label
17.43:1 — AAA ✓
Yellow on White Invisible text
1.20:1 — FAIL ✗
Yellow on Salt Invisible text
1.09:1 — FAIL ✗
Rule — when BSI Yellow is safe:
Yellow on Alpine (9.33:1 AAA) — icons, text, accents, and .btn-primary-dark button fills on any Alpine/dark background
Yellow as filled background + Carbon text (17.43:1 AAA) — .btn-primary-dark button, chip-yellow, badge-brand, new-badge
Yellow on white or Salt — fails at 1.20:1 and 1.09:1. Never use Yellow as text, icon, border, or indicator on light surfaces.

Dark surface primary button rule: On Alpine backgrounds (nav, dark cards, dark sections), use .btn-primary-dark (BSI Yellow + Carbon text). On white/Salt backgrounds, use .btn-primary (Alpine + Salt text). The two classes are context-paired — never swap them across surface types.

Semantic Color Tokens

TokenValuePreviewUsage
--bg-primaryvar(--color-salt)
Page background
--bg-darkvar(--color-alpine)
Dark surfaces, nav
--text-primary#222Primary text
--text-body#444Body copy
--text-muted#777Secondary text, hints
--text-labelvar(--color-arches)
Section eyebrows
--text-linkvar(--color-wasatch)
Links, interactive text
--text-errorvar(--color-canyonlands)
Error messages
--text-successvar(--color-uinta)
Success messages
--border-defaultrgba(0,0,0,.1)Default borders
--focus-ring0 0 0 3px rgba(91,135,195,.45)Keyboard focus

Spacing Scale

--space-14px
--space-28px
--space-312px
--space-416px
--space-520px
--space-624px
--space-728px
--space-832px
--space-1040px
--space-1248px
--space-1664px

Border Radius

--radius-xs 4px · tags
--radius-sm 6px · small elements
--radius-input 8px · inputs
--radius-card 12px · cards
--radius-pill 999px · buttons

Elevation / Shadows

--shadow-sm

Cards, inputs on hover

--shadow-md

Elevated cards, dropdowns

--shadow-lg

Modals, drawers

Motion Tokens

--transition-fast

100ms ease · micro UI

--transition-base

160ms ease · standard

--transition-slow

280ms ease · overlays

--transition-spring

220ms cubic-bezier spring