@nebutra/design-tokens 0.1.2 → 2.0.0

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.
@@ -175,6 +175,22 @@
175
175
  --radius-3xl: 1.5rem;
176
176
  --radius-full: 9999px;
177
177
 
178
+ /* Containers — the page-width contract from CLAUDE.md, as real utilities.
179
+ max-w-text (reading), max-w-content (pricing/blog), max-w-wide (feature bento, navbar).
180
+
181
+ These values also reach :root through the semantic layer, so var(--container-wide) keeps
182
+ working; what was missing was the Tailwind side. Without it there is no max-w-wide to reach
183
+ for, and 92 call sites across apps/** had typed max-w-wide instead — a decided number
184
+ living in a className, where changing the token cannot move it.
185
+
186
+ Literals rather than var(--container-wide): Tailwind emits an @theme entry into its own
187
+ layer, so a same-named reference becomes self-referential and survives only because the
188
+ semantic :root happens to come later in the cascade. Duplicating the number and pinning it
189
+ with a parity test is the honest trade — see design-tokens' container parity test. */
190
+ --container-text: 896px;
191
+ --container-content: 1152px;
192
+ --container-wide: 1400px;
193
+
178
194
  /* Shadows */
179
195
  --shadow-xs: var(--elevation-xs);
180
196
  --shadow-sm: var(--elevation-sm);
@@ -185,22 +201,77 @@
185
201
  --shadow-brand: var(--elevation-brand);
186
202
  --shadow-brand-lg: var(--elevation-brand-lg);
187
203
 
188
- /* Motion — Easing curves */
189
- --ease-in: cubic-bezier(0.4, 0, 1, 1);
190
- --ease-out: cubic-bezier(0, 0, 0.2, 1);
191
- --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
192
- --ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
204
+ /* shadow-ambient-md / shadow-glass-lg / shadow-sheen — so marketing surfaces
205
+ reach for a step on the ramp instead of spelling out a blur and a spread.
206
+ Aliased to var() rather than inlined so the dark theme's values apply. */
207
+ --shadow-ambient-sm: var(--elevation-ambient-sm);
208
+ --shadow-ambient-md: var(--elevation-ambient-md);
209
+ --shadow-ambient-lg: var(--elevation-ambient-lg);
210
+ --shadow-glass-sm: var(--elevation-glass-sm);
211
+ --shadow-glass-md: var(--elevation-glass-md);
212
+ --shadow-glass-lg: var(--elevation-glass-lg);
213
+ --shadow-sheen: var(--elevation-sheen);
214
+
215
+ /* Coloured and centred elevation. shadow-ambient-glow is the one
216
+ non-directional step; shadow-glow-accent|-lg|-sm carry a brand-accent halo
217
+ so a glass card never hand-types the accent as raw rgba; shadow-glow-primary
218
+ tints the xl geometry with the action fill. */
219
+ --shadow-ambient-glow: var(--elevation-ambient-glow);
220
+ --shadow-glow-accent: var(--elevation-glow-accent);
221
+ --shadow-glow-accent-lg: var(--elevation-glow-accent-lg);
222
+ --shadow-glow-accent-sm: var(--elevation-glow-accent-sm);
223
+ --shadow-glow-primary: var(--elevation-glow-primary);
224
+
225
+ /* Motion — Easing curves.
226
+ Indirect, like the shadows above: an @theme entry holding a literal is
227
+ inlined into the utility, so the ease-out class compiled to a fixed
228
+ cubic-bezier and no Brand Package could move it. Pointing at the runtime
229
+ rail in static/base.css makes it follow the language the page is under.
230
+ (No backticks in this block — it is inside a JS template literal.) */
231
+ --ease-in: var(--motion-ease-in);
232
+ --ease-out: var(--motion-ease-out);
233
+ --ease-brand: var(--motion-ease-brand);
234
+ --ease-in-out: var(--motion-ease-in-out);
235
+ --ease-spring: var(--motion-ease-spring);
193
236
 
194
237
  /* Motion — Durations (four-rail; see core.json:duration). Names denote intent, not relative speed. */
