Colors

Four palettes — Iron Night, Birch Mist, Forest, Bloom — organised by role. A two-layer token architecture separates raw palette values from semantic aliases, so components never need to know which theme mode they are in.

Palette Tokens

Raw palette tokens are defined once and never change. Use them directly only for brand moments and design showcases — all production components reference the semantic layer instead.

Iron Night — Dark Surfaces

--in0-void#0D1117
--in1-iron#374151
--in2-slate#4B5563
--in3-ash#6B7280
TokenHexRole
--in0-void#0D1117Primary background (dark mode)
--in1-iron#374151Elevated surfaces — panels, cards on dark
--in2-slate#4B5563Active lines, selections, highlights
--in3-ash#6B7280Secondary text, placeholders (AA-large only)

Birch Mist — Light Surfaces

--bm0-sand#D5D2C7
--bm1-mist#E9E6DC
--bm2-birch#F7F6F3
TokenHexRole
--bm0-sand#D5D2C7Elevated UI (light), input fills, sunken surfaces
--bm1-mist#E9E6DCCard fill, hover states, tinted sections
--bm2-birch#F7F6F3Primary background (light) / primary text (dark)

Forest — Accent

--fo0-sage#5C9E86
--fo1-fern#3E7A62
--fo2-forest#2D5E4A
--fo3-deepwater#254D5A
TokenHexRole
--fo0-sage#5C9E86Supporting accent, dark-mode hover state for Fern
--fo1-fern#3E7A62Primary accent — buttons, links, CTAs (both modes)
--fo2-forest#2D5E4AAccent hover, secondary emphasis
--fo3-deepwater#254D5ACode block backgrounds (light pages), blockquote accent

Bloom — Semantic States

--bl0-ember#C5414C
--bl1-ochre#AB5A2B
--bl2-grain#8D6B20
--bl3-moss#567A37
--bl4-heather#885DB4
TokenHexRole
--bl0-ember#C5414CError, destructive actions
--bl1-ochre#AB5A2BAnnotation, decorator-weight info
--bl2-grain#8D6B20Warning, draft, pending
--bl3-moss#567A37Success, published, active
--bl4-heather#885DB4Special states, beta, experimental

Semantic Token Layer

Components always reference semantic tokens — never palette tokens directly. The semantic layer resolves to the correct palette value per theme mode automatically.

Light Mode (default)

:root,
[data-theme="light"] {
  --color-bg:             var(--bm2-birch);           /* Page background        */
  --color-bg-panel:       var(--bm1-mist);            /* Cards, panels          */
  --color-bg-inset:       var(--bm0-sand);            /* Input fills            */
  --color-bg-code:        var(--fo3-deepwater);       /* Code block background  */
  --color-text:           var(--in0-void);            /* Primary text           */
  --color-text-secondary: var(--in2-slate);           /* Supporting text        */
  --color-text-tertiary:  var(--in3-ash);             /* Placeholders, captions */
  --color-border:         var(--in3-ash);             /* Default border         */
  --color-border-strong:  var(--in1-iron);            /* Prominent dividers     */
  --color-border-subtle:  rgba(55,65,81,0.12);        /* Hairline borders       */
  --color-ghost-border:   rgba(55,65,81,0.25);        /* Ghost button border    */
  --color-accent:         var(--fo1-fern);            /* Primary CTA, links     */
  --color-accent-hover:   var(--fo2-forest);          /* Accent hover           */
  --color-accent-text:    var(--bm2-birch);           /* Text on accent bg      */
  --color-error:          var(--bl0-ember);           /* Error, destructive     */
  --color-warning:        var(--bl2-grain);           /* Warning, draft         */
  --color-success:        var(--bl3-moss);            /* Success, published     */
}

Dark Mode

