@dataimago/tokens 0.1.0-alpha.4 → 0.1.0-alpha.48
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.
- package/README.md +15 -4
- package/dist/index.cjs +318 -37
- package/dist/index.mjs +318 -37
- package/dist/tokens.css +289 -41
- package/dist/tokens.dtcg.json +884 -0
- package/dist/tokens.scss +289 -41
- package/dist/tokens.studio.json +889 -0
- package/dist/tokens.w3c.dtcg.json +1084 -0
- package/package.json +5 -2
- package/src/README.md +40 -156
- package/src/colors.json +8 -8
- package/src/dataviz.json +136 -0
- package/src/effects.json +85 -7
- package/src/theme-colors-p3.json +555 -0
- package/src/theme-colors.json +124 -21
- package/src/typography.json +10 -10
|
@@ -0,0 +1,1084 @@
|
|
|
1
|
+
{
|
|
2
|
+
"color": {
|
|
3
|
+
"surface": {
|
|
4
|
+
"page": {
|
|
5
|
+
"$value": "#ededeb",
|
|
6
|
+
"$type": "color",
|
|
7
|
+
"$extensions": {
|
|
8
|
+
"com.dataimago.theme": {
|
|
9
|
+
"dark": "#141410"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"$description": "Main page background — warm-grey (light) / ink-900 (dark)"
|
|
13
|
+
},
|
|
14
|
+
"page-scrolled": {
|
|
15
|
+
"$value": "#ededeb",
|
|
16
|
+
"$type": "color",
|
|
17
|
+
"$extensions": {
|
|
18
|
+
"com.dataimago.theme": {
|
|
19
|
+
"dark": "#141410"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"$description": "Page background when navbar shrinks — matches page"
|
|
23
|
+
},
|
|
24
|
+
"elevated": {
|
|
25
|
+
"$value": "#f7f7f6",
|
|
26
|
+
"$type": "color",
|
|
27
|
+
"$extensions": {
|
|
28
|
+
"com.dataimago.theme": {
|
|
29
|
+
"dark": "#1c1917"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"$description": "Cards, modals, dropdowns — one step above page (stone-50 on stone-100 / ink-800 on stone-900-aligned dark)"
|
|
33
|
+
},
|
|
34
|
+
"figure-plate": {
|
|
35
|
+
"$value": "#f7f7f6",
|
|
36
|
+
"$type": "color",
|
|
37
|
+
"$extensions": {
|
|
38
|
+
"com.dataimago.theme": {
|
|
39
|
+
"dark": "#dcdcda"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"$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)."
|
|
43
|
+
},
|
|
44
|
+
"sunken": {
|
|
45
|
+
"$value": "#f7f7f6",
|
|
46
|
+
"$type": "color",
|
|
47
|
+
"$extensions": {
|
|
48
|
+
"com.dataimago.theme": {
|
|
49
|
+
"dark": "#0c0a09"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"$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."
|
|
53
|
+
},
|
|
54
|
+
"navbar": {
|
|
55
|
+
"$value": "#ededeb",
|
|
56
|
+
"$type": "color",
|
|
57
|
+
"$extensions": {
|
|
58
|
+
"com.dataimago.theme": {
|
|
59
|
+
"dark": "#141410"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"$description": "Navbar background — matches page in both themes"
|
|
63
|
+
},
|
|
64
|
+
"navbar-scrolled": {
|
|
65
|
+
"$value": "#ededeb",
|
|
66
|
+
"$type": "color",
|
|
67
|
+
"$extensions": {
|
|
68
|
+
"com.dataimago.theme": {
|
|
69
|
+
"dark": "#141410"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"$description": "Navbar when scrolled/shrunk — matches page-scrolled"
|
|
73
|
+
},
|
|
74
|
+
"code": {
|
|
75
|
+
"$value": "#f7f7f6",
|
|
76
|
+
"$type": "color",
|
|
77
|
+
"$extensions": {
|
|
78
|
+
"com.dataimago.theme": {
|
|
79
|
+
"dark": "#1c1917"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"$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)"
|
|
83
|
+
},
|
|
84
|
+
"scrim": {
|
|
85
|
+
"$value": "rgba(20, 20, 16, 0.85)",
|
|
86
|
+
"$type": "color",
|
|
87
|
+
"$extensions": {
|
|
88
|
+
"com.dataimago.theme": {
|
|
89
|
+
"dark": "rgba(20, 20, 16, 0.85)"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"$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). Older browsers (Chrome < 122, Safari < 17.4, Firefox < 120) do not let ::backdrop inherit custom properties from :root, so a consumer painting the scrim on ::backdrop should write a fallback, e.g. var(--color-surface-scrim, rgba(20, 20, 16, 0.85)); the house figure viewer draws its scrim on a div (.di-figure-modal), so it is not affected."
|
|
93
|
+
},
|
|
94
|
+
"scrim-solid": {
|
|
95
|
+
"$value": "rgba(20, 20, 16, 0.92)",
|
|
96
|
+
"$type": "color",
|
|
97
|
+
"$extensions": {
|
|
98
|
+
"com.dataimago.theme": {
|
|
99
|
+
"dark": "rgba(20, 20, 16, 0.92)"
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"$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."
|
|
103
|
+
},
|
|
104
|
+
"print": {
|
|
105
|
+
"$value": "#f7f7f6",
|
|
106
|
+
"$type": "color",
|
|
107
|
+
"$extensions": {
|
|
108
|
+
"com.dataimago.theme": {
|
|
109
|
+
"dark": "#f7f7f6"
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
"$description": "Printed paper: the paper-cover thumbnail, the light slide, the face of a video-play disc. It depicts a physical object (a printed page, a slide), so it is theme-invariant: light and dark carry the same value, and the paper does not darken with the page (the color.border.figure-frame precedent). stone-50, the card colour; the SGPc apps' own #f6f4ee is not a house colour and was mapped onto this step (maintainer decision 2026-11-03). Ink on it is content.on-print, held to 7:1 by tools/contrast-check.mjs. Paper reads as paper by its edge, not its colour: a print surface always carries --shadow-print or a hairline in border.print (the edge rule, maintainer decision 2026-11-03)."
|
|
113
|
+
},
|
|
114
|
+
"play-disc": {
|
|
115
|
+
"$value": "rgba(247, 247, 246, 0.92)",
|
|
116
|
+
"$type": "color",
|
|
117
|
+
"$extensions": {
|
|
118
|
+
"com.dataimago.theme": {
|
|
119
|
+
"dark": "rgba(247, 247, 246, 0.92)"
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"$description": "The video-play disc: surface.print at 0.92 alpha, over a poster frame or poster placeholder. It depicts a physical object, so it is theme-invariant: light and dark carry the same value. Its glyph is content.on-print (no separate token), held to 4.5:1 on the disc composited over each mode's page by tools/contrast-check.mjs, so the disc stays legible in dark mode."
|
|
123
|
+
},
|
|
124
|
+
"media": {
|
|
125
|
+
"$value": "#000000",
|
|
126
|
+
"$type": "color",
|
|
127
|
+
"$extensions": {
|
|
128
|
+
"com.dataimago.theme": {
|
|
129
|
+
"dark": "#000000"
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
"$description": "The media letterbox: the ground behind a <video> and other media (an embedded player, a frame that does not fill its box). Pure black, not the house near-black (stone-900 #14140f, ink-900 #0c0a09): video frames carry true black, so a near-black ground shows the letterbox bars beside the frame's own black, and pure black hides them. It depicts the media frame, not the page, so it is theme-invariant: light and dark carry the same value (the color.surface.print precedent). Nothing is drawn on it, so it has no contrast floor; tools/contrast-check.mjs holds it to theme invariance (maintainer decision 2026-11-03)."
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"border": {
|
|
136
|
+
"subtle": {
|
|
137
|
+
"$value": "rgba(12, 10, 9, 0.45)",
|
|
138
|
+
"$type": "color",
|
|
139
|
+
"$extensions": {
|
|
140
|
+
"com.dataimago.theme": {
|
|
141
|
+
"dark": "rgba(253, 249, 242, 0.45)"
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"$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."
|
|
145
|
+
},
|
|
146
|
+
"moderate": {
|
|
147
|
+
"$value": "rgba(12, 10, 9, 0.60)",
|
|
148
|
+
"$type": "color",
|
|
149
|
+
"$extensions": {
|
|
150
|
+
"com.dataimago.theme": {
|
|
151
|
+
"dark": "rgba(253, 249, 242, 0.60)"
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"$description": "Moderate borders — defined boundaries. See border.subtle on why the alpha is load-bearing and why no number is quoted here."
|
|
155
|
+
},
|
|
156
|
+
"strong": {
|
|
157
|
+
"$value": "rgba(12, 10, 9, 0.75)",
|
|
158
|
+
"$type": "color",
|
|
159
|
+
"$extensions": {
|
|
160
|
+
"com.dataimago.theme": {
|
|
161
|
+
"dark": "rgba(253, 249, 242, 0.75)"
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
"$description": "Strong borders — prominent separation. See border.subtle on why the alpha is load-bearing and why no number is quoted here."
|
|
165
|
+
},
|
|
166
|
+
"card": {
|
|
167
|
+
"$value": "rgba(12, 10, 9, 0.60)",
|
|
168
|
+
"$type": "color",
|
|
169
|
+
"$extensions": {
|
|
170
|
+
"com.dataimago.theme": {
|
|
171
|
+
"dark": "rgba(253, 249, 242, 0.60)"
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
"$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."
|
|
175
|
+
},
|
|
176
|
+
"figure-frame": {
|
|
177
|
+
"$value": "#6a6a6a",
|
|
178
|
+
"$type": "color",
|
|
179
|
+
"$extensions": {
|
|
180
|
+
"com.dataimago.theme": {
|
|
181
|
+
"dark": "#6a6a6a"
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
"$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)."
|
|
185
|
+
},
|
|
186
|
+
"code": {
|
|
187
|
+
"$value": "#d6d3d1",
|
|
188
|
+
"$type": "color",
|
|
189
|
+
"$extensions": {
|
|
190
|
+
"com.dataimago.theme": {
|
|
191
|
+
"dark": "#292524"
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
"$description": "Code block border"
|
|
195
|
+
},
|
|
196
|
+
"on-scrim-focus": {
|
|
197
|
+
"$value": "#3498DB",
|
|
198
|
+
"$type": "color",
|
|
199
|
+
"$extensions": {
|
|
200
|
+
"com.dataimago.theme": {
|
|
201
|
+
"dark": "#3498DB"
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
"$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."
|
|
205
|
+
},
|
|
206
|
+
"print": {
|
|
207
|
+
"$value": "rgba(12, 10, 9, 0.45)",
|
|
208
|
+
"$type": "color",
|
|
209
|
+
"$extensions": {
|
|
210
|
+
"com.dataimago.theme": {
|
|
211
|
+
"dark": "rgba(12, 10, 9, 0.45)"
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
"$description": "The hairline edge of printed paper (surface.print): the paper-cover thumbnail, the light slide. THE EDGE RULE: paper reads as paper by its edge, not by its colour. surface.print is the card colour, so a print surface always carries either --shadow-print or a hairline in this token (maintainer decision 2026-11-03). It is drawn on the paper, which stays light in both modes, so it is theme-invariant: light and dark carry the same value (the color.border.figure-frame precedent). It starts from the light value of border.subtle, and as there the alpha is the role and no ratio is quoted on purpose: composited over surface.print it is held to the WCAG 1.4.11 non-text threshold (3:1) by tools/contrast-check.mjs. Read the value, not this sentence."
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
"content": {
|
|
218
|
+
"primary": {
|
|
219
|
+
"$value": "#14140f",
|
|
220
|
+
"$type": "color",
|
|
221
|
+
"$extensions": {
|
|
222
|
+
"com.dataimago.theme": {
|
|
223
|
+
"dark": "#fdf9f2"
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
"$description": "Primary text — stone-900 on stone-100 (light, matches presentation-theme.scss exactly) / paper-100 on dark surface"
|
|
227
|
+
},
|
|
228
|
+
"secondary": {
|
|
229
|
+
"$value": "#6a6a6a",
|
|
230
|
+
"$type": "color",
|
|
231
|
+
"$extensions": {
|
|
232
|
+
"com.dataimago.theme": {
|
|
233
|
+
"dark": "#a8a29e"
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
"$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"
|
|
237
|
+
},
|
|
238
|
+
"muted": {
|
|
239
|
+
"$value": "#706964",
|
|
240
|
+
"$type": "color",
|
|
241
|
+
"$extensions": {
|
|
242
|
+
"com.dataimago.theme": {
|
|
243
|
+
"dark": "#89827d"
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
"$description": "Muted text — captions, meta info. WCAG-AA on all surfaces in both modes (darkened/lightened from #78716c which failed AA on page)"
|
|
247
|
+
},
|
|
248
|
+
"inverse": {
|
|
249
|
+
"$value": "#fdf9f2",
|
|
250
|
+
"$type": "color",
|
|
251
|
+
"$extensions": {
|
|
252
|
+
"com.dataimago.theme": {
|
|
253
|
+
"dark": "#0c0a09"
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
"$description": "Inverse text — for contrasting backgrounds"
|
|
257
|
+
},
|
|
258
|
+
"on-scrim": {
|
|
259
|
+
"$value": "#f7f7f6",
|
|
260
|
+
"$type": "color",
|
|
261
|
+
"$extensions": {
|
|
262
|
+
"com.dataimago.theme": {
|
|
263
|
+
"dark": "#f7f7f6"
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
"$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."
|
|
267
|
+
},
|
|
268
|
+
"on-print": {
|
|
269
|
+
"$value": "#14140f",
|
|
270
|
+
"$type": "color",
|
|
271
|
+
"$extensions": {
|
|
272
|
+
"com.dataimago.theme": {
|
|
273
|
+
"dark": "#14140f"
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
"$description": "Ink on surface.print, and the glyph on surface.play-disc (the play triangle takes this token; it has no separate one). stone-900. It depicts printed ink, so it is theme-invariant: light and dark carry the same value (the color.border.figure-frame precedent). Held to 7:1 on surface.print, and 4.5:1 on the play disc composited over each mode's page, by tools/contrast-check.mjs."
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
"interactive": {
|
|
280
|
+
"primary": {
|
|
281
|
+
"$value": "#434739",
|
|
282
|
+
"$type": "color",
|
|
283
|
+
"$extensions": {
|
|
284
|
+
"com.dataimago.theme": {
|
|
285
|
+
"dark": "#98a384"
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
"$description": "Primary interactive — forest-700 on light (7.75:1 on stone-100, white text 9.0:1 — passes WCAG AAA) / forest-300 on dark"
|
|
289
|
+
},
|
|
290
|
+
"hover": {
|
|
291
|
+
"$value": "#363a2e",
|
|
292
|
+
"$type": "color",
|
|
293
|
+
"$extensions": {
|
|
294
|
+
"com.dataimago.theme": {
|
|
295
|
+
"dark": "#7e8a6b"
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
"$description": "Hover state — forest-800 on light (slightly darker than canonical) / forest-400 on dark"
|
|
299
|
+
},
|
|
300
|
+
"accent": {
|
|
301
|
+
"$value": "#1f618d",
|
|
302
|
+
"$type": "color",
|
|
303
|
+
"$extensions": {
|
|
304
|
+
"com.dataimago.theme": {
|
|
305
|
+
"dark": "#3498DB"
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
"$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)."
|
|
309
|
+
},
|
|
310
|
+
"focus": {
|
|
311
|
+
"$value": "#434739",
|
|
312
|
+
"$type": "color",
|
|
313
|
+
"$extensions": {
|
|
314
|
+
"com.dataimago.theme": {
|
|
315
|
+
"dark": "#98a384"
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
"$description": "Focus indicators — mirrors interactive.primary"
|
|
319
|
+
}
|
|
320
|
+
},
|
|
321
|
+
"state": {
|
|
322
|
+
"success": {
|
|
323
|
+
"$value": "#007a58",
|
|
324
|
+
"$type": "color",
|
|
325
|
+
"$extensions": {
|
|
326
|
+
"com.dataimago.theme": {
|
|
327
|
+
"dark": "#009E73"
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
"$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"
|
|
331
|
+
},
|
|
332
|
+
"warning": {
|
|
333
|
+
"$value": "#906306",
|
|
334
|
+
"$type": "color",
|
|
335
|
+
"$extensions": {
|
|
336
|
+
"com.dataimago.theme": {
|
|
337
|
+
"dark": "#E69F00"
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
"$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"
|
|
341
|
+
},
|
|
342
|
+
"error": {
|
|
343
|
+
"$value": "#a4262c",
|
|
344
|
+
"$type": "color",
|
|
345
|
+
"$extensions": {
|
|
346
|
+
"com.dataimago.theme": {
|
|
347
|
+
"dark": "#ef5350"
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
"$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"
|
|
351
|
+
},
|
|
352
|
+
"info": {
|
|
353
|
+
"$value": "#1f618d",
|
|
354
|
+
"$type": "color",
|
|
355
|
+
"$extensions": {
|
|
356
|
+
"com.dataimago.theme": {
|
|
357
|
+
"dark": "#3498DB"
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
"$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"
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
"presentation": {
|
|
364
|
+
"accent": {
|
|
365
|
+
"$value": "#3498DB",
|
|
366
|
+
"$type": "color",
|
|
367
|
+
"$extensions": {
|
|
368
|
+
"com.dataimago.theme": {
|
|
369
|
+
"dark": "#3498DB"
|
|
370
|
+
}
|
|
371
|
+
},
|
|
372
|
+
"$description": "Presentation accent — Flat-UI peter-river; reserved for reveal.js 2030s-feel highlights. Not for body prose or interactive primary use. Pairs well with copper on dark slides."
|
|
373
|
+
},
|
|
374
|
+
"accent-hover": {
|
|
375
|
+
"$value": "#2980B9",
|
|
376
|
+
"$type": "color",
|
|
377
|
+
"$extensions": {
|
|
378
|
+
"com.dataimago.theme": {
|
|
379
|
+
"dark": "#2980B9"
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
"$description": "Presentation accent hover/emphasized variant — Flat-UI belize-hole"
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
"vertical-accent": {
|
|
386
|
+
"$comment": {
|
|
387
|
+
"$value": "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."
|
|
388
|
+
},
|
|
389
|
+
"dissertation": {
|
|
390
|
+
"$value": "#B87333",
|
|
391
|
+
"$type": "color",
|
|
392
|
+
"$extensions": {
|
|
393
|
+
"com.dataimago.theme": {
|
|
394
|
+
"dark": "#CE8E5C"
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
"$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)."
|
|
398
|
+
},
|
|
399
|
+
"rpkg": {
|
|
400
|
+
"$value": "#3B82F6",
|
|
401
|
+
"$type": "color",
|
|
402
|
+
"$extensions": {
|
|
403
|
+
"com.dataimago.theme": {
|
|
404
|
+
"dark": "#60A5FA"
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
"$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)."
|
|
408
|
+
},
|
|
409
|
+
"SGPc": {
|
|
410
|
+
"$value": "#5A6310",
|
|
411
|
+
"$type": "color",
|
|
412
|
+
"$extensions": {
|
|
413
|
+
"com.dataimago.theme": {
|
|
414
|
+
"dark": "#B2BF22"
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
"$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."
|
|
418
|
+
}
|
|
419
|
+
},
|
|
420
|
+
"brand-mark": {
|
|
421
|
+
"$comment": {
|
|
422
|
+
"$value": "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."
|
|
423
|
+
},
|
|
424
|
+
"red": {
|
|
425
|
+
"$value": "#cc0000",
|
|
426
|
+
"$type": "color",
|
|
427
|
+
"$extensions": {
|
|
428
|
+
"com.dataimago.theme": {
|
|
429
|
+
"dark": "#ff0000"
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
"$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."
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
"dataviz": {
|
|
436
|
+
"okabe-ito": {
|
|
437
|
+
"orange": {
|
|
438
|
+
"$value": "#E69F00",
|
|
439
|
+
"$type": "color",
|
|
440
|
+
"$description": "Okabe-Ito orange (Okabe & Ito 2008, colour-blind safe). House data-viz primitive; maintainer decision 2026-10-29."
|
|
441
|
+
},
|
|
442
|
+
"sky-blue": {
|
|
443
|
+
"$value": "#56B4E9",
|
|
444
|
+
"$type": "color",
|
|
445
|
+
"$description": "Okabe-Ito sky blue (Okabe & Ito 2008, colour-blind safe). House data-viz primitive; maintainer decision 2026-10-29."
|
|
446
|
+
},
|
|
447
|
+
"bluish-green": {
|
|
448
|
+
"$value": "#009E73",
|
|
449
|
+
"$type": "color",
|
|
450
|
+
"$description": "Okabe-Ito bluish green (Okabe & Ito 2008, colour-blind safe). House data-viz primitive; maintainer decision 2026-10-29."
|
|
451
|
+
},
|
|
452
|
+
"yellow": {
|
|
453
|
+
"$value": "#F0E442",
|
|
454
|
+
"$type": "color",
|
|
455
|
+
"$description": "Okabe-Ito yellow — 1.13:1 on the light page: never use it without a mark outline or a label (Okabe & Ito 2008, colour-blind safe). House data-viz primitive; maintainer decision 2026-10-29."
|
|
456
|
+
},
|
|
457
|
+
"blue": {
|
|
458
|
+
"$value": "#0072B2",
|
|
459
|
+
"$type": "color",
|
|
460
|
+
"$description": "Okabe-Ito blue (Okabe & Ito 2008, colour-blind safe). House data-viz primitive; maintainer decision 2026-10-29."
|
|
461
|
+
},
|
|
462
|
+
"vermillion": {
|
|
463
|
+
"$value": "#D55E00",
|
|
464
|
+
"$type": "color",
|
|
465
|
+
"$description": "Okabe-Ito vermillion (Okabe & Ito 2008, colour-blind safe). House data-viz primitive; maintainer decision 2026-10-29."
|
|
466
|
+
},
|
|
467
|
+
"reddish-purple": {
|
|
468
|
+
"$value": "#CC79A7",
|
|
469
|
+
"$type": "color",
|
|
470
|
+
"$description": "Okabe-Ito reddish purple (Okabe & Ito 2008, colour-blind safe). House data-viz primitive; maintainer decision 2026-10-29."
|
|
471
|
+
},
|
|
472
|
+
"black": {
|
|
473
|
+
"$value": "#000000",
|
|
474
|
+
"$type": "color",
|
|
475
|
+
"$extensions": {
|
|
476
|
+
"com.dataimago.theme": {
|
|
477
|
+
"dark": "#FDF9F2"
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
"$description": "Okabe-Ito black (Okabe & Ito 2008). In dark mode it becomes content.primary.dark: #000000 is 1.14:1 on the dark page. Dark value approved by the maintainer 2026-10-29 (dataviz-check --propose-dark)."
|
|
481
|
+
}
|
|
482
|
+
},
|
|
483
|
+
"categorical": {
|
|
484
|
+
"1": {
|
|
485
|
+
"$value": "#E69F00",
|
|
486
|
+
"$type": "color",
|
|
487
|
+
"$description": "= okabe-ito.orange (slot 1, Wilke order). Categorical colour is never the only channel: pair it with marker shape, line style or a label."
|
|
488
|
+
},
|
|
489
|
+
"2": {
|
|
490
|
+
"$value": "#56B4E9",
|
|
491
|
+
"$type": "color",
|
|
492
|
+
"$description": "= okabe-ito.sky-blue (slot 2, Wilke order). Categorical colour is never the only channel: pair it with marker shape, line style or a label."
|
|
493
|
+
},
|
|
494
|
+
"3": {
|
|
495
|
+
"$value": "#009E73",
|
|
496
|
+
"$type": "color",
|
|
497
|
+
"$description": "= okabe-ito.bluish-green (slot 3, Wilke order). Categorical colour is never the only channel: pair it with marker shape, line style or a label."
|
|
498
|
+
},
|
|
499
|
+
"4": {
|
|
500
|
+
"$value": "#F0E442",
|
|
501
|
+
"$type": "color",
|
|
502
|
+
"$description": "= okabe-ito.yellow (slot 4, Wilke order). Categorical colour is never the only channel: pair it with marker shape, line style or a label."
|
|
503
|
+
},
|
|
504
|
+
"5": {
|
|
505
|
+
"$value": "#0072B2",
|
|
506
|
+
"$type": "color",
|
|
507
|
+
"$description": "= okabe-ito.blue (slot 5, Wilke order). Categorical colour is never the only channel: pair it with marker shape, line style or a label."
|
|
508
|
+
},
|
|
509
|
+
"6": {
|
|
510
|
+
"$value": "#D55E00",
|
|
511
|
+
"$type": "color",
|
|
512
|
+
"$description": "= okabe-ito.vermillion (slot 6, Wilke order). Categorical colour is never the only channel: pair it with marker shape, line style or a label."
|
|
513
|
+
},
|
|
514
|
+
"7": {
|
|
515
|
+
"$value": "#CC79A7",
|
|
516
|
+
"$type": "color",
|
|
517
|
+
"$description": "= okabe-ito.reddish-purple (slot 7, Wilke order). Categorical colour is never the only channel: pair it with marker shape, line style or a label."
|
|
518
|
+
},
|
|
519
|
+
"8": {
|
|
520
|
+
"$value": "#000000",
|
|
521
|
+
"$type": "color",
|
|
522
|
+
"$extensions": {
|
|
523
|
+
"com.dataimago.theme": {
|
|
524
|
+
"dark": "#FDF9F2"
|
|
525
|
+
}
|
|
526
|
+
},
|
|
527
|
+
"$description": "= okabe-ito.black (slot 8, Wilke order). Categorical colour is never the only channel: pair it with marker shape, line style or a label."
|
|
528
|
+
}
|
|
529
|
+
},
|
|
530
|
+
"uncertainty": {
|
|
531
|
+
"outer": {
|
|
532
|
+
"$value": "#D6D6D6",
|
|
533
|
+
"$type": "color",
|
|
534
|
+
"$extensions": {
|
|
535
|
+
"com.dataimago.theme": {
|
|
536
|
+
"dark": "#333333"
|
|
537
|
+
}
|
|
538
|
+
},
|
|
539
|
+
"$description": "Outermost nested uncertainty band (gray 0.84 in the LIwLD PSTricks figures). The ramp is mirrored in dark mode so the innermost band stays the strongest. Dark value approved by the maintainer 2026-10-29 (dataviz-check --propose-dark)."
|
|
540
|
+
},
|
|
541
|
+
"union": {
|
|
542
|
+
"$value": "#9E9E9E",
|
|
543
|
+
"$type": "color",
|
|
544
|
+
"$extensions": {
|
|
545
|
+
"com.dataimago.theme": {
|
|
546
|
+
"dark": "#6B6B6B"
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
"$description": "Union band (gray 0.62); mirrored in dark mode. Dark value approved by the maintainer 2026-10-29 (dataviz-check --propose-dark)."
|
|
550
|
+
},
|
|
551
|
+
"inner": {
|
|
552
|
+
"$value": "#333333",
|
|
553
|
+
"$type": "color",
|
|
554
|
+
"$extensions": {
|
|
555
|
+
"com.dataimago.theme": {
|
|
556
|
+
"dark": "#D6D6D6"
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
"$description": "Innermost band (gray 0.20); mirrored in dark mode, where #333333 would be 1.46:1. Dark value approved by the maintainer 2026-10-29 (dataviz-check --propose-dark)."
|
|
560
|
+
}
|
|
561
|
+
},
|
|
562
|
+
"sgpc-bucket": {
|
|
563
|
+
"very-low": {
|
|
564
|
+
"$value": "#D55E00",
|
|
565
|
+
"$type": "color",
|
|
566
|
+
"$description": "= okabe-ito.vermillion. SGPc growth bucket 1 of 5 (very low) on the ordered scale very low → very high. Colour is never the only channel: pair it with a marker and the bucket letter code. Author decision 2026-11-01, matching the LIwLD paper's figures."
|
|
567
|
+
},
|
|
568
|
+
"low": {
|
|
569
|
+
"$value": "#E69F00",
|
|
570
|
+
"$type": "color",
|
|
571
|
+
"$description": "= okabe-ito.orange. SGPc growth bucket 2 of 5 (low) on the ordered scale very low → very high. Colour is never the only channel: pair it with a marker and the bucket letter code. Author decision 2026-11-01, matching the LIwLD paper's figures."
|
|
572
|
+
},
|
|
573
|
+
"typical": {
|
|
574
|
+
"$value": "#56B4E9",
|
|
575
|
+
"$type": "color",
|
|
576
|
+
"$description": "= okabe-ito.sky-blue. SGPc growth bucket 3 of 5 (typical) on the ordered scale very low → very high. Colour is never the only channel: pair it with a marker and the bucket letter code. Author decision 2026-11-01, matching the LIwLD paper's figures."
|
|
577
|
+
},
|
|
578
|
+
"high": {
|
|
579
|
+
"$value": "#009E73",
|
|
580
|
+
"$type": "color",
|
|
581
|
+
"$description": "= okabe-ito.bluish-green. SGPc growth bucket 4 of 5 (high) on the ordered scale very low → very high. Colour is never the only channel: pair it with a marker and the bucket letter code. Author decision 2026-11-01, matching the LIwLD paper's figures."
|
|
582
|
+
},
|
|
583
|
+
"very-high": {
|
|
584
|
+
"$value": "#0072B2",
|
|
585
|
+
"$type": "color",
|
|
586
|
+
"$description": "= okabe-ito.blue. SGPc growth bucket 5 of 5 (very high) on the ordered scale very low → very high. Colour is never the only channel: pair it with a marker and the bucket letter code. Author decision 2026-11-01, matching the LIwLD paper's figures."
|
|
587
|
+
}
|
|
588
|
+
},
|
|
589
|
+
"sgpc-role": {
|
|
590
|
+
"marginal": {
|
|
591
|
+
"$value": "#0072B2",
|
|
592
|
+
"$type": "color",
|
|
593
|
+
"$description": "= okabe-ito.blue. SGPc methodological role: what the separate margins (the score distributions) supply. 5.19:1 on white. A figure uses role colours or bucket colours, never both: this hue is also sgpc-bucket.very-high. Light-ground tints (marginal-pale 30 %, marginal-wash 12 %, mixes with white) ship in the TeX, JSON and R data-viz outputs only, and a tint is never the only channel: it sits with this stroke or a label. Maintainer decision 2026-11-09."
|
|
594
|
+
},
|
|
595
|
+
"linkage": {
|
|
596
|
+
"$value": "#D55E00",
|
|
597
|
+
"$type": "color",
|
|
598
|
+
"$description": "= okabe-ito.vermillion. SGPc methodological role: what linkage (the copula) supplies. 3.87:1 on white. A figure uses role colours or bucket colours, never both: this hue is also sgpc-bucket.very-low. Light-ground tints (linkage-pale 30 %, linkage-wash 12 %, mixes with white) ship in the TeX, JSON and R data-viz outputs only, and a tint is never the only channel: it sits with this stroke or a label. Maintainer decision 2026-11-09."
|
|
599
|
+
},
|
|
600
|
+
"kernel": {
|
|
601
|
+
"$value": "#CC79A7",
|
|
602
|
+
"$type": "color",
|
|
603
|
+
"$description": "= okabe-ito.reddish-purple. SGPc methodological role: the kernel-substitution term b_K. 3.06:1 on white, 2.86:1 on the light figure plate and 2.61:1 on the light page, so the kernel term always carries a second cue (a dash pattern or a label). Its light-ground tint (kernel-pale, 30 % mixed with white) ships in the TeX, JSON and R data-viz outputs only and is never the only channel. Maintainer decision 2026-11-09."
|
|
604
|
+
}
|
|
605
|
+
},
|
|
606
|
+
"map": {
|
|
607
|
+
"ocean": {
|
|
608
|
+
"$value": "#808fa7",
|
|
609
|
+
"$type": "color",
|
|
610
|
+
"$extensions": {
|
|
611
|
+
"com.dataimago.theme": {
|
|
612
|
+
"dark": "#042438"
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
"$description": "Map-surface ground: the sea on the SGPc globe, behind land, absent countries and bucket-filled shapes. A muted slate blue on light surfaces and a deep blue on dark (maintainer 2026-10-22); not a palette step. The light value moved from #c9e1ec on 2026-11-01, when the Okabe-Ito sky-blue bucket blended into it: #808fa7 sits mid-way in lightness between the two blue buckets and is grey enough to read as sea. Gated by tools/dataviz-check.mjs against the five sgpc-bucket colours and the land neutrals (ink-200 land and ink-100 absent in light; ink-600 land and ink-700 absent in dark) at ΔE2000 ≥ 11.1 under normal vision and deutan, protan and tritan simulation, and the country outline (ink-600 light, ink-300 dark) at ≥ 3:1. Draw country borders in this colour, as gaps between shapes. The dark value moved from the apps' #14232c to #042438 on 2026-11-03 (maintainer): a slightly deeper sea keeps the quiet 'no data' countries (ink-700) distinct from it for protan readers (#14232c was ΔE 6.61 from them). Raised from the SGPc apps (2026-11-03)."
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
},
|
|
620
|
+
"shadow": {
|
|
621
|
+
"sm": {
|
|
622
|
+
"$value": "0 1px 2px 0 rgb(0 0 0 / 0.05)"
|
|
623
|
+
},
|
|
624
|
+
"md": {
|
|
625
|
+
"$value": "0 4px 6px -1px rgb(0 0 0 / 0.1)"
|
|
626
|
+
},
|
|
627
|
+
"lg": {
|
|
628
|
+
"$value": "0 10px 15px -3px rgb(0 0 0 / 0.1)"
|
|
629
|
+
},
|
|
630
|
+
"xl": {
|
|
631
|
+
"$value": "0 20px 25px -5px rgb(0 0 0 / 0.1)"
|
|
632
|
+
}
|
|
633
|
+
},
|
|
634
|
+
"border": {
|
|
635
|
+
"subtle": {
|
|
636
|
+
"$value": "rgba(20, 20, 16, 0.47)",
|
|
637
|
+
"$type": "color",
|
|
638
|
+
"$extensions": {
|
|
639
|
+
"com.dataimago.theme": {
|
|
640
|
+
"dark": "rgba(237, 237, 235, 0.47)"
|
|
641
|
+
}
|
|
642
|
+
},
|
|
643
|
+
"$description": "Subtle borders - element separation. THE ALPHA IS THE ROLE. Distinct from color.border.subtle: this family has its own base (20,20,16 / 237,237,235), so it needs a DIFFERENT alpha to render the same. 0.47 here matches 0.45 there at 3.07:1 on the worst surface; copying 0.45 would land at 2.90:1 and fail WCAG 1.4.11. Gated by tools/contrast-check.mjs."
|
|
644
|
+
},
|
|
645
|
+
"moderate": {
|
|
646
|
+
"$value": "rgba(20, 20, 16, 0.63)",
|
|
647
|
+
"$type": "color",
|
|
648
|
+
"$extensions": {
|
|
649
|
+
"com.dataimago.theme": {
|
|
650
|
+
"dark": "rgba(237, 237, 235, 0.63)"
|
|
651
|
+
}
|
|
652
|
+
},
|
|
653
|
+
"$description": "Moderate borders - defined boundaries. 0.63 here matches color.border.moderate 0.60 in rendered contrast; see border.subtle on why the numbers differ between the two families."
|
|
654
|
+
},
|
|
655
|
+
"focus": {
|
|
656
|
+
"$value": "#3498DB",
|
|
657
|
+
"$type": "color",
|
|
658
|
+
"$extensions": {
|
|
659
|
+
"com.dataimago.theme": {
|
|
660
|
+
"dark": "#4FC3F7"
|
|
661
|
+
}
|
|
662
|
+
},
|
|
663
|
+
"$description": "Focus indicators - accessibility"
|
|
664
|
+
}
|
|
665
|
+
},
|
|
666
|
+
"transition": {
|
|
667
|
+
"quick": {
|
|
668
|
+
"$value": "0.15s ease",
|
|
669
|
+
"$type": "duration",
|
|
670
|
+
"$description": "Snap-fast micro-interactions — hover lifts, focus rings, immediate-feedback affordances"
|
|
671
|
+
},
|
|
672
|
+
"standard": {
|
|
673
|
+
"$value": "0.25s ease-in-out",
|
|
674
|
+
"$type": "duration",
|
|
675
|
+
"$description": "Default for most state changes — toggles, button states, card hovers"
|
|
676
|
+
},
|
|
677
|
+
"smooth": {
|
|
678
|
+
"$value": "0.35s ease",
|
|
679
|
+
"$type": "duration",
|
|
680
|
+
"$description": "Theme transitions, navbar collapse/expand, layout shifts that should feel deliberate"
|
|
681
|
+
},
|
|
682
|
+
"logo": {
|
|
683
|
+
"$value": "0.3s",
|
|
684
|
+
"$type": "duration",
|
|
685
|
+
"$description": "Reserved for the dataimago wordmark / brand-mark transitions; do not borrow for general UI"
|
|
686
|
+
}
|
|
687
|
+
},
|
|
688
|
+
"motion": {
|
|
689
|
+
"enter": {
|
|
690
|
+
"$value": "200ms",
|
|
691
|
+
"$type": "duration",
|
|
692
|
+
"$description": "Something arrives: a page fade, tooltip in, chip in, view switch, drawer open, chart marks. Pair with motion.ease-out. Raised from the SGPc apps (2026-11-03), which named it --motion-enter. Within the 300ms motion-dignity ceiling; gated by tools/motion-lint.mjs."
|
|
693
|
+
},
|
|
694
|
+
"exit": {
|
|
695
|
+
"$value": "120ms",
|
|
696
|
+
"$type": "duration",
|
|
697
|
+
"$description": "Something leaves: tooltip out, chip out, drawer close. Shorter than motion.enter, because leaving should not hold the reader. Pair with motion.ease-in; a component that unmounts in script holds the unmount for this long. Raised from the SGPc apps (2026-11-03), which named it --motion-exit."
|
|
698
|
+
},
|
|
699
|
+
"ease-out": {
|
|
700
|
+
"$value": [
|
|
701
|
+
0.25,
|
|
702
|
+
0.46,
|
|
703
|
+
0.45,
|
|
704
|
+
0.94
|
|
705
|
+
],
|
|
706
|
+
"$type": "cubicBezier",
|
|
707
|
+
"$description": "easeOutQuad, the curve foundations/design/motion-dignity.md names, for entrances: fast at the start, settling gently. Raised from the SGPc apps (2026-11-03), which named it --motion-ease-out."
|
|
708
|
+
},
|
|
709
|
+
"ease-in": {
|
|
710
|
+
"$value": [
|
|
711
|
+
0.55,
|
|
712
|
+
0.085,
|
|
713
|
+
0.68,
|
|
714
|
+
0.53
|
|
715
|
+
],
|
|
716
|
+
"$type": "cubicBezier",
|
|
717
|
+
"$description": "easeInQuad, for exits: starts gently and leaves quickly. The counterpart of motion.ease-out. Raised from the SGPc apps (2026-11-03), which named it --motion-ease-in."
|
|
718
|
+
},
|
|
719
|
+
"duration": {
|
|
720
|
+
"120": {
|
|
721
|
+
"$value": "120ms",
|
|
722
|
+
"$type": "duration",
|
|
723
|
+
"$description": "Duration scale step, 120ms. Equal to motion.exit."
|
|
724
|
+
},
|
|
725
|
+
"160": {
|
|
726
|
+
"$value": "160ms",
|
|
727
|
+
"$type": "duration",
|
|
728
|
+
"$description": "Duration scale step, 160ms: a hover on a small control, a sheet leaving."
|
|
729
|
+
},
|
|
730
|
+
"200": {
|
|
731
|
+
"$value": "200ms",
|
|
732
|
+
"$type": "duration",
|
|
733
|
+
"$description": "Duration scale step, 200ms. Equal to motion.enter."
|
|
734
|
+
},
|
|
735
|
+
"250": {
|
|
736
|
+
"$value": "250ms",
|
|
737
|
+
"$type": "duration",
|
|
738
|
+
"$description": "Duration scale step, 250ms: a sheet arriving, a grid-column change."
|
|
739
|
+
},
|
|
740
|
+
"300": {
|
|
741
|
+
"$value": "300ms",
|
|
742
|
+
"$type": "duration",
|
|
743
|
+
"$description": "Duration scale step, 300ms: the motion-dignity ceiling. Nothing in the scale is longer, and the motion gate holds every motion.* value to it. A slow ambient entrance is not a token: a wait before an animation is a delay, not motion, and the animation itself stays at or under this step."
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
},
|
|
747
|
+
"font": {
|
|
748
|
+
"family": {
|
|
749
|
+
"sans": {
|
|
750
|
+
"$value": "Noto Sans, Noto Sans Math, system-ui, sans-serif",
|
|
751
|
+
"$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)."
|
|
752
|
+
},
|
|
753
|
+
"mono": {
|
|
754
|
+
"$value": "Noto Sans Mono, SF Mono, Monaco, Inconsolata, monospace",
|
|
755
|
+
"$description": "Noto Sans Mono — code blocks and technical content; matches the shipped font"
|
|
756
|
+
},
|
|
757
|
+
"display": {
|
|
758
|
+
"$value": "var(--font-family-display-editorial)",
|
|
759
|
+
"$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."
|
|
760
|
+
},
|
|
761
|
+
"display-editorial": {
|
|
762
|
+
"$value": "Josefin Sans, Noto Sans, Noto Sans Math, system-ui, sans-serif",
|
|
763
|
+
"$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."
|
|
764
|
+
},
|
|
765
|
+
"display-documentation": {
|
|
766
|
+
"$value": "Noto Sans, Noto Sans Math, system-ui, sans-serif",
|
|
767
|
+
"$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."
|
|
768
|
+
},
|
|
769
|
+
"brand": {
|
|
770
|
+
"$value": "Futura, system-ui, sans-serif",
|
|
771
|
+
"$description": "Brand font - dataimago navbar and branding elements"
|
|
772
|
+
},
|
|
773
|
+
"math": {
|
|
774
|
+
"$value": "Noto Sans Math, math",
|
|
775
|
+
"$description": "Noto Sans Math, falling back to the browser's maths face; native MathML is the maths contract"
|
|
776
|
+
}
|
|
777
|
+
},
|
|
778
|
+
"size": {
|
|
779
|
+
"micro": {
|
|
780
|
+
"$value": "0.75rem",
|
|
781
|
+
"$type": "dimension",
|
|
782
|
+
"$description": "Micro text - captions, metadata"
|
|
783
|
+
},
|
|
784
|
+
"small": {
|
|
785
|
+
"$value": "0.875rem",
|
|
786
|
+
"$type": "dimension",
|
|
787
|
+
"$description": "Small text - secondary information"
|
|
788
|
+
},
|
|
789
|
+
"base": {
|
|
790
|
+
"$value": "1rem",
|
|
791
|
+
"$type": "dimension",
|
|
792
|
+
"$description": "Base text size - body content"
|
|
793
|
+
},
|
|
794
|
+
"readable": {
|
|
795
|
+
"$value": "1.125rem",
|
|
796
|
+
"$type": "dimension",
|
|
797
|
+
"$description": "Comfortable reading size - main content"
|
|
798
|
+
},
|
|
799
|
+
"emphasis": {
|
|
800
|
+
"$value": "1.25rem",
|
|
801
|
+
"$type": "dimension",
|
|
802
|
+
"$description": "Emphasized text - call-outs"
|
|
803
|
+
},
|
|
804
|
+
"heading-small": {
|
|
805
|
+
"$value": "1.5rem",
|
|
806
|
+
"$type": "dimension",
|
|
807
|
+
"$description": "Small headings - H4, H5"
|
|
808
|
+
},
|
|
809
|
+
"heading-medium": {
|
|
810
|
+
"$value": "1.875rem",
|
|
811
|
+
"$type": "dimension",
|
|
812
|
+
"$description": "Medium headings - H3"
|
|
813
|
+
},
|
|
814
|
+
"heading-large": {
|
|
815
|
+
"$value": "2.25rem",
|
|
816
|
+
"$type": "dimension",
|
|
817
|
+
"$description": "Large headings - H2"
|
|
818
|
+
},
|
|
819
|
+
"heading-xl": {
|
|
820
|
+
"$value": "3rem",
|
|
821
|
+
"$type": "dimension",
|
|
822
|
+
"$description": "Extra large headings - H1"
|
|
823
|
+
}
|
|
824
|
+
},
|
|
825
|
+
"weight": {
|
|
826
|
+
"extralight": {
|
|
827
|
+
"$value": "200",
|
|
828
|
+
"$type": "number",
|
|
829
|
+
"$description": "Extra-light weight — reserved for display-scale refinements (subtitles, oversized numerals)"
|
|
830
|
+
},
|
|
831
|
+
"light": {
|
|
832
|
+
"$value": "300",
|
|
833
|
+
"$type": "number",
|
|
834
|
+
"$description": "Light weight — minor headings (h4–h6), large serif-like display at small sizes"
|
|
835
|
+
},
|
|
836
|
+
"normal": {
|
|
837
|
+
"$value": "400",
|
|
838
|
+
"$type": "number",
|
|
839
|
+
"$description": "Normal text weight — body content"
|
|
840
|
+
},
|
|
841
|
+
"medium": {
|
|
842
|
+
"$value": "500",
|
|
843
|
+
"$type": "number",
|
|
844
|
+
"$description": "Medium weight — emphasis within text, h2"
|
|
845
|
+
},
|
|
846
|
+
"semibold": {
|
|
847
|
+
"$value": "600",
|
|
848
|
+
"$type": "number",
|
|
849
|
+
"$description": "Semi-bold — subtitles, important text"
|
|
850
|
+
},
|
|
851
|
+
"bold": {
|
|
852
|
+
"$value": "700",
|
|
853
|
+
"$type": "number",
|
|
854
|
+
"$description": "Bold — h1, strong emphasis"
|
|
855
|
+
},
|
|
856
|
+
"heading": {
|
|
857
|
+
"_invariant": {
|
|
858
|
+
"$value": "Heading-weight cluster — 400 floor for all Josefin Sans headings (see wiki/decisions/josefin-weight-floor.md). Sub-400 weights (200, 300) are bound to the opt-in .di-numeric-display utility class, never the default for prose-tier headings. Per wiki/decisions/h1-weight-medium.md the prose-correct band for editorial headings is 400–500."
|
|
859
|
+
},
|
|
860
|
+
"h1": {
|
|
861
|
+
"$value": "var(--font-weight-medium)",
|
|
862
|
+
"$description": "Heading h1 weight — medium (500). Top-level editorial voice; preserves Josefin Sans's geometric character at hero scale (was bold/700 before iteration-1; see wiki/decisions/h1-weight-medium.md)."
|
|
863
|
+
},
|
|
864
|
+
"h2": {
|
|
865
|
+
"$value": "var(--font-weight-medium)",
|
|
866
|
+
"$description": "Heading h2 weight — medium (500). Second tier; sub-sections."
|
|
867
|
+
},
|
|
868
|
+
"h3": {
|
|
869
|
+
"$value": "var(--font-weight-normal)",
|
|
870
|
+
"$description": "Heading h3 weight — normal (400). Differentiated from body by size, not weight."
|
|
871
|
+
},
|
|
872
|
+
"h4": {
|
|
873
|
+
"$value": "var(--font-weight-light)",
|
|
874
|
+
"$description": "Heading h4 weight — light (300). Minor heading; quiet hierarchy marker."
|
|
875
|
+
},
|
|
876
|
+
"h5": {
|
|
877
|
+
"$value": "var(--font-weight-light)",
|
|
878
|
+
"$description": "Heading h5 weight — light (300). Minor heading."
|
|
879
|
+
},
|
|
880
|
+
"h6": {
|
|
881
|
+
"$value": "var(--font-weight-light)",
|
|
882
|
+
"$description": "Heading h6 weight — light (300). Minor heading."
|
|
883
|
+
},
|
|
884
|
+
"subtitle": {
|
|
885
|
+
"$value": "var(--font-weight-semibold)",
|
|
886
|
+
"$description": "Subtitle weight — semibold (600). Heavier than h3 on purpose: reads as emphasis, not continuation."
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
},
|
|
890
|
+
"style": {
|
|
891
|
+
"normal": {
|
|
892
|
+
"$value": "normal",
|
|
893
|
+
"$description": "Normal font style - upright text"
|
|
894
|
+
},
|
|
895
|
+
"italic": {
|
|
896
|
+
"$value": "italic",
|
|
897
|
+
"$description": "Italic style - sloped text with true italic glyphs"
|
|
898
|
+
},
|
|
899
|
+
"oblique": {
|
|
900
|
+
"$value": "oblique",
|
|
901
|
+
"$description": "Oblique style - sloped text without true italic design"
|
|
902
|
+
}
|
|
903
|
+
},
|
|
904
|
+
"lineHeight": {
|
|
905
|
+
"tight": {
|
|
906
|
+
"$value": "1.25",
|
|
907
|
+
"$type": "number",
|
|
908
|
+
"$description": "Tight line height - headings"
|
|
909
|
+
},
|
|
910
|
+
"normal": {
|
|
911
|
+
"$value": "1.5",
|
|
912
|
+
"$type": "number",
|
|
913
|
+
"$description": "Normal line height - body text"
|
|
914
|
+
},
|
|
915
|
+
"relaxed": {
|
|
916
|
+
"$value": "1.625",
|
|
917
|
+
"$type": "number",
|
|
918
|
+
"$description": "Relaxed line height - long-form content"
|
|
919
|
+
}
|
|
920
|
+
},
|
|
921
|
+
"feature-settings": {
|
|
922
|
+
"_invariant": {
|
|
923
|
+
"$value": "OpenType feature settings cluster — display rules apply lining figures (lnum) so numerals render uniform-baseline at heading scale; body rules retain old-style figures where they belong (in-line numerical mentions in prose). See wiki/decisions/display-lining-figures.md."
|
|
924
|
+
},
|
|
925
|
+
"display": {
|
|
926
|
+
"$value": "\"lnum\"",
|
|
927
|
+
"$description": "Lining figures (lnum) for display headings — uniform baseline, uniform height; corrects Josefin Sans's old-style default figures that read as casual at editorial/title scale. Consumed by every CSS rule whose font-family resolves to --font-family-display, --font-family-display-editorial, or --font-family-display-documentation."
|
|
928
|
+
},
|
|
929
|
+
"body": {
|
|
930
|
+
"$value": "\"normal\"",
|
|
931
|
+
"$description": "Default figure style for body text — preserves Josefin's old-style figures where they harmonize with lowercase letterforms in continuous prose."
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
},
|
|
935
|
+
"spacing": {
|
|
936
|
+
"xs": {
|
|
937
|
+
"$value": "0.25rem",
|
|
938
|
+
"$type": "dimension"
|
|
939
|
+
},
|
|
940
|
+
"sm": {
|
|
941
|
+
"$value": "0.5rem",
|
|
942
|
+
"$type": "dimension"
|
|
943
|
+
},
|
|
944
|
+
"md": {
|
|
945
|
+
"$value": "1rem",
|
|
946
|
+
"$type": "dimension"
|
|
947
|
+
},
|
|
948
|
+
"lg": {
|
|
949
|
+
"$value": "1.5rem",
|
|
950
|
+
"$type": "dimension"
|
|
951
|
+
},
|
|
952
|
+
"xl": {
|
|
953
|
+
"$value": "2rem",
|
|
954
|
+
"$type": "dimension"
|
|
955
|
+
},
|
|
956
|
+
"2xl": {
|
|
957
|
+
"$value": "3rem",
|
|
958
|
+
"$type": "dimension"
|
|
959
|
+
},
|
|
960
|
+
"3xl": {
|
|
961
|
+
"$value": "4rem",
|
|
962
|
+
"$type": "dimension"
|
|
963
|
+
}
|
|
964
|
+
},
|
|
965
|
+
"radius": {
|
|
966
|
+
"sm": {
|
|
967
|
+
"$value": "0.25rem",
|
|
968
|
+
"$type": "dimension"
|
|
969
|
+
},
|
|
970
|
+
"md": {
|
|
971
|
+
"$value": "0.5rem",
|
|
972
|
+
"$type": "dimension"
|
|
973
|
+
},
|
|
974
|
+
"lg": {
|
|
975
|
+
"$value": "0.75rem",
|
|
976
|
+
"$type": "dimension"
|
|
977
|
+
},
|
|
978
|
+
"xl": {
|
|
979
|
+
"$value": "1rem",
|
|
980
|
+
"$type": "dimension"
|
|
981
|
+
},
|
|
982
|
+
"full": {
|
|
983
|
+
"$value": "9999px",
|
|
984
|
+
"$type": "dimension"
|
|
985
|
+
}
|
|
986
|
+
},
|
|
987
|
+
"$extensions": {
|
|
988
|
+
"com.dataimago.components": {
|
|
989
|
+
"card": {
|
|
990
|
+
"background": "surface.elevated",
|
|
991
|
+
"padding": "spacing.component.padding",
|
|
992
|
+
"radius": "radius.component",
|
|
993
|
+
"shadow": "shadow.moderate",
|
|
994
|
+
"border": "border.subtle",
|
|
995
|
+
"description": "Card component tokens - references semantic tokens"
|
|
996
|
+
},
|
|
997
|
+
"button": {
|
|
998
|
+
"padding-x": "spacing.component.padding",
|
|
999
|
+
"padding-y": "spacing.micro.normal",
|
|
1000
|
+
"radius": "radius.component",
|
|
1001
|
+
"font-weight": "typography.weight.medium",
|
|
1002
|
+
"primary": {
|
|
1003
|
+
"background": "interactive.primary",
|
|
1004
|
+
"text": "content.inverse",
|
|
1005
|
+
"hover": "interactive.hover"
|
|
1006
|
+
},
|
|
1007
|
+
"secondary": {
|
|
1008
|
+
"background": "surface.elevated",
|
|
1009
|
+
"text": "content.primary",
|
|
1010
|
+
"hover": "surface.page"
|
|
1011
|
+
}
|
|
1012
|
+
},
|
|
1013
|
+
"navbar": {
|
|
1014
|
+
"background": "surface.navbar",
|
|
1015
|
+
"background-scrolled": "surface.navbar-scrolled",
|
|
1016
|
+
"text": "content.secondary",
|
|
1017
|
+
"text-hover": "interactive.accent",
|
|
1018
|
+
"transition": "transition.smooth"
|
|
1019
|
+
},
|
|
1020
|
+
"navigation": {
|
|
1021
|
+
"item-spacing": "spacing.micro.loose",
|
|
1022
|
+
"hover-background": {
|
|
1023
|
+
"light": "rgba(20, 20, 16, 0.05)",
|
|
1024
|
+
"dark": "rgba(237, 237, 235, 0.05)"
|
|
1025
|
+
},
|
|
1026
|
+
"active-background": {
|
|
1027
|
+
"light": "rgba(20, 20, 16, 0.1)",
|
|
1028
|
+
"dark": "rgba(237, 237, 235, 0.1)"
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
},
|
|
1032
|
+
"com.dataimago.frequent": {
|
|
1033
|
+
"spacing": {
|
|
1034
|
+
"component": {
|
|
1035
|
+
"padding": "1rem",
|
|
1036
|
+
"margin": "1.5rem",
|
|
1037
|
+
"gap": "0.75rem",
|
|
1038
|
+
"description": "Most frequently adjusted spacing - component internals"
|
|
1039
|
+
},
|
|
1040
|
+
"layout": {
|
|
1041
|
+
"section": "3rem",
|
|
1042
|
+
"container": "2rem",
|
|
1043
|
+
"comfortable": "1rem",
|
|
1044
|
+
"description": "Layout-level spacing - between major elements"
|
|
1045
|
+
},
|
|
1046
|
+
"micro": {
|
|
1047
|
+
"tight": "0.25rem",
|
|
1048
|
+
"normal": "0.5rem",
|
|
1049
|
+
"loose": "1rem",
|
|
1050
|
+
"description": "Fine-tuning spacing - when things feel cramped or loose"
|
|
1051
|
+
}
|
|
1052
|
+
},
|
|
1053
|
+
"radius": {
|
|
1054
|
+
"component": "0.5rem",
|
|
1055
|
+
"subtle": "0.25rem",
|
|
1056
|
+
"prominent": "0.75rem",
|
|
1057
|
+
"full": "9999px",
|
|
1058
|
+
"description": "Border radius values - component rounding"
|
|
1059
|
+
},
|
|
1060
|
+
"contrast": {
|
|
1061
|
+
"high": {
|
|
1062
|
+
"light": "rgb(20, 20, 16)",
|
|
1063
|
+
"dark": "rgb(237, 237, 235)",
|
|
1064
|
+
"description": "Maximum contrast text - accessibility focus"
|
|
1065
|
+
},
|
|
1066
|
+
"readable": {
|
|
1067
|
+
"light": "rgb(20, 20, 16)",
|
|
1068
|
+
"dark": "rgb(237, 237, 235)",
|
|
1069
|
+
"description": "Comfortable reading contrast - primary text"
|
|
1070
|
+
},
|
|
1071
|
+
"medium": {
|
|
1072
|
+
"light": "#7c7c7c",
|
|
1073
|
+
"dark": "#83838f",
|
|
1074
|
+
"description": "Medium emphasis - secondary information"
|
|
1075
|
+
},
|
|
1076
|
+
"subtle": {
|
|
1077
|
+
"light": "#7c7c7c",
|
|
1078
|
+
"dark": "#83838f",
|
|
1079
|
+
"description": "De-emphasized text - captions, meta info"
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
}
|