195
- --duration-micro: 100ms;
196
- --duration-flow: 200ms;
197
- --duration-reveal: 300ms;
198
- --duration-cinematic: 500ms;
199
-
200
- /* Font family — Geist primary stack with CJK fallbacks */
201
- --font-sans: var(--font-geist-sans), "Geist", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
202
- --font-cn: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", "vivo Sans", sans-serif;
203
- --font-display: var(--font-geist-sans), "Geist", "Noto Sans SC", sans-serif;
204
- --font-heading: var(--font-geist-sans), "Geist", "Noto Sans SC", sans-serif;
238
+ --duration-micro: var(--motion-duration-micro);
239
+ --duration-flow: var(--motion-duration-flow);
240
+ --duration-reveal: var(--motion-duration-reveal);
241
+ --duration-cinematic: var(--motion-duration-cinematic);
242
+
243
+ /* The same four rails on the namespace Tailwind reads for duration-*.
244
+ --duration-* is the variable other CSS consumes; the utility class is built
245
+ from --transition-duration-*, and only that one. Without these,
246
+ duration-micro and duration-reveal are class names that generate nothing:
247
+ they were in use in the component library and on the marketing site, and
248
+ every one of them silently fell back to the 150ms default. */
249
+ --transition-duration-micro: var(--motion-duration-micro);
250
+ --transition-duration-flow: var(--motion-duration-flow);
251
+ --transition-duration-reveal: var(--motion-duration-reveal);
252
+ --transition-duration-cinematic: var(--motion-duration-cinematic);
253
+
254
+ /* Likewise for ease-*: the utility namespace is --ease-* already, so the four
255
+ above are reachable as ease-brand / ease-spring without further mapping. */
256
+
257
+ /* Spacing — DO NOT register --spacing-sm|md|lg|xl|2xl here.
258
+ Tailwind v4 puts every --spacing-{key} on the shared size rail, so
259
+ max-w-sm / max-w-2xl (and width/height/gap utilities with the same keys)
260
+ resolve to the breathing-room lengths (0.75rem to 3rem) instead of the
261
+ container scale (24rem to 42rem). That shipped as one-word-per-line prose
262
+ and a 32px install box on nebutra.com (measured 2026-08-03).
263
+ Brand Packages still override --space-source-*; consumers must read
264
+ those vars directly (var(--space-source-md, ...)), never via a @theme
265
+ --spacing-{step} alias. --spacing itself (0.25rem arithmetic base) stays
266
+ untouched. See static/base.css. */
267
+
268
+ /* Font family — Geist keeps Latin + numerals, self-hosted Noto Sans SC takes
269
+ CJK, system CJK faces behind it. Order is the design decision; see the
270
+ fontFamily $description in tokens/core.json. Mirror of those tokens — keep
271
+ the two in sync (verify:parity compares them). */
272
+ --font-sans: var(--font-geist-sans), "Geist", var(--font-noto-sans-sc, "Noto Sans SC"), "PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
273
+ --font-cn: var(--font-geist-sans), "Geist", var(--font-noto-sans-sc, "Noto Sans SC"), "PingFang SC", "Microsoft YaHei", sans-serif;
274
+ --font-display: var(--font-geist-sans), "Geist", var(--font-noto-sans-sc, "Noto Sans SC"), sans-serif;
275
+ --font-heading: var(--font-geist-sans), "Geist", var(--font-noto-sans-sc, "Noto Sans SC"), sans-serif;
205
276
  --font-mono: var(--font-geist-mono), "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
206
277
  }