[data-theme="dark"] {
  --color-bg:             var(--in0-void);
  --color-bg-panel:       var(--in1-iron);
  --color-bg-inset:       var(--in2-slate);
  --color-bg-code:        var(--in1-iron);
  --color-text:           var(--bm2-birch);
  --color-text-secondary: var(--bm1-mist);
  --color-text-tertiary:  var(--bm0-sand);
  --color-border:         var(--in2-slate);
  --color-border-strong:  var(--bm0-sand);
  --color-border-subtle:  rgba(75,85,99,0.25);
  --color-ghost-border:   rgba(247,246,243,0.25);
  --color-accent:         var(--fo1-fern);
  --color-accent-hover:   var(--fo0-sage);
  --color-accent-text:    var(--bm2-birch);
  --color-error:          var(--bl0-ember);
  --color-warning:        var(--bl2-grain);
  --color-success:        var(--bl3-moss);
}

Surface Depth

Apply data-surface to set a depth level on any element. All surfaces are relative — they adapt when the page theme switches. Use data-theme on an element to force a specific theme context.

<section data-surface="base"> … </section>    <!-- page-level -->
<section data-surface="layer"> … </section>   <!-- cards, panels -->
<section data-surface="overlay"> … </section> <!-- modals, dropdowns -->
<section data-theme="dark" data-surface="layer"> … </section> <!-- forced dark panel -->

Accessibility

Full contrast matrix for all semantic foreground/background token pairs. Ratings follow WCAG 2.1: AAA ≥ 7:1 · AA ≥ 4.5:1 · AA Large ≥ 3:1 (≥ 24 px regular, or ≥ 19 px bold) · Fail < 3:1.

Light mode

Foreground token on --color-bg on --color-bg-elevated on --color-bg-sunken
--color-text 17.51:1 AAA 15.15:1 AAA 12.50:1 AAA
--color-text-secondary 6.99:1 AA 6.05:1 AA 4.99:1 AA
--color-text-tertiary 4.47:1 AA Large 3.87:1 AA Large 3.19:1 AA Large
--color-accent 4.67:1 AA 4.04:1 AA Large 3.33:1 AA Large
--color-accent-hover 6.91:1 AA 5.98:1 AA 4.93:1 AA
--color-accent-text 1.00:1 Fail 1.16:1 Fail 1.40:1 Fail
--color-error 4.59:1 AA 3.97:1 AA Large 3.28:1 AA Large
--color-warning 4.57:1 AA 3.95:1 AA Large 3.26:1 AA Large
--color-success 4.59:1 AA 3.97:1 AA Large 3.28:1 AA Large

Dark mode

Foreground token on --color-bg on --color-bg-elevated on --color-bg-sunken
--color-text 17.51:1 AAA 9.54:1 AAA 17.51:1 AAA
--color-text-secondary 15.15:1 AAA 8.25:1 AAA 15.15:1 AAA
--color-text-tertiary 12.50:1 AAA 6.81:1 AA 12.50:1 AAA
--color-accent 3.75:1 AA Large 2.04:1 Fail 3.75:1 AA Large
--color-accent-hover 6.03:1 AA 3.28:1 AA Large 6.03:1 AA
--color-accent-text 17.51:1 AAA 9.54:1 AAA 17.51:1 AAA
--color-error 3.82:1 AA Large 2.08:1 Fail 3.82:1 AA Large
--color-warning 3.84:1 AA Large 2.09:1 Fail 3.84:1 AA Large
--color-success 3.82:1 AA Large 2.08:1 Fail 3.82:1 AA Large

--color-accent-text (light mode) is designed for text on --color-accent button backgrounds — Fail against page surfaces is by design. State tokens (error/warning/success) marked † fall below 3:1 on --color-bg-elevated in dark mode; pair with an icon or use on --color-bg/--color-bg-sunken instead. Note: in dark mode --color-bg and --color-bg-sunken both resolve to --in0-void, so those two columns are identical by design. --color-text-tertiary is AA Large only in all light-mode contexts — never use it for body-size text; restrict to ≥ 24 px regular or ≥ 19 px bold.

Usage Rules