@dataimago/tokens 0.1.0-alpha.3 → 0.1.0-alpha.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,10 +16,15 @@
16
16
  "dark": "#1c1917",
17
17
  "description": "Cards, modals, dropdowns — one step above page (stone-50 on stone-100 / ink-800 on stone-900-aligned dark)"
18
18
  },
19
+ "figure-plate": {
20
+ "light": "#f7f7f6",
21
+ "dark": "#dcdcda",
22
+ "description": "Figure plate: the ground a .box figure sits on, in HTML (figure img.box, the figure modal) and the PDF (di-figure-plate). Figures are dark ink and Okabe-Ito colours drawn for a light ground, so the plate stays light in dark mode, dimmed one step to cut glare: stone-50 (light) / stone-200 (dark). Dark-mode plate #dcdcda: dark ink 13.5:1, okabe-ito blue 3.8, vermillion 2.8, bluish-green 2.5, reddish-purple 2.2, sky-blue 1.7, orange 1.6 (the light plate's 4.8/3.6/3.2/2.9/2.2/2.1); the light content.secondary frame 3.9:1 on it. Hue separation is checked plate-independently by the data-viz colour-blind gate. Maintainer decision 2026-11-01 (dimmed light plate); a 42%-white mix over the dark page (#777774) was rejected (colours ~1.2:1)."
23
+ },
19
24
  "sunken": {
20
- "light": "#faf2e3",
25
+ "light": "#f7f7f6",
21
26
  "dark": "#0c0a09",
22
- "description": "Input fields, code blocks — below page level"
27
+ "description": "Input fields and insets. Light: the card colour, stone-50 (since 2026-11-02; it was the warm paper-200 #faf2e3). Dark: ink-900, below the page. Code blocks use surface.code."
23
28
  },
24
29
  "navbar": {
25
30
  "light": "#ededeb",
@@ -32,36 +37,56 @@
32
37
  "description": "Navbar when scrolled/shrunk — matches page-scrolled"
33
38
  },
34
39
  "code": {
35
- "light": "#faf2e3",
40
+ "light": "#f7f7f6",
36
41
  "dark": "#1c1917",
37
- "description": "Code block and inline code background"
42
+ "description": "Code block and inline code background: the card colour (surface.elevated) in both modes, so code reads as a card on the page (2026-11-02; light mode was the warm paper-200 #faf2e3)"
43
+ },
44
+ "scrim": {
45
+ "light": "rgba(20, 20, 16, 0.85)",
46
+ "dark": "rgba(20, 20, 16, 0.85)",
47
+ "description": "Figure viewer backdrop. Mode-invariant: the scrim is dark in both modes, so light and dark carry the same value (the color.border.figure-frame precedent). Ink-900-ish at 0.85, drawn under a 3px blur; measured composited over the page, on-scrim text is 11.5:1 on the light page and 17.2:1 on the dark (gated by tools/contrast-check.mjs, 2026-11-03)."
48
+ },
49
+ "scrim-solid": {
50
+ "light": "rgba(20, 20, 16, 0.92)",
51
+ "dark": "rgba(20, 20, 16, 0.92)",
52
+ "description": "Figure viewer backdrop where backdrop blur is unavailable (prefers-reduced-transparency, prefers-contrast: more and browsers without backdrop blur): the same ink at 0.92. Mode-invariant: the scrim is dark in both modes, so light and dark carry the same value (the color.border.figure-frame precedent). Gated by tools/contrast-check.mjs."
38
53
  }
39
54
  },