@@ -52,6 +52,7 @@ module.exports = {
52
52
  "breakpoint-shell": "73.75rem",
53
53
  "breakpoint-3xl": "112.5rem",
54
54
  "radius-none": "0",
55
+ "radius-xs": "0.125rem",
55
56
  "radius-sm": "0.25rem",
56
57
  "radius-md": "0.375rem",
57
58
  "radius-lg": "0.5rem",
@@ -67,7 +68,7 @@ module.exports = {
67
68
  "duration-reveal": "300ms",
68
69
  "duration-cinematic": "500ms",
69
70
  "ease-in": "cubic-bezier(0.4, 0, 1, 1)",
70
- "ease-out": "cubic-bezier(0, 0, 0.2, 1)",
71
+ "ease-out": "cubic-bezier(0.16, 1, 0.3, 1)",
71
72
  "ease-in-out": "cubic-bezier(0.4, 0, 0.2, 1)",
72
73
  "ease-spring": "cubic-bezier(0.175, 0.885, 0.32, 1.275)",
73
74
  "tracking-display": "-0.04em",
@@ -78,15 +79,15 @@ module.exports = {
78
79
  "ring-hairline": "inset 0 0 0 1px rgb(255 255 255 / 0.06)",
79
80
  "overlay-faint": "rgb(255 255 255 / 0.06)",
80
81
  "font-sans":
81
- 'var(--font-geist-sans), "Geist", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, system-ui, sans-serif',
82
+ 'var(--font-geist-sans), "Geist", var(--font-noto-sans-sc, "Noto Sans SC"), "PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, system-ui, sans-serif',
82
83
  "font-cn":
83
- '"Noto Sans SC", "PingFang SC", "Microsoft YaHei", "vivo Sans", sans-serif',
84
- "font-display": 'var(--font-geist-sans), "Geist", "Noto Sans SC", sans-serif',
85
- "font-heading": 'var(--font-geist-sans), "Geist", "Noto Sans SC", sans-serif',
84
+ 'var(--font-geist-sans), "Geist", var(--font-noto-sans-sc, "Noto Sans SC"), "PingFang SC", "Microsoft YaHei", sans-serif',
85
+ "font-display":
86
+ 'var(--font-geist-sans), "Geist", var(--font-noto-sans-sc, "Noto Sans SC"), sans-serif',
87
+ "font-heading":
88
+ 'var(--font-geist-sans), "Geist", var(--font-noto-sans-sc, "Noto Sans SC"), sans-serif',
86
89
  "font-mono":
87
90
  'var(--font-geist-mono), "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace',
88
- "transition-duration": "200ms",
89
- "transition-easing": "ease-out",
90
91
  "brand-primary": "#5c7cfa",
91
92
  "brand-accent": "#1af7c8",
92
93
  "brand-tertiary": "#8b5cf6",
@@ -118,45 +119,47 @@ module.exports = {
118
119
  "neutral-3": "#1e293b",
119
120
  "neutral-4": "#334155",
120
121
  "neutral-5": "#475569",
121
- "neutral-6": "#171717",
122
- "neutral-7": "#262626",
123
- "neutral-8": "#404040",
122
+ "neutral-6": "#666666",
123
+ "neutral-7": "#7a7a7a",
124
+ "neutral-8": "#8d8d8d",
124
125
  "neutral-9": "#94a3b8",
125
126
  "neutral-10": "#cbd5e1",
126
127
  "neutral-11": "#e2e8f0",
127
128
  "neutral-12": "#f8fafc",
128
- "blue-1": "#000830",
129
- "blue-2": "#000f59",
130
- "blue-3": "#001882",
131
- "blue-4": "#0021ab",
132
- "blue-5": "#002ad4",
133
- "blue-6": "#001882",
134
- "blue-7": "#0021ab",
135
- "blue-8": "#002ad4",
136
- "blue-9": "#5c7cfa",
137
- "blue-10": "#91a7ff",
138
- "blue-11": "#bac8ff",
139
- "blue-12": "#dbe4ff",
140
- "cyan-1": "#012923",
141
- "cyan-2": "#035143",
142
- "cyan-3": "#057963",
143
- "cyan-4": "#07a183",
144
- "cyan-5": "#09c9a3",
145
- "cyan-6": "#057963",
146
- "cyan-7": "#07a183",
147
- "cyan-8": "#09c9a3",
148
- "cyan-9": "#1af7c8",
149
- "cyan-10": "#4dfcd4",
150
- "cyan-11": "#80ffe0",
151
- "cyan-12": "#b3ffec",
129
+ "blue-1": "#030815",
130
+ "blue-2": "#060f25",
131
+ "blue-3": "#09183b",
132
+ "blue-4": "#0d2254",
133
+ "blue-5": "#132e6f",
134
+ "blue-6": "#1c3c8a",
135
+ "blue-7": "#254ba7",
136
+ "blue-8": "#2f5ac4",
137
+ "blue-9": "#396ae2",
138
+ "blue-10": "#3f70e3",
139
+ "blue-11": "#89aaee",
140
+ "blue-12": "#d2e0fd",
141
+ "blue-contrast": "#ffffff",
142
+ "cyan-1": "#04100c",
143
+ "cyan-2": "#091e18",
144
+ "cyan-3": "#0f2e25",
145
+ "cyan-4": "#1c4035",
146
+ "cyan-5": "#2b5347",
147
+ "cyan-6": "#307864",
148
+ "cyan-7": "#309e82",
149
+ "cyan-8": "#28c7a2",
150
+ "cyan-9": "#0bf1c3",
151
+ "cyan-10": "#5af8ce",
152
+ "cyan-11": "#90fbdb",
153
+ "cyan-12": "#bdfde8",
154
+ "cyan-contrast": "#0d2b25",
152
155
  background: "222 14% 9%",
153
156
  foreground: "210 18% 96%",
154
157
  card: "222 12% 13%",
155
158
  "card-foreground": "210 18% 96%",
156
159
  popover: "222 12% 13%",
157
160
  "popover-foreground": "210 18% 96%",
158
- primary: "228 90% 72%",
159
- "primary-foreground": "222 14% 9%",
161
+ primary: "222.6 74.4% 55.5%",
162
+ "primary-foreground": "0 0% 100%",
160
163
  secondary: "222 10% 18%",
161
164
  "secondary-foreground": "210 18% 96%",
162
165
  muted: "222 10% 17%",
@@ -165,10 +168,13 @@ module.exports = {
165
168
  "accent-foreground": "228 95% 80%",
166
169
  destructive: "0 63% 38%",
167
170
  "destructive-foreground": "210 18% 96%",
171
+ "destructive-strong": "0 80% 66%",
168
172
  success: "142 60% 42%",
169
173
  "success-foreground": "222 14% 9%",
174
+ "success-strong": "142 60% 42%",
170
175
  warning: "38 80% 52%",
171
176
  "warning-foreground": "222 14% 9%",
177
+ "warning-strong": "38 80% 52%",
172
178
  info: "228 95% 72%",
173
179
  "info-foreground": "222 14% 9%",
174
180
  border: "220 8% 22%",
@@ -233,4 +239,26 @@ module.exports = {
233
239
  "0 0 0 1px rgb(92 124 250 / 0.25), 0 4px 20px -2px rgb(92 124 250 / 0.3)",
234
240
  "elevation-brand-lg":
235
241
  "0 0 0 1px rgb(92 124 250 / 0.3), 0 8px 40px -4px rgb(92 124 250 / 0.4)",
242
+ "elevation-ambient-sm":
243
+ "0 1px 2px -1px rgb(0 0 0 / 0.4), 0 6px 16px -6px rgb(0 0 0 / 0.5)",
244
+ "elevation-ambient-md":
245
+ "0 2px 4px -2px rgb(0 0 0 / 0.4), 0 12px 32px -10px rgb(0 0 0 / 0.55)",
246
+ "elevation-ambient-lg":
247
+ "0 4px 8px -4px rgb(0 0 0 / 0.4), 0 24px 56px -18px rgb(0 0 0 / 0.6)",
248
+ "elevation-glass-sm":
249
+ "inset 0 1px 0 rgb(255 255 255 / 0.08), 0 1px 2px -1px rgb(0 0 0 / 0.4), 0 6px 16px -6px rgb(0 0 0 / 0.5)",
250
+ "elevation-glass-md":
251
+ "inset 0 1px 0 rgb(255 255 255 / 0.08), 0 2px 4px -2px rgb(0 0 0 / 0.4), 0 12px 32px -10px rgb(0 0 0 / 0.55)",
252
+ "elevation-glass-lg":
253
+ "inset 0 1px 0 rgb(255 255 255 / 0.08), 0 4px 8px -4px rgb(0 0 0 / 0.4), 0 24px 56px -18px rgb(0 0 0 / 0.6)",
254
+ "elevation-sheen": "inset 0 1px 0 rgb(0 0 0 / 0.12)",
255
+ "elevation-ambient-glow": "0 0 80px rgb(255 255 255 / 0.06)",
256
+ "elevation-glow-accent":
257
+ "0 8px 32px rgb(0 0 0 / 0.4), 0 0 60px color-mix(in srgb, var(--brand-accent) 8%, transparent)",
258
+ "elevation-glow-accent-lg":
259
+ "0 12px 48px rgb(0 0 0 / 0.5), 0 0 80px color-mix(in srgb, var(--brand-accent) 12%, transparent)",
260
+ "elevation-glow-accent-sm":
261
+ "0 0 20px color-mix(in srgb, var(--brand-accent) 10%, transparent)",
262
+ "elevation-glow-primary":
263
+ "0 20px 25px -5px hsl(var(--primary) / 0.05), 0 8px 10px -6px hsl(var(--primary) / 0.05)",
236
264
  };
@@ -52,6 +52,7 @@ module.exports = {
52
52
  "breakpoint-shell": "73.75rem",
53
53
  "breakpoint-3xl": "112.5rem",
54
54
  "radius-none": "0",
55
+ "radius-xs": "0.125rem",
55
56
  "radius-sm": "0.25rem",
56
57
  "radius-md": "0.375rem",
57
58
  "radius-lg": "0.5rem",
@@ -67,7 +68,7 @@ module.exports = {
67
68
  "duration-reveal": "300ms",
68
69
  "duration-cinematic": "500ms",
69
70
  "ease-in": "cubic-bezier(0.4, 0, 1, 1)",
70
- "ease-out": "cubic-bezier(0, 0, 0.2, 1)",
71
+ "ease-out": "cubic-bezier(0.16, 1, 0.3, 1)",
71
72
  "ease-in-out": "cubic-bezier(0.4, 0, 0.2, 1)",
72
73
  "ease-spring": "cubic-bezier(0.175, 0.885, 0.32, 1.275)",
73
74
  "tracking-display": "-0.04em",
@@ -78,15 +79,15 @@ module.exports = {
78
79
  "ring-hairline": "inset 0 0 0 1px rgb(255 255 255 / 0.04)",
79
80
  "overlay-faint": "rgb(0 0 0 / 0.06)",
80
81
  "font-sans":
81
- 'var(--font-geist-sans), "Geist", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, system-ui, sans-serif',
82
+ 'var(--font-geist-sans), "Geist", var(--font-noto-sans-sc, "Noto Sans SC"), "PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, system-ui, sans-serif',
82
83
  "font-cn":
83
- '"Noto Sans SC", "PingFang SC", "Microsoft YaHei", "vivo Sans", sans-serif',
84
- "font-display": 'var(--font-geist-sans), "Geist", "Noto Sans SC", sans-serif',
85
- "font-heading": 'var(--font-geist-sans), "Geist", "Noto Sans SC", sans-serif',
84
+ 'var(--font-geist-sans), "Geist", var(--font-noto-sans-sc, "Noto Sans SC"), "PingFang SC", "Microsoft YaHei", sans-serif',
85
+ "font-display":
86
+ 'var(--font-geist-sans), "Geist", var(--font-noto-sans-sc, "Noto Sans SC"), sans-serif',
87
+ "font-heading":
88
+ 'var(--font-geist-sans), "Geist", var(--font-noto-sans-sc, "Noto Sans SC"), sans-serif',
86
89
  "font-mono":
87
90
  'var(--font-geist-mono), "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace',
88
- "transition-duration": "200ms",
89
- "transition-easing": "ease-out",
90
91
  "brand-primary": "#0033fe",
91
92
  "brand-accent": "#0bf1c3",
92
93
  "brand-tertiary": "#8b5cf6",
@@ -118,44 +119,46 @@ module.exports = {
118
119
  "neutral-3": "#f1f5f9",
119
120
  "neutral-4": "#e2e8f0",
120
121
  "neutral-5": "#cbd5e1",
121
- "neutral-6": "#e2e8f0",
122
- "neutral-7": "#cbd5e1",
123
- "neutral-8": "#94a3b8",
122
+ "neutral-6": "#b0bccb",
123
+ "neutral-7": "#96a3b5",
124
+ "neutral-8": "#7d8ba0",
124
125
  "neutral-9": "#64748b",
125
126
  "neutral-10": "#475569",
126
127
  "neutral-11": "#334155",
127
128
  "neutral-12": "#0f172a",
128
- "blue-1": "#f0f4ff",
129
- "blue-2": "#dbe4ff",
130
- "blue-3": "#bac8ff",
131
- "blue-4": "#91a7ff",
132
- "blue-5": "#5c7cfa",
133
- "blue-6": "#bac8ff",
134
- "blue-7": "#91a7ff",
135
- "blue-8": "#5c7cfa",
136
- "blue-9": "#0033fe",
137
- "blue-10": "#002ad4",
138
- "blue-11": "#0021ab",
139
- "blue-12": "#000f59",
140
- "cyan-1": "#e6fff8",
141
- "cyan-2": "#b3ffec",
142
- "cyan-3": "#80ffe0",
143
- "cyan-4": "#4dfcd4",
144
- "cyan-5": "#1af7c8",
145
- "cyan-6": "#80ffe0",
146
- "cyan-7": "#4dfcd4",
147
- "cyan-8": "#1af7c8",
129
+ "blue-1": "#fafcfe",
130
+ "blue-2": "#f2f6fd",
131
+ "blue-3": "#e7eefc",
132
+ "blue-4": "#d8e4fb",
133
+ "blue-5": "#c6d7fa",
134
+ "blue-6": "#9fbcf9",
135
+ "blue-7": "#79a1f7",
136
+ "blue-8": "#5384f3",
137
+ "blue-9": "#2e65ee",
138
+ "blue-10": "#2253d4",
139
+ "blue-11": "#1740ad",
140
+ "blue-12": "#031654",
141
+ "blue-contrast": "#ffffff",
142
+ "cyan-1": "#f9fdfb",
143
+ "cyan-2": "#effbf7",
144
+ "cyan-3": "#daf9ee",
145
+ "cyan-4": "#c3f6e4",
146
+ "cyan-5": "#a3f2d8",
147
+ "cyan-6": "#8eefd1",
148
+ "cyan-7": "#77ecc9",
149
+ "cyan-8": "#5be8c2",
148
150
  "cyan-9": "#0bf1c3",
149
- "cyan-10": "#09c9a3",
150
- "cyan-11": "#07a183",
151
- "cyan-12": "#035143",
151
+ "cyan-10": "#33e5bb",
152
+ "cyan-11": "#027a61",
153
+ "cyan-12": "#004133",
154
+ "cyan-contrast": "#0d2b25",
152
155
  background: "0 0% 100%",
153
156
  foreground: "222 47% 11%",
154
157
  card: "0 0% 100%",
155
158
  "card-foreground": "222 47% 11%",
156
159
  popover: "0 0% 100%",
157
160
  "popover-foreground": "222 47% 11%",
158
- primary: "228 85% 56%",
161
+ primary: "222.8 85% 55.7%",
159
162
  "primary-foreground": "0 0% 100%",
160
163
  secondary: "210 40% 96%",
161
164
  "secondary-foreground": "222 47% 11%",
@@ -165,10 +168,13 @@ module.exports = {
165
168
  "accent-foreground": "228 85% 56%",
166
169
  destructive: "0 84% 45%",
167
170
  "destructive-foreground": "0 0% 100%",
171
+ "destructive-strong": "0 84% 45%",
168
172
  success: "142 71% 29%",
169
173
  "success-foreground": "0 0% 100%",
174
+ "success-strong": "142 71% 27%",
170
175
  warning: "38 92% 50%",
171
176
  "warning-foreground": "222 47% 11%",
177
+ "warning-strong": "38 92% 30%",
172
178
  info: "228 85% 56%",
173
179
  "info-foreground": "0 0% 100%",
174
180
  border: "240 5.9% 90%",
@@ -233,4 +239,26 @@ module.exports = {
233
239
  "0 0 0 1px rgb(0 51 254 / 0.15), 0 4px 20px -2px rgb(0 51 254 / 0.2)",
234
240
  "elevation-brand-lg":
235
241
  "0 0 0 1px rgb(0 51 254 / 0.2), 0 8px 40px -4px rgb(0 51 254 / 0.3)",
242
+ "elevation-ambient-sm":
243
+ "0 1px 2px -1px hsl(222 47% 11% / 0.06), 0 6px 16px -6px hsl(222 47% 11% / 0.12)",
244
+ "elevation-ambient-md":
245
+ "0 2px 4px -2px hsl(222 47% 11% / 0.06), 0 12px 32px -10px hsl(222 47% 11% / 0.14)",
246
+ "elevation-ambient-lg":
247
+ "0 4px 8px -4px hsl(222 47% 11% / 0.06), 0 24px 56px -18px hsl(222 47% 11% / 0.16)",
248
+ "elevation-glass-sm":
249
+ "inset 0 1px 0 rgb(255 255 255 / 0.5), 0 1px 2px -1px hsl(222 47% 11% / 0.06), 0 6px 16px -6px hsl(222 47% 11% / 0.12)",
250
+ "elevation-glass-md":
251
+ "inset 0 1px 0 rgb(255 255 255 / 0.5), 0 2px 4px -2px hsl(222 47% 11% / 0.06), 0 12px 32px -10px hsl(222 47% 11% / 0.14)",
252
+ "elevation-glass-lg":
253
+ "inset 0 1px 0 rgb(255 255 255 / 0.5), 0 4px 8px -4px hsl(222 47% 11% / 0.06), 0 24px 56px -18px hsl(222 47% 11% / 0.16)",
254
+ "elevation-sheen": "inset 0 1px 0 rgb(255 255 255 / 0.2)",
255
+ "elevation-ambient-glow": "0 0 80px hsl(222 47% 11% / 0.1)",
256
+ "elevation-glow-accent":
257
+ "0 8px 32px rgb(0 0 0 / 0.4), 0 0 60px color-mix(in srgb, var(--brand-accent) 8%, transparent)",
258
+ "elevation-glow-accent-lg":
259
+ "0 12px 48px rgb(0 0 0 / 0.5), 0 0 80px color-mix(in srgb, var(--brand-accent) 12%, transparent)",
260
+ "elevation-glow-accent-sm":
261
+ "0 0 20px color-mix(in srgb, var(--brand-accent) 10%, transparent)",
262
+ "elevation-glow-primary":
263
+ "0 20px 25px -5px hsl(var(--primary) / 0.05), 0 8px 10px -6px hsl(var(--primary) / 0.05)",
236
264
  };
@@ -70,19 +70,29 @@ export const SizeBreakpointTight: string;
70
70
  export const SizeBreakpointShell: string;
71
71
  /** 1800px — 4K / Studio Display friendliness */
72
72
  export const SizeBreakpoint3xl: string;
73
+ /** Job: flush. Edge-to-edge surfaces — a full-bleed table row, a segment welded to its neighbour, an inset that must not round twice. */
73
74
  export const SizeRadiusNone: string;
75
+ /** Job: swatch. The smallest corner that still reads as intentional at 8-12px: chart legend keys, mark highlights, progress and sparkline bar caps. Added because 18 call sites had hand-written 1px, 2px and 3px corners with no step to reach for. Matches the bottom of the Tailwind scale, so rounded-xs and var(--radius-xs) agree. */
76
+ export const SizeRadiusXs: string;
77
+ /** Job: inner. The corner of something nested inside a control — a thumbnail inside a chip, a swatch inside a tile, a code span inside a paragraph. One step inside md. */
74
78
  export const SizeRadiusSm: string;
79
+ /** Job: control. The default for anything you can click or type into at text height: input, select trigger, small button, menu item, badge with square corners. The most-used step on the ladder. */
75
80
  export const SizeRadiusMd: string;
81
+ /** Job: container. Things that hold controls rather than being one: popover, dropdown surface, tooltip, toolbar, inline code block. Aliased as radius-button. */
76
82
  export const SizeRadiusLg: string;
83
+ /** Job: card. A discrete surface in a list or grid that carries its own padding and elevation. Aliased as radius-card. */
77
84
  export const SizeRadiusXl: string;
85
+ /** Job: panel. A region that holds cards — bento cell, dialog, sheet, dashboard section. Aliased as radius-panel. */
78
86
  export const SizeRadius2xl: string;
87
+ /** Job: frame. The outermost shell of a marketing or docs composition — mockup window, hero frame, screenshot chrome. The top of the ladder. */
79
88
  export const SizeRadius3xl: string;
89
+ /** Job: pill. Fully round by intent, not by size: avatar, dot, toggle track, tag. Kept as one step, not a pair, so there is exactly one way to say round. */
80
90
  export const SizeRadiusFull: string;
81
- /** 2026 button radius — Vercel/Linear/Cursor consensus */
91
+ /** Intent alias for the container step. Reach for this in product code instead of lg so the shape can be re-tuned in one place. */
82
92
  export const SizeRadiusButton: string;
83
- /** 2026 card radius */
93
+ /** Intent alias for the card step. Reach for this in product code instead of xl. */
84
94
  export const SizeRadiusCard: string;
85
- /** 2026 bento/hero panel radius */
95
+ /** Intent alias for the panel step. Reach for this in product code instead of 2xl. */
86
96
  export const SizeRadiusPanel: string;
87
97
  /** Micro-feedback: hover, focus, toggle, button press */
88
98
  export const DurationMicro: string;
@@ -109,6 +119,7 @@ export const RingHairline: string;
109
119
  /** Dark-mode faint overlay (6% white) — inverted from light */
110
120
  export const OverlayFaint: string;
111
121
  export const FontFamilySans: string;
122
+ /** CJK-locale stack — same order as sans, minus the Latin-only system faces */
112
123
  export const FontFamilyCn: string;
113
124
  export const FontFamilyDisplay: string;
114
125
  export const FontFamilyHeading: string;
@@ -119,13 +130,9 @@ export const TransitionDefault: {
119
130
  timingFunction: string;
120
131
  delay: string;
121
132
  };
122
- /** Default transition duration — 200ms flow rail. */
123
- export const TransitionDuration: string;
124
- /** ease-out keyword form (CSS-friendly). Equivalent to cubic-bezier(0,0,0.2,1). */
125
- export const TransitionEasing: string;
126
- /** Dark-mode brand primary — visible against dark surfaces (uses --blue-9 = nebutra-blue-400). */
133
+ /** Dark-mode brand primary — the identity blue lifted to nebutra-blue-400 so it stays visible on dark surfaces. This is the identity alias, not the functional fill: the dark solid fill is --blue-9 (#396ae2, white label 4.85:1). The two are deliberately separate now that the VI hex is no longer pinned into ramp slot 9. */
127
134
  export const BrandPrimary: string;
128
- /** Dark-mode brand accent — visible against dark surfaces (uses --cyan-9 = nebutra-cyan-400). */
135
+ /** Dark-mode brand accent — nebutra-cyan-400 (L* 87.1). The functional bright fill is --cyan-9 (#0bf1c3, L* 85.41), the same hex in both modes; dark ink for it is --cyan-contrast at 10.35:1. */
129
136
  export const BrandAccent: string;
130
137
  export const BrandTertiary: string;
131
138
  /** Legacy alias of --primary (shadcn product blue). Prefer bg-primary / Button default. */
@@ -165,44 +172,77 @@ export const ScaleNeutral2: string;
165
172
  export const ScaleNeutral3: string;
166
173
  export const ScaleNeutral4: string;
167
174
  export const ScaleNeutral5: string;
175
+ /** subtle border — DERIVED: OKLab lerp step5 → step9 at t=0.25, chroma forced to 0. The achromatic result is deliberate and preserves the documented intent of color.nebutra-gray ('used where blue undertone clashes — primarily dark-mode borders, dividers, elevation hairlines'). What was broken was the LIGHTNESS: gray-900/800/700 are darker than the slate background tier they sit above, so the border read as a hole rather than a hairline. */
168
176
  export const ScaleNeutral6: string;
177
+ /** default border — DERIVED: OKLab lerp step5 → step9 at t=0.50, chroma 0. */
169
178
  export const ScaleNeutral7: string;
179
+ /** hovered border — DERIVED: OKLab lerp step5 → step9 at t=0.75, chroma 0. */
170
180
  export const ScaleNeutral8: string;
171
181
  export const ScaleNeutral9: string;
172
182
  export const ScaleNeutral10: string;
173
183
  export const ScaleNeutral11: string;
174
184
  export const ScaleNeutral12: string;
185
+ /** app tint — L* 13.59, C 0.031, hue 264. */
175
186
  export const ScaleBlue1: string;
187
+ /** subtle background — L* 17.43, C 0.048. */
176
188
  export const ScaleBlue2: string;
189
+ /** component background default — L* 22.04, C 0.071. */
177
190
  export const ScaleBlue3: string;
191
+ /** component background hover — L* 26.99, C 0.095. */
178
192
  export const ScaleBlue4: string;
193
+ /** component background active — L* 32.46, C 0.118. Anchor for the derived border tier. */
179
194
  export const ScaleBlue5: string;
195
+ /** subtle border — DERIVED at build time (scripts/derive-border-tier.mjs): OKLab lerp of step 5 toward step9 (deep scale, span 23.5 L*) at t=0.25. The value here is a placeholder anchor only; the preprocessor overwrites it. Lands at L* 38.25, C 0.136. */
180
196
  export const ScaleBlue6: string;
197
+ /** default border — DERIVED at build time (scripts/derive-border-tier.mjs): OKLab lerp of step 5 toward step9 (deep scale, span 23.5 L*) at t=0.50. The value here is a placeholder anchor only; the preprocessor overwrites it. Lands at L* 44.21, C 0.155. */
181
198
  export const ScaleBlue7: string;
199
+ /** hovered border — DERIVED at build time (scripts/derive-border-tier.mjs): OKLab lerp of step 5 toward step9 (deep scale, span 23.5 L*) at t=0.75. The value here is a placeholder anchor only; the preprocessor overwrites it. Lands at L* 50.01, C 0.173. */
182
200
  export const ScaleBlue8: string;
201
+ /** solid fill — L* 55.92, C 0.191, hue 264.3. White label 4.85:1. Same value as the dark shadcn --primary, so light and dark both take their deep fill from one source. Chroma ceiling for dark is 0.190; this is 0.191. */
183
202
  export const ScaleBlue9: string;
203
+ /** solid fill hover — L* 57.44, C 0.183. White label 4.53:1. The hover has to move UP in a dark ramp, which costs contrast, so the step is deliberately small (1.52 L*) to keep white above 4.5:1. */
184
204
  export const ScaleBlue10: string;
205
+ /** secondary text — L* 74.01, C 0.106. 8.62:1 on step 1. */
185
206
  export const ScaleBlue11: string;
207
+ /** primary text — L* 90.52, C 0.043. 15.08:1 on step 1. */
186
208
  export const ScaleBlue12: string;
209
+ /** Label ink for the solid fill tier. Absolute value, identical in both modes. 4.85:1 on step 9, 4.53:1 on step 10. */
210
+ export const ScaleBlueContrast: string;
211
+ /** app tint — L* 15.90, C 0.021, hue 172. */
187
212
  export const ScaleCyan1: string;
213
+ /** subtle background — L* 21.54, C 0.030. */
188
214
  export const ScaleCyan2: string;
215
+ /** component background default — L* 27.46, C 0.041. */
189
216
  export const ScaleCyan3: string;
217
+ /** component background hover — L* 34.10, C 0.046. */
190
218
  export const ScaleCyan4: string;
219
+ /** component background active — L* 40.88, C 0.050. Anchor for the derived border tier. */
191
220
  export const ScaleCyan5: string;
221
+ /** subtle border — DERIVED at build time (scripts/derive-border-tier.mjs): OKLab lerp of step 5 toward step9 (span 44.5 L*) at t=0.25. The value here is a placeholder anchor only; the preprocessor overwrites it. Lands at L* 52.12, C 0.079. */
192
222
  export const ScaleCyan6: string;
223
+ /** default border — DERIVED at build time (scripts/derive-border-tier.mjs): OKLab lerp of step 5 toward step9 (span 44.5 L*) at t=0.50. The value here is a placeholder anchor only; the preprocessor overwrites it. Lands at L* 63.04, C 0.107. */
193
224
  export const ScaleCyan7: string;
225
+ /** hovered border — DERIVED at build time (scripts/derive-border-tier.mjs): OKLab lerp of step 5 toward step9 (span 44.5 L*) at t=0.75. The value here is a placeholder anchor only; the preprocessor overwrites it. Lands at L* 74.30, C 0.136. */
194
226
  export const ScaleCyan8: string;
227
+ /** solid fill — same bright value as light mode, the way Radix ships one hex for mint-9 in both modes: L* 85.41, C 0.164. Ink 10.35:1 against --cyan-contrast. */
195
228
  export const ScaleCyan9: string;
229
+ /** solid fill hover — L* 88.53, C 0.145, 3.12 L* above step 9 (Radix mint dark moves up 4.60 L*). Ink 11.34:1. */
196
230
  export const ScaleCyan10: string;
231
+ /** secondary text — L* 91.46, C 0.110. 15.68:1 on step 1. */
197
232
  export const ScaleCyan11: string;
233
+ /** primary text — L* 94.54, C 0.070. 16.95:1 on step 1. */
198
234
  export const ScaleCyan12: string;
235
+ /** Label ink for the bright fill tier. Absolute near-black, identical in both modes. 10.35:1 on step 9, 11.34:1 on step 10. */
236
+ export const ScaleCyanContrast: string;
199
237
  export const ShadcnBackground: string;
200
238
  export const ShadcnForeground: string;
201
239
  export const ShadcnCard: string;
202
240
  export const ShadcnCardForeground: string;
203
241
  export const ShadcnPopover: string;
204
242
  export const ShadcnPopoverForeground: string;
243
+ /** Dark-mode action blue, paired with the near-black --primary-foreground, not white. #396ae2 keeps the VI hue and sits at L*55.9 C0.191. */
205
244
  export const ShadcnPrimary: string;
245
+ /** White, matching light mode and matching --blue-contrast. It was near-black (222 14% 9%) when --primary was a LIGHT fill at L* 68.3, where dark ink read 6.20:1. Once --primary became a deep fill at L* 55.9 the pairing inverted and measured 3.74:1, below AA — the fill moved and the ink did not. The deep-fill tier takes white in both modes; --blue-contrast says the same thing, and they must agree because --primary and --blue-9 are now the same value. */
206
246
  export const ShadcnPrimaryForeground: string;
207
247
  export const ShadcnSecondary: string;
208
248
  export const ShadcnSecondaryForeground: string;
@@ -212,10 +252,16 @@ export const ShadcnAccent: string;
212
252
  export const ShadcnAccentForeground: string;
213
253
  export const ShadcnDestructive: string;
214
254
  export const ShadcnDestructiveForeground: string;
255
+ /** Red as FOREGROUND on a dark surface. --destructive (0 63% 38%) is 2.15:1 on --card here — a fill only. Lightened to 5.18:1 on --card / 5.61:1 on --neutral-1, which sits alongside the light-mode 5.42:1 so red reads with the same weight in both themes. Use --destructive for fills with --destructive-foreground on top; use this for red text and icons. */
256
+ export const ShadcnDestructiveStrong: string;
215
257
  export const ShadcnSuccess: string;
216
258
  export const ShadcnSuccessForeground: string;
259
+ /** Green as foreground on a dark surface. Needs no adjustment — 142 60% 42% is already 4.83:1 as ink on its own 10% tint — so it deliberately equals --success, matching how --warning-strong behaves in this theme. */
260
+ export const ShadcnSuccessStrong: string;
217
261
  export const ShadcnWarning: string;
218
262
  export const ShadcnWarningForeground: string;
263
+ /** Amber as foreground on a dark surface. Unlike light mode this needs no adjustment — 38 80% 52% is already 7.98:1 against --neutral-1 — so it deliberately equals --warning. The token exists in both themes so consumers can reference one name. */
264
+ export const ShadcnWarningStrong: string;
219
265
  export const ShadcnInfo: string;
220
266
  export const ShadcnInfoForeground: string;
221
267
  export const ShadcnBorder: string;
@@ -275,3 +321,27 @@ export const ElevationXl: string;
275
321
  export const Elevation2xl: string;
276
322
  export const ElevationBrand: string;
277
323
  export const ElevationBrandLg: string;
324
+ /** Ambient elevation, small. Contact layer plus a wide soft pool — the marketing-surface counterpart to the tight xs..2xl product ramp. */
325
+ export const ElevationAmbientSm: string;
326
+ /** Ambient elevation, medium. Default resting depth for a floating marketing card. */
327
+ export const ElevationAmbientMd: string;
328
+ /** Ambient elevation, large. One step up from md; use for hover of a md surface, not as a resting default. */
329
+ export const ElevationAmbientLg: string;
330
+ /** Ambient-sm plus a lit top edge, for translucent panels over a blurred backdrop. */
331
+ export const ElevationGlassSm: string;
332
+ /** Ambient-md plus a lit top edge. */
333
+ export const ElevationGlassMd: string;
334
+ /** Ambient-lg plus a lit top edge. */
335
+ export const ElevationGlassLg: string;
336
+ /** Top-edge sheen for solid inverted fills (bg-foreground). Lifts with light on a dark fill, with shade on a light one. */
337
+ export const ElevationSheen: string;
338
+ /** Centred offsetless halo — the only non-directional step on the ramp. Inverted from the light value: a black halo has nothing to darken against a dark surround, so the halo becomes light. Keep the alpha low; this is separation, not a bloom. */
339
+ export const ElevationAmbientGlow: string;
340
+ /** Identical to the light value by design. The pool is theme-invariant black because glow-accent surfaces are fixed dark glass in both themes; only the accent halo shifts, via --brand-accent. */
341
+ export const ElevationGlowAccent: string;
342
+ /** Hover escalation of glow-accent. Identical to the light value by design. */
343
+ export const ElevationGlowAccentLg: string;
344
+ /** Accent halo alone, no pool. Identical to the light value by design. */
345
+ export const ElevationGlowAccentSm: string;
346
+ /** xl geometry tinted with the action fill at 5 percent. Same reference as light; --primary carries the dark channels. */
347
+ export const ElevationGlowPrimary: string;