Colors

Four primitive ramps and twelve semantic roles, extracted from the components rather than declared ahead of them. Body text is held to 4.5:1 against its background, and where a colour does not clear that bar the audit reports it rather than the system quietly hiding it.

in-sync·Source: css:blocks/base.css·Last synced 11d ago

Semantic

Primary text. Headings, body copy, stat figures.

#161616

Rating stars. 1.63:1 on white, below AA — the deliberate contrast bug the demo shows the audit catching.

#f3c60d

Brand mark and eyebrow labels. Same value as accent, kept separate so a rebrand can move one without the other.

#2b59ff

Tertiary text. 3.45:1 on white, below AA — a finding the demo keeps.

#8a8a8a

Secondary text. Section intros and card copy.

#5c5c5c

Primary action. Buttons, links, active states.

#2b59ff

Hairline borders, dividers and card outlines.

#e3e3e3

Page background behind the blocks.

#f5f5f5

Positive state and upward metrics. 3.54:1 on white, below AA — a finding the demo keeps.

#3f9b2b

Raised surfaces: cards, panels, secondary buttons.

#ffffff

A second border value, used once: the features section top rule. One step darker than --border (#e3e3e3 to #d4d4d4, a delta of 5.3 in L*), which lifts that rule from 1.18:1 to 1.36:1 against the section's own background. Reads as drift, not intent; held at its measured value until that is decided.

#d4d4d4

A second page background, used once: the hero. One step lighter than --ground (#f5f5f5 to #f9f9f9, a delta of 1.4 in L*) and it overrides .dot-grid's own background-color: var(--ground) in the same cascade. Reads as drift, not intent; held at its measured value until that is decided.

#f9f9f9

Accent on --dark-ground: the highlighted span in the stats heading. 8.17:1 there, where --accent would be 3.63:1 and fail AA — which is why the dark context carries its own accent role instead of reusing the light one.

#7fa8ff

Dark section background: the inverted counterpart to --ground, and the system's only dark context. One block uses it, the stats block. White text on it is 19.18:1.

#0b0f17

Hover fill for a primary action.

#1f47d9

Text and icons on an accent fill.

#ffffff
:root {
  --color-neutral-0: #ffffff; /** White. Card, panel and button surfaces. */
  --color-neutral-25: #f9f9f9; /** Off-white, one step lighter than 50 (L* 97.9 vs 96.5). Used once, by the hero background. */
  --color-neutral-50: #f5f5f5; /** Off-white. The page behind every block. */
  --color-neutral-200: #e3e3e3; /** Light grey. Hairline borders and dividers. */
  --color-neutral-300: #d4d4d4; /** Light grey one step darker than 200 (L* 84.9 vs 90.2). Used once, by the features section top rule. */
  --color-neutral-500: #8a8a8a; /** Mid grey. 3.45:1 on white. */
  --color-neutral-700: #5c5c5c; /** Dark grey. 6.69:1 on white. */
  --color-neutral-950: #161616; /** Near-black. 18.1:1 on white. */
  --color-blue-300: #7fa8ff; /** Light blue, hsl(221 100% 75%). 8.17:1 on blue 950, which is the only place it is used. */
  --color-blue-500: #2b59ff; /** Brand blue. 5.28:1 on white. */
  --color-blue-600: #1f47d9; /** Deeper blue for pressed and hover states. */
  --color-blue-950: #0b0f17; /** Near-black with a blue cast, hsl(220 35% 7%). Not on the pure-grey neutral ramp, which is why it sits with the blues. The system's only dark surface. */
  --color-green-600: #3f9b2b; /** Green. 3.54:1 on white. */
  --color-yellow-400: #f3c60d; /** Yellow. 1.63:1 on white. */
  --color-semantic-ink: #161616; /** Primary text. Headings, body copy, stat figures. */
  --color-semantic-muted: #5c5c5c; /** Secondary text. Section intros and card copy. */
  --color-semantic-faint: #8a8a8a; /** Tertiary text. 3.45:1 on white, below AA — a finding the demo keeps. */
  --color-semantic-ground: #f5f5f5; /** Page background behind the blocks. */
  --color-semantic-ground-alt: #f9f9f9; /** A second page background, used once: the hero. One step lighter than --ground (#f5f5f5 to #f9f9f9, a delta of 1.4 in L*) and it overrides .dot-grid's own background-color: var(--ground) in the same cascade. Reads as drift, not intent; held at its measured value until that is decided. */
  --color-semantic-surface: #ffffff; /** Raised surfaces: cards, panels, secondary buttons. */
  --color-semantic-border: #e3e3e3; /** Hairline borders, dividers and card outlines. */
  --color-semantic-border-alt: #d4d4d4; /** A second border value, used once: the features section top rule. One step darker than --border (#e3e3e3 to #d4d4d4, a delta of 5.3 in L*), which lifts that rule from 1.18:1 to 1.36:1 against the section's own background. Reads as drift, not intent; held at its measured value until that is decided. */
  --color-semantic-accent: #2b59ff; /** Primary action. Buttons, links, active states. */
  --color-semantic-accent-hover: #1f47d9; /** Hover fill for a primary action. */
  --color-semantic-accent-contrast: #ffffff; /** Text and icons on an accent fill. */
  --color-semantic-brand: #2b59ff; /** Brand mark and eyebrow labels. Same value as accent, kept separate so a rebrand can move one without the other. */
  --color-semantic-success: #3f9b2b; /** Positive state and upward metrics. 3.54:1 on white, below AA — a finding the demo keeps. */
  --color-semantic-star: #f3c60d; /** Rating stars. 1.63:1 on white, below AA — the deliberate contrast bug the demo shows the audit catching. */
  --color-semantic-dark-ground: #0b0f17; /** Dark section background: the inverted counterpart to --ground, and the system's only dark context. One block uses it, the stats block. White text on it is 19.18:1. */
  --color-semantic-dark-accent: #7fa8ff; /** Accent on --dark-ground: the highlighted span in the stats heading. 8.17:1 there, where --accent would be 3.63:1 and fail AA — which is why the dark context carries its own accent role instead of reusing the light one. */
}