40
55
  "border": {
41
56
  "subtle": {
42
- "light": "rgba(12, 10, 9, 0.08)",
43
- "dark": "rgba(253, 249, 242, 0.08)",
44
- "description": "Subtle borders — element separation"
57
+ "light": "rgba(12, 10, 9, 0.45)",
58
+ "dark": "rgba(253, 249, 242, 0.45)",
59
+ "description": "Subtle borders — element separation. THE ALPHA IS THE ROLE: border.subtle / moderate / strong / card share one base color and are distinguished by opacity alone, so a gamut conversion that drops the alpha channel collapses four semantic roles into one opaque value (this happened in 17995c3, #72, 2026-06-28). No number is quoted here on purpose: the scale is set by the founder decision recorded in wi-20260817-border-alpha-scale-retune and gated by tools/contrast-check.mjs at the WCAG 1.4.11 non-text threshold (3:1). Read the value, not this sentence."
45
60
  },
46
61
  "moderate": {
47
- "light": "rgba(12, 10, 9, 0.15)",
48
- "dark": "rgba(253, 249, 242, 0.15)",
49
- "description": "Moderate borders — defined boundaries"
62
+ "light": "rgba(12, 10, 9, 0.60)",
63
+ "dark": "rgba(253, 249, 242, 0.60)",
64
+ "description": "Moderate borders — defined boundaries. See border.subtle on why the alpha is load-bearing and why no number is quoted here."
50
65
  },
51
66
  "strong": {
52
- "light": "rgba(12, 10, 9, 0.25)",
53
- "dark": "rgba(253, 249, 242, 0.25)",
54
- "description": "Strong borders — prominent separation"
67
+ "light": "rgba(12, 10, 9, 0.75)",
68
+ "dark": "rgba(253, 249, 242, 0.75)",
69
+ "description": "Strong borders — prominent separation. See border.subtle on why the alpha is load-bearing and why no number is quoted here."
55
70
  },
56
71
  "card": {
57
- "light": "rgba(12, 10, 9, 0.15)",
58
- "dark": "rgba(253, 249, 242, 0.15)",
59
- "description": "Card border color with transparency for subtle definition"
72
+ "light": "rgba(12, 10, 9, 0.60)",
73
+ "dark": "rgba(253, 249, 242, 0.60)",
74
+ "description": "Card border color with transparency for subtle definition. See border.subtle on why the alpha is load-bearing and why no number is quoted here."
75
+ },
76
+ "figure-frame": {
77
+ "light": "#6a6a6a",
78
+ "dark": "#6a6a6a",
79
+ "description": "Figure frame: the 1px rule round a .box figure and the border of an enlarged figure in the figure modal. It sits on surface.figure-plate, which is light in both modes, so the frame keeps the light content.secondary value in both: 5.0:1 on the light plate #f7f7f6 and 3.9:1 on the dimmed dark-mode plate #dcdcda (WCAG 1.4.11 non-text, 3:1). The PDF's di-figure-frame is the same colour (2026-11-01)."
60
80
  },
61
81
  "code": {
62
82
  "light": "#d6d3d1",
63
83
  "dark": "#292524",
64
84
  "description": "Code block border"
85
+ },
86
+ "on-scrim-focus": {
87
+ "light": "#3498DB",
88
+ "dark": "#3498DB",
89
+ "description": "Focus ring on the figure viewer scrim. Mode-invariant: the scrim is dark in both modes, so light and dark carry the same value (the color.border.figure-frame precedent). The slate accent's dark-mode value in both modes, because the scrim is dark in both. Held to 3:1 (WCAG 1.4.11) over both scrims and both page modes by tools/contrast-check.mjs."
65
90
  }
66
91
  },
67
92
  "content": {
@@ -71,19 +96,24 @@
71
96
  "description": "Primary text — stone-900 on stone-100 (light, matches presentation-theme.scss exactly) / paper-100 on dark surface"
72
97
  },
73
98
  "secondary": {
74
- "light": "#7c7c7c",
99
+ "light": "#6a6a6a",
75
100
  "dark": "#a8a29e",
76
- "description": "Secondary text — stone-500 (light, matches presentation-theme.scss --color-secondary) / ink-300 on dark"
101
+ "description": "Secondary text — WCAG-AA on all light surfaces (≥4.6:1, darkened from stone-500 #7c7c7c which was 3.6:1) / ink-300 on dark"
77
102
  },
