Styles
Color
Ink, paper, and rust scales, domain signals, and the semantic color roles every component reads.
Scales
tokens/colors.cssInk — the near-black canvas and its greys
ink-950
#0a0a0a
ink-900
#0e0e0e
ink-850
#121212
ink-800
#1a1a1a
ink-750
#202020
ink-700
#2a2a2a
ink-600
#444444
ink-500
#666666
ink-400
#999999
ink-300
#c2c2c2
ink-200
#e8e8e8
ink-100
#f5f5f5
ink-50
#fafafa
Paper — warm off-whites for the reading tone
paper-50
#faf9f7
paper-100
#f3f1ec
paper-150
#ece9e2
paper-200
#e4e0d8
paper-300
#d6d1c6
paper-400
#b0aa9d
paper-500
#847f74
paper-600
#595550
paper-700
#38352f
Rust — the one warm accent, anchored at 500
rust-700
#8f3d0c
rust-600
#a8480f
rust-500
#c0551a
rust-400
#d4762f
rust-300
#e8a080
rust-200
#f2c9b3
Domain signals
--signal-*One accent per content stream, desaturated on purpose. Never introduce hues outside this set — differentiate with value, not new colors.
Semantic roles
ink · paperComponents read these roles only. Each theme block redefines the full set, so a nested data-theme wrapper switches tone cleanly.
| Role | Ink | Paper | Usage |
|---|---|---|---|
| --color-bg | #0e0e0e | #faf9f7 | Page canvas |
| --color-bg-elevated | #1a1a1a | #ffffff | Cards, chips, inputs |
| --color-bg-panel | #121212 | #f3f1ec | Recessed panels |
| --color-bg-deep | #0a0a0a | #e4e0d8 | Deepest wells, code blocks |
| --color-bg-hover | #202020 | #f3f1ec | Hover fills |
| --color-fg | #fafafa | #0a0a0a | Primary text |
| --color-fg-muted | #c2c2c2 | #38352f | Secondary text |
| --color-fg-subtle | #999999 | #595550 | Meta, labels |
| --color-border | #2a2a2a | #e4e0d8 | Hairlines at rest |
| --color-border-hover | #444444 | #d6d1c6 | Hairlines, lit |
| --surface-contrast | #ffffff | #0e0e0e | Opposite-tone card |
| --on-contrast | #0a0a0a | #f5f5f5 | Text on contrast |
| --accent | #c0551a | #a8480f | Active domain accent |
| --accent-on | #f5f5f5 | #ffffff | Text on accent fills |
| --selection-bg | #f5f5f5 | #f2c9b3 | Text selection |
/* Author against SEMANTIC roles — never raw hex. The same rule
renders correctly on ink and on paper. */
.my-card {
background: var(--color-bg-elevated);
color: var(--color-fg);
border: 1px solid var(--color-border);
}
.my-card:hover {
border-color: var(--color-border-hover); /* lift = brighter hairline */
}Dual tone, live
data-theme="ink | paper"data-theme="ink"
Quiet, cinematic
Annotation Builder
The same card, reading semantic tokens only.
data-theme="paper"
Warm, editorial
Annotation Builder
The same card, reading semantic tokens only.
Domain signals, live
data-stream="…"Writing carries the rust signature — issue labels, ledes, pullquote rules.
Video-led work carries warm amber — the eyebrow tick above the work band.
Design systems carry muted steel — including these pages.