@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dataimago/tokens",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.48",
|
|
4
4
|
"description": "dataimago design tokens — canonical JSON sources plus generated TS/CSS artifacts",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -30,7 +30,10 @@
|
|
|
30
30
|
"./frequent": "./src/frequent.json",
|
|
31
31
|
"./components": "./src/components.json",
|
|
32
32
|
"./css": "./dist/tokens.css",
|
|
33
|
-
"./scss": "./dist/tokens.scss"
|
|
33
|
+
"./scss": "./dist/tokens.scss",
|
|
34
|
+
"./dtcg": "./dist/tokens.dtcg.json",
|
|
35
|
+
"./dtcg-w3c": "./dist/tokens.w3c.dtcg.json",
|
|
36
|
+
"./tokens-studio": "./dist/tokens.studio.json"
|
|
34
37
|
},
|
|
35
38
|
"files": [
|
|
36
39
|
"src",
|
package/src/README.md
CHANGED
|
@@ -1,175 +1,59 @@
|
|
|
1
|
-
# dataimago
|
|
2
|
-
|
|
3
|
-
## 🎯 Source of Truth Architecture
|
|
4
|
-
|
|
5
|
-
This directory contains the **authoritative source** for all design decisions across the dataimago ecosystem. These JSON-based tokens serve as the foundation for:
|
|
6
|
-
|
|
7
|
-
- **CSS Custom Properties**: Generated via idempotent build process
|
|
8
|
-
- **Theme Support**: Automatic light/dark mode generation
|
|
9
|
-
- **Consumer Integration**: Distributed to all consumer repositories via git submodules
|
|
10
|
-
- **Design Consistency**: Single definition → multiple output formats
|
|
11
|
-
|
|
12
|
-
## 🔄 Idempotent Token Processing
|
|
13
|
-
|
|
14
|
-
The token build system follows strict deterministic principles:
|
|
15
|
-
|
|
16
|
-
- **✅ Stable Output**: Same tokens → identical CSS every time
|
|
17
|
-
- **✅ No Timestamps**: Generated CSS excludes dynamic timestamps
|
|
18
|
-
- **✅ Version Controlled**: Only source tokens are committed, generated files are build artifacts
|
|
19
|
-
- **✅ Consumer Ready**: Generated assets integrate seamlessly into consumer repositories
|
|
20
|
-
|
|
21
|
-
## Overview
|
|
22
|
-
These tokens are processed into CSS custom properties that work across light and dark themes via our idempotent build system.
|
|
23
|
-
|
|
24
|
-
## Token Structure
|
|
25
|
-
|
|
26
|
-
### 🎨 **theme-colors.json** - Theme-Aware Colors
|
|
27
|
-
Your carefully tuned light/dark color scheme:
|
|
28
|
-
|
|
29
|
-
```json
|
|
30
|
-
{
|
|
31
|
-
"color": {
|
|
32
|
-
"surface": {
|
|
33
|
-
"page": {
|
|
34
|
-
"light": "rgb(237, 237, 235)", // Your warm light gray
|
|
35
|
-
"dark": "rgb(20, 20, 16)" // Your warm dark background
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
"content": {
|
|
39
|
-
"primary": {
|
|
40
|
-
"light": "rgb(20, 20, 16)", // Near Black text on light
|
|
41
|
-
"dark": "rgb(237, 237, 235)" // Near white on dark
|
|
42
|
-
},
|
|
43
|
-
"secondary": {
|
|
44
|
-
"light": "#7c7c7c", // Your tuned light gray
|
|
45
|
-
"dark": "#83838f" // Your tuned dark gray
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### 🏃 **frequent.json** - High-Change Values
|
|
53
|
-
Most commonly adjusted in DevTools:
|
|
54
|
-
|
|
55
|
-
```json
|
|
56
|
-
{
|
|
57
|
-
"spacing": {
|
|
58
|
-
"component": {
|
|
59
|
-
"padding": "1rem", // Card/button internal spacing
|
|
60
|
-
"margin": "1.5rem", // Between-component spacing
|
|
61
|
-
"gap": "0.75rem" // Flex/grid gaps
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
"contrast": {
|
|
65
|
-
"readable": "...", // Comfortable reading contrast
|
|
66
|
-
"medium": "...", // Secondary information
|
|
67
|
-
"subtle": "..." // De-emphasized text
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### 🎯 **effects.json** - Theme-Aware Effects
|
|
73
|
-
Shadows and borders that adapt to themes:
|
|
74
|
-
|
|
75
|
-
```json
|
|
76
|
-
{
|
|
77
|
-
"shadow": {
|
|
78
|
-
"subtle": {
|
|
79
|
-
"light": "0 1px 2px 0 rgb(0 0 0 / 0.05)",
|
|
80
|
-
"dark": "0 1px 2px 0 rgb(255 255 255 / 0.03)"
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
"border": {
|
|
84
|
-
"subtle": {
|
|
85
|
-
"light": "rgba(0, 0, 0, 0.1)",
|
|
86
|
-
"dark": "rgba(255, 255, 255, 0.1)"
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### 🧩 **components.json** - Component References
|
|
93
|
-
Components reference semantic tokens:
|
|
94
|
-
|
|
95
|
-
```json
|
|
96
|
-
{
|
|
97
|
-
"card": {
|
|
98
|
-
"background": "surface.elevated",
|
|
99
|
-
"padding": "spacing.component.padding",
|
|
100
|
-
"shadow": "shadow.moderate"
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
```
|
|
1
|
+
# dataimago Token Source Guide
|
|
104
2
|
|
|
105
|
-
|
|
3
|
+
This directory is the source tree for `@dataimago/tokens`. The package build turns these JSON files into CSS variables, SCSS maps, typed JS modules, and an additive DTCG-style export.
|
|
106
4
|
|
|
107
|
-
|
|
5
|
+
## Distribution
|
|
108
6
|
|
|
109
|
-
|
|
110
|
-
|---------------------|--------------------|-----------------------------|
|
|
111
|
-
| Card padding too tight | `frequent.json` → `spacing.component.padding` | `--spacing-component-padding` |
|
|
112
|
-
| Text too light in dark | `theme-colors.json` → `content.secondary.dark` | `--color-content-secondary` |
|
|
113
|
-
| Button needs more emphasis | `theme-colors.json` → `interactive.primary` | `--color-interactive-primary` |
|
|
114
|
-
| Borders invisible | `effects.json` → `border.subtle.dark` | `--color-border-subtle` |
|
|
7
|
+
Consumers receive tokens through public npm packages, not a production git submodule:
|
|
115
8
|
|
|
116
|
-
|
|
9
|
+
- House identity: `@dataimago/tokens`, `@dataimago/css`, `@dataimago/ui`, `@dataimago/brand`
|
|
10
|
+
- Neutral identity: `@dataimago/tokens-neutral`, `@dataimago/css-neutral`
|
|
117
11
|
|
|
118
|
-
|
|
119
|
-
# 1. Edit token JSON file
|
|
120
|
-
edit ui/src/tokens/frequent.json
|
|
121
|
-
|
|
122
|
-
# 2. Quick rebuild
|
|
123
|
-
cd ui && npm run watch # Auto-rebuilds on save
|
|
12
|
+
The compatibility contract for this tightening iteration is strict: do not remove existing package names, package exports, token names, CSS custom properties, or required consumer import paths.
|
|
124
13
|
|
|
125
|
-
|
|
126
|
-
```
|
|
14
|
+
## Source Files
|
|
127
15
|
|
|
128
|
-
|
|
16
|
+
| File | Role | Emits CSS variables? | Schema-governed? |
|
|
17
|
+
|---|---|---:|---:|
|
|
18
|
+
| `colors.json` | Primitive color scales and functional colors | Yes | Yes |
|
|
19
|
+
| `theme-colors.json` | Semantic light/dark color roles | Yes | Yes |
|
|
20
|
+
| `typography.json` | Font families, sizes, weights, styles, features, line heights | Yes | Yes |
|
|
21
|
+
| `spacing.json` | Spacing, radius, and layout scale | Yes | Yes |
|
|
22
|
+
| `effects.json` | Theme-aware borders/shadows and motion tokens | Yes | Yes |
|
|
23
|
+
| `frequent.json` | High-change reference values and metadata clusters | No | No |
|
|
24
|
+
| `components.json` | Component-level aliases/reference manifest | No | No |
|
|
129
25
|
|
|
130
|
-
|
|
26
|
+
`frequent.json` and `components.json` are intentionally treated as metadata/reference manifests in the current alpha line. Do not assume they emit CSS or normalize them opportunistically; any migration to canonical token shape needs to preserve existing exports and CSS variables.
|
|
131
27
|
|
|
132
|
-
|
|
133
|
-
/* Theme-agnostic values */
|
|
134
|
-
:root {
|
|
135
|
-
--color-brand-dataimago-primary: #3498DB;
|
|
136
|
-
--spacing-component-padding: 1rem;
|
|
137
|
-
}
|
|
28
|
+
## Build Outputs
|
|
138
29
|
|
|
139
|
-
|
|
140
|
-
:root, [data-bs-theme="light"] {
|
|
141
|
-
--color-surface-page: rgb(237, 237, 235);
|
|
142
|
-
--color-content-primary: #000000;
|
|
143
|
-
}
|
|
30
|
+
Run from the repo root:
|
|
144
31
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
--color-surface-page: rgb(20, 20, 16);
|
|
148
|
-
--color-content-primary: rgb(237, 237, 235);
|
|
149
|
-
}
|
|
32
|
+
```bash
|
|
33
|
+
node packages/tokens/build.mjs
|
|
150
34
|
```
|
|
151
35
|
|
|
152
|
-
|
|
36
|
+
The build emits:
|
|
153
37
|
|
|
154
|
-
|
|
38
|
+
- `packages/tokens/dist/tokens.css`
|
|
39
|
+
- `packages/tokens/dist/tokens.scss`
|
|
40
|
+
- `packages/tokens/dist/index.mjs`
|
|
41
|
+
- `packages/tokens/dist/index.cjs`
|
|
42
|
+
- `packages/tokens/dist/index.d.ts`
|
|
43
|
+
- `packages/tokens/dist/tokens.dtcg.json`
|
|
155
44
|
|
|
156
|
-
|
|
157
|
-
- `--color-content-primary` = Color for content/primary emphasis
|
|
158
|
-
- `--spacing-component-padding` = Spacing for component/padding use
|
|
159
|
-
- `--shadow-moderate` = Shadow for moderate elevation
|
|
45
|
+
Run the compatibility check after token changes:
|
|
160
46
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
- **Your colors preserved** = Light/dark values from your tuned SCSS files
|
|
165
|
-
- **DevTools friendly** = Easy to find the token you need to change
|
|
166
|
-
- **Automatic theming** = Components work in both themes without extra code
|
|
47
|
+
```bash
|
|
48
|
+
node tools/check-css-vars.mjs
|
|
49
|
+
```
|
|
167
50
|
|
|
168
|
-
|
|
51
|
+
The check compares generated CSS variable names against `packages/tokens/schema/css-vars.snapshot.json` and fails on removals. Additive variables are allowed.
|
|
169
52
|
|
|
170
|
-
|
|
171
|
-
- **New tokens** complement existing system
|
|
172
|
-
- **Backward compatible** = Old CSS still works during transition
|
|
173
|
-
- **Build system** automatically distributes to all channels
|
|
53
|
+
## Editing Rules
|
|
174
54
|
|
|
175
|
-
|
|
55
|
+
- Use canonical leaf shapes in CSS-emitting files: `{ "value": "..." }` or `{ "light": "...", "dark": "..." }`.
|
|
56
|
+
- Use `_invariant` or another underscore-prefixed metadata key for group-level notes.
|
|
57
|
+
- Never add a group-level `description` beside string-valued children in CSS-emitting files; that is the historical walker-bailout bug pattern.
|
|
58
|
+
- Prefer semantic roles over primitive palette references in consumers.
|
|
59
|
+
- Record threshold or role changes in `wiki/log.md`, and add or amend an ADR when the change alters durable design intent.
|
package/src/colors.json
CHANGED
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"paper": {
|
|
41
41
|
"50": { "value": "#fefdfb", "description": "Paper scale — lightest warm surface; renamed from cream — reserved for elevated cards/modals when warm tint is desired" },
|
|
42
42
|
"100": { "value": "#fdf9f2", "description": "Paper scale — warm page-background option (legacy cream-100); not the primary surface in this iteration" },
|
|
43
|
-
"200": { "value": "#faf2e3", "description": "Paper scale —
|
|
43
|
+
"200": { "value": "#faf2e3", "description": "Paper scale — pull-quote background; warm tint reads as 'paper' (code blocks and sunken surfaces moved to the card colour, 2026-11-02)" },
|
|
44
44
|
"300": { "value": "#f5e8cf", "description": "Paper scale — call-out / emphasised panel background" },
|
|
45
45
|
"400": { "value": "#edd9b3", "description": "Paper scale — muted warm accent" },
|
|
46
46
|
"500": { "value": "#e0c088", "description": "Paper scale — strong warm accent; wheat" }
|
|
@@ -74,20 +74,20 @@
|
|
|
74
74
|
},
|
|
75
75
|
"functional": {
|
|
76
76
|
"success": {
|
|
77
|
-
"value": "#
|
|
78
|
-
"description": "Success
|
|
77
|
+
"value": "#009E73",
|
|
78
|
+
"description": "Success hue (Okabe-Ito bluish-green, 2026-11-02; was Flat-UI #27AE60). For text use the mode-aware color.state.success"
|
|
79
79
|
},
|
|
80
80
|
"warning": {
|
|
81
|
-
"value": "#
|
|
82
|
-
"description": "Warning
|
|
81
|
+
"value": "#E69F00",
|
|
82
|
+
"description": "Warning hue (Okabe-Ito orange, 2026-11-02; was Flat-UI #F39C12). For text use the mode-aware color.state.warning"
|
|
83
83
|
},
|
|
84
84
|
"error": {
|
|
85
|
-
"value": "#
|
|
86
|
-
"description": "Error
|
|
85
|
+
"value": "#ef5350",
|
|
86
|
+
"description": "Error hue (red, 2026-11-02; was Flat-UI #E74C3C). For text use the mode-aware color.state.error"
|
|
87
87
|
},
|
|
88
88
|
"info": {
|
|
89
89
|
"value": "#3498DB",
|
|
90
|
-
"description": "
|
|
90
|
+
"description": "Info hue (the slate accent). For text use the mode-aware color.state.info"
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
}
|
package/src/dataviz.json
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
{
|
|
2
|
+
"color": {
|
|
3
|
+
"dataviz": {
|
|
4
|
+
"okabe-ito": {
|
|
5
|
+
"orange": {
|
|
6
|
+
"value": "#E69F00",
|
|
7
|
+
"description": "Okabe-Ito orange (Okabe & Ito 2008, colour-blind safe). House data-viz primitive; maintainer decision 2026-10-29."
|
|
8
|
+
},
|
|
9
|
+
"sky-blue": {
|
|
10
|
+
"value": "#56B4E9",
|
|
11
|
+
"description": "Okabe-Ito sky blue (Okabe & Ito 2008, colour-blind safe). House data-viz primitive; maintainer decision 2026-10-29."
|
|
12
|
+
},
|
|
13
|
+
"bluish-green": {
|
|
14
|
+
"value": "#009E73",
|
|
15
|
+
"description": "Okabe-Ito bluish green (Okabe & Ito 2008, colour-blind safe). House data-viz primitive; maintainer decision 2026-10-29."
|
|
16
|
+
},
|
|
17
|
+
"yellow": {
|
|
18
|
+
"value": "#F0E442",
|
|
19
|
+
"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."
|
|
20
|
+
},
|
|
21
|
+
"blue": {
|
|
22
|
+
"value": "#0072B2",
|
|
23
|
+
"description": "Okabe-Ito blue (Okabe & Ito 2008, colour-blind safe). House data-viz primitive; maintainer decision 2026-10-29."
|
|
24
|
+
},
|
|
25
|
+
"vermillion": {
|
|
26
|
+
"value": "#D55E00",
|
|
27
|
+
"description": "Okabe-Ito vermillion (Okabe & Ito 2008, colour-blind safe). House data-viz primitive; maintainer decision 2026-10-29."
|
|
28
|
+
},
|
|
29
|
+
"reddish-purple": {
|
|
30
|
+
"value": "#CC79A7",
|
|
31
|
+
"description": "Okabe-Ito reddish purple (Okabe & Ito 2008, colour-blind safe). House data-viz primitive; maintainer decision 2026-10-29."
|
|
32
|
+
},
|
|
33
|
+
"black": {
|
|
34
|
+
"light": "#000000",
|
|
35
|
+
"dark": "#FDF9F2",
|
|
36
|
+
"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)."
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"categorical": {
|
|
40
|
+
"1": {
|
|
41
|
+
"value": "#E69F00",
|
|
42
|
+
"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."
|
|
43
|
+
},
|
|
44
|
+
"2": {
|
|
45
|
+
"value": "#56B4E9",
|
|
46
|
+
"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."
|
|
47
|
+
},
|
|
48
|
+
"3": {
|
|
49
|
+
"value": "#009E73",
|
|
50
|
+
"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."
|
|
51
|
+
},
|
|
52
|
+
"4": {
|
|
53
|
+
"value": "#F0E442",
|
|
54
|
+
"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."
|
|
55
|
+
},
|
|
56
|
+
"5": {
|
|
57
|
+
"value": "#0072B2",
|
|
58
|
+
"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."
|
|
59
|
+
},
|
|
60
|
+
"6": {
|
|
61
|
+
"value": "#D55E00",
|
|
62
|
+
"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."
|
|
63
|
+
},
|
|
64
|
+
"7": {
|
|
65
|
+
"value": "#CC79A7",
|
|
66
|
+
"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."
|
|
67
|
+
},
|
|
68
|
+
"8": {
|
|
69
|
+
"light": "#000000",
|
|
70
|
+
"dark": "#FDF9F2",
|
|
71
|
+
"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."
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"uncertainty": {
|
|
75
|
+
"outer": {
|
|
76
|
+
"light": "#D6D6D6",
|
|
77
|
+
"dark": "#333333",
|
|
78
|
+
"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)."
|
|
79
|
+
},
|
|
80
|
+
"union": {
|
|
81
|
+
"light": "#9E9E9E",
|
|
82
|
+
"dark": "#6B6B6B",
|
|
83
|
+
"description": "Union band (gray 0.62); mirrored in dark mode. Dark value approved by the maintainer 2026-10-29 (dataviz-check --propose-dark)."
|
|
84
|
+
},
|
|
85
|
+
"inner": {
|
|
86
|
+
"light": "#333333",
|
|
87
|
+
"dark": "#D6D6D6",
|
|
88
|
+
"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)."
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"sgpc-bucket": {
|
|
92
|
+
"very-low": {
|
|
93
|
+
"value": "#D55E00",
|
|
94
|
+
"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."
|
|
95
|
+
},
|
|
96
|
+
"low": {
|
|
97
|
+
"value": "#E69F00",
|
|
98
|
+
"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."
|
|
99
|
+
},
|
|
100
|
+
"typical": {
|
|
101
|
+
"value": "#56B4E9",
|
|
102
|
+
"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."
|
|
103
|
+
},
|
|
104
|
+
"high": {
|
|
105
|
+
"value": "#009E73",
|
|
106
|
+
"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."
|
|
107
|
+
},
|
|
108
|
+
"very-high": {
|
|
109
|
+
"value": "#0072B2",
|
|
110
|
+
"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."
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"sgpc-role": {
|
|
114
|
+
"marginal": {
|
|
115
|
+
"value": "#0072B2",
|
|
116
|
+
"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."
|
|
117
|
+
},
|
|
118
|
+
"linkage": {
|
|
119
|
+
"value": "#D55E00",
|
|
120
|
+
"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."
|
|
121
|
+
},
|
|
122
|
+
"kernel": {
|
|
123
|
+
"value": "#CC79A7",
|
|
124
|
+
"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."
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"map": {
|
|
128
|
+
"ocean": {
|
|
129
|
+
"light": "#808fa7",
|
|
130
|
+
"dark": "#042438",
|
|
131
|
+
"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)."
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
package/src/effects.json
CHANGED
|
@@ -14,18 +14,50 @@
|
|
|
14
14
|
"light": "0 10px 15px -3px rgb(20 20 16 / 0.1)",
|
|
15
15
|
"dark": "0 10px 15px -3px rgb(237 237 235 / 0.4)",
|
|
16
16
|
"description": "Strong elevation - modals, floating elements"
|
|
17
|
+
},
|
|
18
|
+
"figure-plate": {
|
|
19
|
+
"hover": {
|
|
20
|
+
"light": "0 10px 15px -3px rgb(20 20 16 / 0.1)",
|
|
21
|
+
"dark": "0 4px 12px rgb(0 0 0 / 0.5)",
|
|
22
|
+
"description": "Figure plate on hover. Light mode is the prominent shadow. Dark mode needs its own value: the plate stays light in dark mode, and prominent's light-ink glow (rgb(237 237 235 / 0.4)) would haze the dark page round a light plate, so a plain black shadow is used. Not mode-invariant."
|
|
23
|
+
},
|
|
24
|
+
"active": {
|
|
25
|
+
"light": "0 4px 6px -1px rgb(20 20 16 / 0.1)",
|
|
26
|
+
"dark": "0 2px 8px rgb(0 0 0 / 0.35)",
|
|
27
|
+
"description": "Figure plate while pressed. Light mode is the moderate shadow; dark mode is a plain black shadow for the same reason as figure-plate.hover. Not mode-invariant."
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"lift": {
|
|
31
|
+
"light": "0 -8px 24px rgb(20 20 16 / 0.07)",
|
|
32
|
+
"dark": "0 -8px 24px rgb(0 0 0 / 0.30)",
|
|
33
|
+
"description": "Upward panel lift: a lower panel rising over the section above it, e.g. the landing's lower panel over the globe during the section wipe. Every other shadow here falls downward. Light is ink-900-ish at 0.07 (the apps wrote rgb(28 25 23), normalised to the house base rgb(20 20 16)); dark is plain black at 0.30 because a light-ink glow (as in shadow.prominent) would haze the dark page above the panel. The dark value is a controller call, not measured. Raised from the SGPc apps (2026-11-03)."
|
|
34
|
+
},
|
|
35
|
+
"sheet": {
|
|
36
|
+
"light": "0 -8px 24px rgb(0 0 0 / 0.18)",
|
|
37
|
+
"dark": "0 -8px 24px rgb(0 0 0 / 0.18)",
|
|
38
|
+
"description": "Upward shadow for a bottom sheet (the map details panel on a narrow screen). Plain black at 0.18 in both modes: a sheet is a physical layer over the page, so light and dark carry the same value. Raised from the SGPc apps (2026-11-03)."
|
|
39
|
+
},
|
|
40
|
+
"float": {
|
|
41
|
+
"light": "0 1px 2px rgb(20 20 16 / 0.06), 0 4px 14px rgb(20 20 16 / 0.08)",
|
|
42
|
+
"dark": "0 1px 2px rgb(0 0 0 / 0.40), 0 4px 14px rgb(0 0 0 / 0.35)",
|
|
43
|
+
"description": "Floating control: a small disc standing off the page, e.g. the landing's scroll chevron. Two layers, a tight contact shadow and a soft spread. Pair it with a hairline outline, because a shadow alone does not read in dark mode. Light is the apps' value normalised to rgb(20 20 16); dark is plain black, stronger (0.40 and 0.35) so the layers still read on a dark page, a controller call, not measured. Raised from the SGPc apps (2026-11-03)."
|
|
44
|
+
},
|
|
45
|
+
"print": {
|
|
46
|
+
"light": "0 1px 3px rgb(0 0 0 / 0.25)",
|
|
47
|
+
"dark": "0 1px 3px rgb(0 0 0 / 0.25)",
|
|
48
|
+
"description": "Paper drop shadow under a printed-paper object, e.g. the paper-cover thumbnail on color.surface.print. It depicts a physical object, so it is theme-invariant: the same in light and dark. Raised from the SGPc apps (2026-11-03)."
|
|
17
49
|
}
|
|
18
50
|
},
|
|
19
51
|
"border": {
|
|
20
52
|
"subtle": {
|
|
21
|
-
"light": "rgba(20, 20, 16, 0.
|
|
22
|
-
"dark": "rgba(237, 237, 235, 0.
|
|
23
|
-
"description": "Subtle borders - element separation"
|
|
53
|
+
"light": "rgba(20, 20, 16, 0.47)",
|
|
54
|
+
"dark": "rgba(237, 237, 235, 0.47)",
|
|
55
|
+
"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."
|
|
24
56
|
},
|
|
25
57
|
"moderate": {
|
|
26
|
-
"light": "rgba(20, 20, 16, 0.
|
|
27
|
-
"dark": "rgba(237, 237, 235, 0.
|
|
28
|
-
"description": "Moderate borders - defined boundaries"
|
|
58
|
+
"light": "rgba(20, 20, 16, 0.63)",
|
|
59
|
+
"dark": "rgba(237, 237, 235, 0.63)",
|
|
60
|
+
"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."
|
|
29
61
|
},
|
|
30
62
|
"focus": {
|
|
31
63
|
"light": "#3498DB",
|
|
@@ -50,5 +82,51 @@
|
|
|
50
82
|
"value": "0.3s",
|
|
51
83
|
"description": "Reserved for the dataimago wordmark / brand-mark transitions; do not borrow for general UI"
|
|
52
84
|
}
|
|
85
|
+
},
|
|
86
|
+
"gradient": {
|
|
87
|
+
"video-poster": {
|
|
88
|
+
"value": "linear-gradient(135deg, #2b3a4a, #1f2a1f 60%, #3b2f1c)",
|
|
89
|
+
"description": "Video-poster placeholder, shown until a real poster frame exists: a slate-to-green-to-umber diagonal. It depicts a video frame, so it is theme-invariant (the same in light and dark). Its three stops (#2b3a4a, #1f2a1f, #3b2f1c) are a one-off and are NOT palette colours: do not reach for them elsewhere. A CSS gradient string has no clean DTCG mapping, so this token is in tokens.css and the JS exports only and is left out of the W3C DTCG and Tokens Studio exports (the legacy dist/tokens.dtcg.json still carries it). Raised from the SGPc apps (2026-11-03)."
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"motion": {
|
|
93
|
+
"enter": {
|
|
94
|
+
"value": "200ms",
|
|
95
|
+
"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."
|
|
96
|
+
},
|
|
97
|
+
"exit": {
|
|
98
|
+
"value": "120ms",
|
|
99
|
+
"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."
|
|
100
|
+
},
|
|
101
|
+
"ease-out": {
|
|
102
|
+
"value": "cubic-bezier(0.25, 0.46, 0.45, 0.94)",
|
|
103
|
+
"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."
|
|
104
|
+
},
|
|
105
|
+
"ease-in": {
|
|
106
|
+
"value": "cubic-bezier(0.55, 0.085, 0.68, 0.53)",
|
|
107
|
+
"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."
|
|
108
|
+
},
|
|
109
|
+
"duration": {
|
|
110
|
+
"120": {
|
|
111
|
+
"value": "120ms",
|
|
112
|
+
"description": "Duration scale step, 120ms. Equal to motion.exit."
|
|
113
|
+
},
|
|
114
|
+
"160": {
|
|
115
|
+
"value": "160ms",
|
|
116
|
+
"description": "Duration scale step, 160ms: a hover on a small control, a sheet leaving."
|
|
117
|
+
},
|
|
118
|
+
"200": {
|
|
119
|
+
"value": "200ms",
|
|
120
|
+
"description": "Duration scale step, 200ms. Equal to motion.enter."
|
|
121
|
+
},
|
|
122
|
+
"250": {
|
|
123
|
+
"value": "250ms",
|
|
124
|
+
"description": "Duration scale step, 250ms: a sheet arriving, a grid-column change."
|
|
125
|
+
},
|
|
126
|
+
"300": {
|
|
127
|
+
"value": "300ms",
|
|
128
|
+
"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."
|
|
129
|
+
}
|
|
130
|
+
}
|
|
53
131
|
}
|
|
54
|
-
}
|
|
132
|
+
}
|