78
103
  "muted": {
79
- "light": "#78716c",
80
- "dark": "#78716c",
81
- "description": "Muted text — captions, meta info"
104
+ "light": "#706964",
105
+ "dark": "#89827d",
106
+ "description": "Muted text — captions, meta info. WCAG-AA on all surfaces in both modes (darkened/lightened from #78716c which failed AA on page)"
82
107
  },
83
108
  "inverse": {
84
109
  "light": "#fdf9f2",
85
110
  "dark": "#0c0a09",
86
111
  "description": "Inverse text — for contrasting backgrounds"
112
+ },
113
+ "on-scrim": {
114
+ "light": "#f7f7f6",
115
+ "dark": "#f7f7f6",
116
+ "description": "Text and controls on the figure viewer scrim (stone-50). Mode-invariant: the scrim is dark in both modes, so light and dark carry the same value (the color.border.figure-frame precedent). Held to 7:1 over both scrims and both page modes by tools/contrast-check.mjs."
87
117
  }
88
118
  },
89
119
  "interactive": {
@@ -98,9 +128,9 @@
98
128
  "description": "Hover state — forest-800 on light (slightly darker than canonical) / forest-400 on dark"
99
129
  },
100
130
  "accent": {
101
- "light": "#b54a27",
102
- "dark": "#b54a27",
103
- "description": "Accent — emancipation copper-red; moral-weight color (preserved from copper era as deliberate non-interactive emphasis)"
131
+ "light": "#1f618d",
132
+ "dark": "#3498DB",
133
+ "description": "Accent — sky-blue moral-weight color (iteration-2). Light: accent-500 (5.68:1 on stone-100, AA with headroom; 6.66:1 white-on-color for backplates). Dark: accent-300 (5.41:1 on stone-900, AA with headroom — closes the iteration-1 dark-mode AA-large-only contrast gap). FIRST instance of mode-aware role mapping in the system: light and dark point to different palette stops rather than the same hex. The scale-name `accent` is preserved across iteration-1 → iteration-2 (consumer-side text-accent-500 keeps working). See wiki/decisions/iteration-2-blue-accent.md for the dialectical reframe of the iteration-1 emancipation-copper framing (sky/horizon/Enlightenment-blueprint/Reformation-Protestant traditions vs. Western-traffic-coding STOP-red)."
104
134
  },
105
135
  "focus": {
106
136
  "light": "#434739",
@@ -108,6 +138,28 @@
108
138
  "description": "Focus indicators — mirrors interactive.primary"
109
139
  }
110
140
  },
