Colors
Dark-mode-only color system built from CSS variables — no theme switching. The surface classes are the sanctioned exception: .surface-paper / .surface-white are a light plane inside the dark site, and .surface-ink a dark island within one. They re-point these same tokens for a subtree, so components adapt without any component-specific colours. Uses the production blue accent scale.
Accent
Primary accent family — 6 tokens cover everything from primary buttons to subtle background tints and strong glows.
--accentPrimary accent color
--accent-hoverLighter on hover
--accent-deepThe dark end of the accent, and the one to reach for behind white text — every value in the set measures 5.8-6.1:1, clearing AA where the bright --accent does not. Drives the service card hover CTA badge, plus hero and avatar gradients. Re-pointed per card by the .svc-accent-* classes; the only accent token neither surface class touches.
--accent-subtleSoft background tint (~10%)
--accent-softMid borders, hover wash (~20%)
--accent-strongStrong borders, glows, shadows (~40%)
The swatches above are the blue the site defaults to, but the accent family is not fixed. Each service card carries one of svc-accent-blue, svc-accent-violet, svc-accent-magenta or svc-accent-teal, which re-points all six tokens for that card's subtree — so its illustration, tick marks, focus ring and title highlight all take the card's colour without any of them knowing about it. Same mechanism the surface classes use, one level deeper.
Two rules govern the set. Hue spacing is chosen in OKLCH, not HSL — HSL compresses the blue region badly enough that “distinct” colours come out looking identical; blue sits at 255°, and green (163°), gold (86°) and orange (56°) are reserved for status, leaving only the cyan-to-teal band and the violet-to-magenta arc free. And every --accent-deep is a solid fill behind white text, so each one is held to at least 4.5:1 — the four in use measure 5.8–6.1:1, tight enough that the title highlights read as one family rather than four weights.
Backgrounds
Page background plus the section ground tints.
--backgroundPage background — the darkest surface (#0f121a navy)
--surface-liftNot painted directly: the mid navy (#3d5a99) every lighter dark surface mixes toward, in oklch, so the ladder keeps its navy hue as it lightens.
--surface-sectionThe tint ground (SectionFrame surface="tint") — only a whisper above the page background, so a hero or testimonial band reads as a faint plane rather than a lighter slab. Translucent, so it composites onto any ground. The light grounds re-point it to cream / white.
--surface-ink-panelThe opaque dark plane cards and panels sit on. Backs the CategoryFilters scroll fade, and — on a light ground — the card fills in .surface-paper .card-service / .card-carousel-item, whose washes end on transparent and would otherwise let the cream tint them. Equals --surface-section composited over --background at :root and under .surface-ink; deliberately diverges under .surface-paper.
Surfaces
Elevated surfaces for cards, inputs, popovers, and the always-dark ink surface used by the CTA button.
--surfaceCards, inputs, placeholders
--surface-bandExactly the base navy (#0f121a) for the homepage "Who I work best with" band — it reads as its own zone between the tint testimonials band above and the light case-studies band below. Applied with SectionFrame surface="band".
--surface-elevatedElevated cards, buttons, popovers
--surface-hoverHover states
--surface-cardFlat card plane (the base lifted 18% toward --surface-lift, in oklch) — testimonial and ux-audit panels. The non-gradient counterpart to --gradient-card-surface. Opaque on purpose: a translucent version let decorative page glows bleed through and tint the larger cards.
--surface-inkCTA button fill. Note: the token --surface-ink is unrelated to the .surface-ink class, which restores dark tokens inside a light section.
--surface-ink-hoverCTA hover state
Text
Text hierarchy from primary to muted.
--foregroundPrimary text
--foreground-secondaryBody copy, hero subtitles, descriptions (72%)
--text-tertiaryTertiary text, metadata (40%)
--text-mutedMuted text and placeholders (30%)
Borders
Border colors for dividers and container outlines.
--borderDefault borders
--border-subtleSubtle borders
Decorative
Status colors for success (green), errors (red), and ratings (gold).
--greenSuccess/available
--green-deepLight-ground twin of --green (as --accent-deep is to --accent) — clears 4.5:1 on white. Used by the light UX audit hero mockup.
--red-deepLight-ground twin of --red — clears 4.5:1 on white.
--orange-deepLight-ground twin of --orange — clears 4.5:1 on white.
--goldStars/ratings
--redErrors/danger
--orangeAttention/availability
Foreground opacity
White overlays at low opacity used for faint tints, dividers, and hover highlights.
--foreground-subtleFaint overlays and illustration fills (~5%). Frame hairlines use --border-subtle, not this.
--foreground-overlayHover highlights (~10%). Carousel arrows use a solid --background so they read on whatever they overlay.
Usage
Tailwind Classes
bg-surface, bg-surface-elevated, bg-accent, bg-accent-hovertext-foreground, text-text-tertiary, text-accentborder-border, border-border-subtle, border-accentCSS Variables
color: var(--foreground);background: var(--accent-subtle);box-shadow: 0 0 30px var(--accent-strong);