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.

Accent
--accent

Primary accent color

Accent Hover
--accent-hover

Lighter on hover

Accent Deep
--accent-deep

The 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 Subtle
--accent-subtle

Soft background tint (~10%)

Accent Soft
--accent-soft

Mid borders, hover wash (~20%)

Accent Strong
--accent-strong

Strong 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.

Background
--background

Page background — the darkest surface (#0f121a navy)

Surface Lift
--surface-lift

Not 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 Section
--surface-section

The 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 Panel
--surface-ink-panel

The 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.

Surface
--surface

Cards, inputs, placeholders

Surface Band
--surface-band

Exactly 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 Elevated
--surface-elevated

Elevated cards, buttons, popovers

Surface Hover
--surface-hover

Hover states

Surface Card
--surface-card

Flat 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 Ink
--surface-ink

CTA button fill. Note: the token --surface-ink is unrelated to the .surface-ink class, which restores dark tokens inside a light section.

Surface Ink Hover
--surface-ink-hover

CTA hover state

Text

Text hierarchy from primary to muted.

Foreground
--foreground

Primary text

Foreground Secondary
--foreground-secondary

Body copy, hero subtitles, descriptions (72%)

Text Tertiary
--text-tertiary

Tertiary text, metadata (40%)

Text Muted
--text-muted

Muted text and placeholders (30%)

Borders

Border colors for dividers and container outlines.

Border
--border

Default borders

Border Subtle
--border-subtle

Subtle borders

Decorative

Status colors for success (green), errors (red), and ratings (gold).

Green
--green

Success/available

Green Deep
--green-deep

Light-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 Deep
--red-deep

Light-ground twin of --red — clears 4.5:1 on white.

Orange Deep
--orange-deep

Light-ground twin of --orange — clears 4.5:1 on white.

Gold
--gold

Stars/ratings

Red
--red

Errors/danger

Orange
--orange

Attention/availability

Foreground opacity

White overlays at low opacity used for faint tints, dividers, and hover highlights.

Foreground Subtle
--foreground-subtle

Faint overlays and illustration fills (~5%). Frame hairlines use --border-subtle, not this.

Foreground Overlay
--foreground-overlay

Hover 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-accent

CSS Variables

color: var(--foreground);background: var(--accent-subtle);box-shadow: 0 0 30px var(--accent-strong);