141
+ "state": {
142
+ "success": {
143
+ "light": "#007a58",
144
+ "dark": "#009E73",
145
+ "description": "State: success. Okabe-Ito bluish-green, darkened in light mode for text: 4.56:1 on page and 4.99:1 on card (dark 5.40 / 5.11). 2026-11-02; replaces the Flat-UI functional colours as the semantic layer"
146
+ },
147
+ "warning": {
148
+ "light": "#906306",
149
+ "dark": "#E69F00",
150
+ "description": "State: warning. Okabe-Ito orange, darkened in light mode to an amber that holds text contrast: 4.51:1 on page and 4.93:1 on card (dark 8.20 / 7.76). 2026-11-02; replaces the Flat-UI functional colours as the semantic layer"
151
+ },
152
+ "error": {
153
+ "light": "#a4262c",
154
+ "dark": "#ef5350",
155
+ "description": "State: error. Red rather than Okabe-Ito vermillion: darkened vermillion collapses into the amber warning under deuteranopia (ΔE 2.0). 6.2:1 on page in light mode (dark 5.30 / 5.02). 2026-11-02; replaces the Flat-UI functional colours as the semantic layer"
156
+ },
157
+ "info": {
158
+ "light": "#1f618d",
159
+ "dark": "#3498DB",
160
+ "description": "State: info. The house slate accent (interactive.accent), so notes and info read slate-blue against the stone surfaces: 5.68:1 on page in light mode (dark 5.86). 2026-11-02; replaces the Flat-UI functional colours as the semantic layer"
161
+ }
162
+ },
111
163
  "presentation": {
112
164
  "accent": {
113
165
  "light": "#3498DB",
@@ -119,6 +171,32 @@
119
171
  "dark": "#2980B9",
120
172
  "description": "Presentation accent hover/emphasized variant — Flat-UI belize-hole"
121
173
  }
174
+ },
175
+ "vertical-accent": {
176
+ "$comment": "Per-vertical brand accents — each Level-2 property's identity color, distinct from the house interactive.accent (the L1 sky-blue hub color). Mode-aware (light/dark stops) like interactive.accent. Used for app icons, navbar-logo emphasis, and per-vertical theming. Contrast vs surface.page verified WCAG: light values are the on-light marks, dark values the on-dark marks. dataimago (L1 hub) intentionally has no vertical accent — it uses interactive.accent + ink.",
177
+ "dissertation": {
178
+ "light": "#B87333",
179
+ "dark": "#CE8E5C",
180
+ "description": "dissertation-ai — copper (manuscript / annotation / the human hand in the margin). Light: 3.23:1 on stone-100 (AA-large; large-mark use). Dark: #CE8E5C 6.72:1 on ink-900 (AA)."
181
+ },
182
+ "rpkg": {
183
+ "light": "#3B82F6",
184
+ "dark": "#60A5FA",
185
+ "description": "rpkg-ai — engineering blue. Light: 3.14:1 on stone-100 (AA-large; large-mark use). Dark: #60A5FA 7.26:1 on ink-900 (AA)."
186
+ },
187
+ "SGPc": {
188
+ "light": "#5A6310",
189
+ "dark": "#B2BF22",
190
+ "description": "SGPc-ai — growth yellow-green (decided 2026-06-26). The brand value is the bright #B2BF22, but it fails contrast on light surfaces (1.73:1), so LIGHT mode uses the darkened companion #5A6310 (5.55:1 on stone-100 — full AA) and DARK mode uses the bright #B2BF22 (9.12:1 on ink-900). See wiki/decisions/sgpc-accent.md."
191
+ }
192
+ },
193
+ "brand-mark": {
194
+ "$comment": "Brand-MARK colors (the dataimago monogram / wordmark logo treatment) — distinct from the interactive.accent role. The signature monogram red is a wide-gamut PILOT (see wiki/decisions/p3-oklch-color.md). It is mode-aware for AA-normal headroom: a single red cannot clear 4.5:1 on BOTH the light page (#ededeb) and ink-900 — light needs a deep red, dark needs a bright one. LIGHT uses the deepened #cc0000 (faithful P3, contrast-first); DARK keeps the vivid display-P3 primary red (#ff0000 fallback → color(display-p3 1 0 0)), where #ff0000 already passes AA-normal. Vivid override authored in tools/color-converter.mjs (dark-only for the red), emitted as a `#hex → color(display-p3 …)` cascade in the -p3 build.",
195
+ "red": {
196
+ "light": "#cc0000",
197
+ "dark": "#ff0000",
198
+ "description": "Signature monogram red — mode-aware for AA-normal. LIGHT: deepened #cc0000 (5.0:1 on stone-100 #ededeb / 5.5:1 on elevated — full AA-normal, safe at small sizes / as text). DARK: vivid #ff0000 fallback + display-P3 primary red (4.6:1 on ink-900 — AA-normal). Logo-mark color only — NOT the interactive accent (which is iteration-2 blue). Large navbar lift-wash marks keep the vivid display-P3 red (AA-large, large-mark use); this token is the AA-normal value for arbitrary/small mark reuse."
199
+ }
122
200
  }
123
201
  }
124
202
  }
@@ -2,23 +2,23 @@
2
2
  "font": {
3
3
  "family": {
4
4
  "sans": {
5
- "value": "Noto Sans, Fira Sans, system-ui, sans-serif",
6
- "description": "Primary sans-serif font - body text"
5
+ "value": "Noto Sans, Noto Sans Math, system-ui, sans-serif",
6
+ "description": "Primary sans-serif font - body text. Noto Sans Math is second so a glyph Noto Sans lacks (arrows such as U+2192, maths operators) is drawn by the shipped Noto, not a system font; a page downloads the maths face only when it needs such a glyph. Fira Sans, a leftover of the ai-native extension, was dropped (2026-11-01)."
7
7
  },
8
8
  "mono": {
9
- "value": "JetBrains Mono, SF Mono, Monaco, Inconsolata, monospace",
10
- "description": "Monospace font - code blocks and technical content"
9
+ "value": "Noto Sans Mono, SF Mono, Monaco, Inconsolata, monospace",
10
+ "description": "Noto Sans Mono — code blocks and technical content; matches the shipped font"
11
11
  },
12
12
  "display": {
13
13
  "value": "var(--font-family-display-editorial)",
14
- "description": "DEPRECATED alias of display-editorial; preserved through 0.2.x and removed in 0.3.0. New code should reference --font-family-display-editorial or --font-family-display-documentation directly. See wiki/decisions/display-family-split.md."
14
+ "description": "Alias of display-editorial, and the load-bearing indirection .di-prose rebinds to swap a whole surface to the documentation family — do NOT rewrite heading rules to reference display-editorial directly or .di-prose stops working. Reference display-editorial/display-documentation explicitly only where the surface must NOT control the family (brand chrome, navbars). Its 0.3.0 removal was deferred 2026-08-10 under wiki/decisions/compatibility-contract.md (additive-only); removal now requires its own cleanup ADR. See wiki/decisions/display-family-split.md."
15
15
  },
16
16
  "display-editorial": {
17
- "value": "Josefin Sans, system-ui, sans-serif",
18
- "description": "Editorial display family — Josefin Sans, the brand voice. Used on surfaces where the heading does rhetorical/branding work: hero/landing, marketing, story showcases, slide titles. Default for unmarked headings. Pair with weight 500 (h1) per wiki/decisions/h1-weight-medium.md."
17
+ "value": "Josefin Sans, Noto Sans, Noto Sans Math, system-ui, sans-serif",
18
+ "description": "Editorial display family — Josefin Sans, the brand voice. Used on surfaces where the heading does rhetorical/branding work: hero/landing, marketing, story showcases, slide titles. Default for unmarked headings. The Noto Sans fallback serves untagged text; tagged languages are handled by fonts/lang.css. Pair with weight 500 (h1) per wiki/decisions/h1-weight-medium.md."
19
19
  },
20
20
  "display-documentation": {
21
- "value": "Noto Sans, system-ui, sans-serif",
21
+ "value": "Noto Sans, Noto Sans Math, system-ui, sans-serif",
22
22
  "description": "Documentation display family — Noto Sans, the wayfinding voice. Used on surfaces where the heading does structural work: API docs, foundation Section h2s, KNOWLEDGE.md/CLAUDE.md headings, long-form research subheadings. Activated by wrapping content in .di-prose; pair with weight 600 (semibold). See wiki/decisions/display-family-split.md."
23
23
  },
24
24
  "brand": {
@@ -26,8 +26,8 @@
26
26
  "description": "Brand font - dataimago navbar and branding elements"
27
27
  },
28
28
  "math": {
29
- "value": "Noto Sans Math, Noto Sans, system-ui, sans-serif",
30
- "description": "Mathematical notation font — Noto Sans Math for broad Unicode math coverage; harmonises with the Noto Sans body stack"
29
+ "value": "Noto Sans Math, math",
30
+ "description": "Noto Sans Math, falling back to the browser's maths face; native MathML is the maths contract"
31
31
  }
32
32
  },
33
33
  "size": {