@aziontech/theme 5.2.1 → 5.2.2
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/dist/v4/globals.css +2 -2
- package/dist/v4/globals.scss +2 -2
- package/package.json +1 -1
- package/src/scripts/build-tokens.mjs +1 -121
- package/src/scripts/compile-primitives.js +0 -18
- package/src/scripts/compile-theme.js +0 -10
- package/src/scripts/refs.d.ts.map +1 -1
- package/src/scripts/refs.js +0 -9
- package/src/scripts/zero-unit.mjs +0 -19
- package/src/tokens/README.md +0 -7
- package/src/tokens/index.js +0 -4
- package/src/tokens/primitives/animations/animate.d.ts.map +1 -1
- package/src/tokens/primitives/animations/animate.js +0 -2
- package/src/tokens/primitives/animations/keyframes.d.ts +0 -5
- package/src/tokens/primitives/animations/keyframes.d.ts.map +1 -1
- package/src/tokens/primitives/animations/keyframes.js +0 -25
- package/src/tokens/primitives/colors/colors.js +0 -5
- package/src/tokens/primitives/shape/container.d.ts.map +1 -1
- package/src/tokens/primitives/shape/container.js +13 -30
- package/src/tokens/primitives/typography/tracking.js +0 -6
- package/src/tokens/semantic/colors.js +0 -21
- package/src/tokens/semantic/containers.d.ts.map +1 -1
- package/src/tokens/semantic/containers.data.d.ts +0 -10
- package/src/tokens/semantic/containers.data.d.ts.map +1 -1
- package/src/tokens/semantic/containers.data.js +0 -11
- package/src/tokens/semantic/containers.js +1 -7
- package/src/tokens/semantic/layouts.data.d.ts +0 -15
- package/src/tokens/semantic/layouts.data.d.ts.map +1 -1
- package/src/tokens/semantic/layouts.data.js +10 -265
- package/src/tokens/semantic/spacings.data.d.ts +0 -6
- package/src/tokens/semantic/spacings.data.d.ts.map +1 -1
- package/src/tokens/semantic/spacings.data.js +0 -7
- package/src/tokens/semantic/texts.data.d.ts +0 -1
- package/src/tokens/semantic/texts.data.d.ts.map +1 -1
- package/src/tokens/semantic/texts.data.js +0 -48
- package/src/tokens/semantic/z-indices.data.d.ts +0 -22
- package/src/tokens/semantic/z-indices.data.d.ts.map +1 -1
- package/src/tokens/semantic/z-indices.data.js +0 -23
- package/src/tokens/theme/accent.js +0 -12
- package/src/tokens/theme/background.js +0 -5
- package/src/tokens/theme/border.js +0 -22
- package/src/tokens/theme/code-sintax.js +0 -4
- package/src/tokens/theme/text.js +1 -1
- package/src/scripts/measure-comment.mjs +0 -47
package/dist/v4/globals.css
CHANGED
|
@@ -1066,7 +1066,7 @@
|
|
|
1066
1066
|
--border-strong: #FFFFFF;
|
|
1067
1067
|
--border-selected: #F3652B;
|
|
1068
1068
|
--text-default: #FAFAFA;
|
|
1069
|
-
--text-muted: #
|
|
1069
|
+
--text-muted: #999999;
|
|
1070
1070
|
--text-disabled: #4D4D4D;
|
|
1071
1071
|
--text-link: #3392FF;
|
|
1072
1072
|
--text-link-hover: #66ADFF;
|
|
@@ -1101,7 +1101,7 @@
|
|
|
1101
1101
|
--illustration-line-strong: #4D4D4D;
|
|
1102
1102
|
--illustration-highlight: #FFFFFF;
|
|
1103
1103
|
--illustration-ink: #FAFAFA;
|
|
1104
|
-
--illustration-ink-muted: #
|
|
1104
|
+
--illustration-ink-muted: #999999;
|
|
1105
1105
|
--illustration-primary: #F3652B;
|
|
1106
1106
|
--illustration-accent: #0072F5;
|
|
1107
1107
|
--illustration-code-punctuation: #999999;
|
package/dist/v4/globals.scss
CHANGED
|
@@ -1066,7 +1066,7 @@
|
|
|
1066
1066
|
--border-strong: #FFFFFF;
|
|
1067
1067
|
--border-selected: #F3652B;
|
|
1068
1068
|
--text-default: #FAFAFA;
|
|
1069
|
-
--text-muted: #
|
|
1069
|
+
--text-muted: #999999;
|
|
1070
1070
|
--text-disabled: #4D4D4D;
|
|
1071
1071
|
--text-link: #3392FF;
|
|
1072
1072
|
--text-link-hover: #66ADFF;
|
|
@@ -1101,7 +1101,7 @@
|
|
|
1101
1101
|
--illustration-line-strong: #4D4D4D;
|
|
1102
1102
|
--illustration-highlight: #FFFFFF;
|
|
1103
1103
|
--illustration-ink: #FAFAFA;
|
|
1104
|
-
--illustration-ink-muted: #
|
|
1104
|
+
--illustration-ink-muted: #999999;
|
|
1105
1105
|
--illustration-primary: #F3652B;
|
|
1106
1106
|
--illustration-accent: #0072F5;
|
|
1107
1107
|
--illustration-code-punctuation: #999999;
|
package/package.json
CHANGED
|
@@ -1,30 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Build design tokens into a Tailwind v4 stylesheet.
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
* node build-tokens.mjs
|
|
7
|
-
*
|
|
8
|
-
* Output:
|
|
9
|
-
* - dist/v4/globals.css @import "tailwindcss" + @theme + :root @media + @keyframes
|
|
10
|
-
* - dist/v4/globals.scss identical bytes, .scss extension
|
|
11
|
-
*
|
|
12
|
-
* Inputs:
|
|
13
|
-
* - `tokens/primitives/**` declarative primitives (colors, spacings,
|
|
14
|
-
* typography, breakpoints, animations, …)
|
|
15
|
-
* - `tokens/semantic/{containers,spacings,texts}.data.js`
|
|
16
|
-
* responsive-shaped semantic tokens
|
|
17
|
-
* - `tokens/semantic/layouts.data.js`
|
|
18
|
-
* layout tokens (all derived from --spacing-* /
|
|
19
|
-
* --container-*) + the `@utility` blocks that
|
|
20
|
-
* build the container system on them
|
|
21
|
-
* - `tokens/primitives/animations/{animate,keyframes}.js`
|
|
22
|
-
* animation utilities (`--animate-*`) + `@keyframes`
|
|
23
|
-
* definitions + extra CSS (transform-origin) for
|
|
24
|
-
* popup-scale-*.
|
|
25
|
-
*
|
|
26
|
-
* No external deps — node:fs/promises, node:path, node:url only.
|
|
27
|
-
*/
|
|
28
2
|
|
|
29
3
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
30
4
|
import { dirname, resolve } from 'node:path';
|
|
@@ -35,24 +9,19 @@ import { animateExtras, keyframes } from '../tokens/primitives/animations/keyfra
|
|
|
35
9
|
import { breakpoints } from '../tokens/primitives/breakpoints.js';
|
|
36
10
|
import { compilePrimitivesVars } from './compile-primitives.js';
|
|
37
11
|
import { compileThemeCss, compileThemeVars } from './compile-theme.js';
|
|
38
|
-
import { container } from '../tokens/primitives/shape/container.js';
|
|
39
12
|
import { containersData } from '../tokens/semantic/containers.data.js';
|
|
40
13
|
import { layoutsData, layoutsUtilities } from '../tokens/semantic/layouts.data.js';
|
|
41
14
|
import { spacingsData } from '../tokens/semantic/spacings.data.js';
|
|
42
15
|
import { textsData } from '../tokens/semantic/texts.data.js';
|
|
43
16
|
import { zIndicesData } from '../tokens/semantic/z-indices.data.js';
|
|
44
|
-
import { assertMeasureCommentsMatch } from './measure-comment.mjs';
|
|
45
17
|
import { assertNoZeroWithUnit } from './zero-unit.mjs';
|
|
46
18
|
|
|
47
19
|
const BREAKPOINT_ORDER = ['sm', 'md', 'lg', 'xl', '2xl'];
|
|
48
20
|
|
|
49
21
|
const kebab = (s) => s.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
50
22
|
|
|
51
|
-
// ─── 1. Primitives ──────────────────────────────────────────────────────────
|
|
52
|
-
// compilePrimitivesVars throws on any unresolved tokenRef (see refs.js).
|
|
53
23
|
const flattenPrimitives = () => compilePrimitivesVars();
|
|
54
24
|
|
|
55
|
-
// ─── 2. Semantic flattening ─────────────────────────────────────────────────
|
|
56
25
|
const splitResponsive = (value) => {
|
|
57
26
|
if (value === null || typeof value !== 'object') return { _: String(value) };
|
|
58
27
|
const out = {};
|
|
@@ -103,18 +72,11 @@ const buildFlatModel = () => ({
|
|
|
103
72
|
texts: flattenBundle(textsData),
|
|
104
73
|
});
|
|
105
74
|
|
|
106
|
-
// ─── 3. Formatting helpers ─────────────────────────────────────────────────
|
|
107
75
|
const formatVars = (vars, indent) =>
|
|
108
76
|
Object.entries(vars)
|
|
109
77
|
.map(([k, v]) => `${indent}${k}: ${v};`)
|
|
110
78
|
.join('\n');
|
|
111
79
|
|
|
112
|
-
/**
|
|
113
|
-
* Container / spacing / animation-extra classes — emitted inside `@layer components`.
|
|
114
|
-
* These are used bare (never behind Tailwind variants), so component-layer is fine.
|
|
115
|
-
* Typography classes are NOT here; they ship as `@utility` (see emitTextUtilities)
|
|
116
|
-
* so that variant modifiers like `data-[size=medium]:text-button-md` compile.
|
|
117
|
-
*/
|
|
118
80
|
const emitComponentClasses = (indent = ' ') => {
|
|
119
81
|
const lines = [];
|
|
120
82
|
|
|
@@ -142,12 +104,6 @@ const emitComponentClasses = (indent = ' ') => {
|
|
|
142
104
|
return lines.join('\n');
|
|
143
105
|
};
|
|
144
106
|
|
|
145
|
-
/**
|
|
146
|
-
* Emit typography classes as Tailwind v4 `@utility` blocks so they participate
|
|
147
|
-
* in variant compilation (`data-[size=medium]:text-button-md`, `hover:text-link`,
|
|
148
|
-
* etc.). `@layer components` classes are opaque to v4's variant resolver and
|
|
149
|
-
* their modifiers silently drop, leaving elements at the inherited 16px.
|
|
150
|
-
*/
|
|
151
107
|
const emitTextUtilities = () => {
|
|
152
108
|
const blocks = [];
|
|
153
109
|
for (const [key, bundle] of Object.entries(textsData)) {
|
|
@@ -173,26 +129,6 @@ const emitTextUtilities = () => {
|
|
|
173
129
|
return blocks.join('\n\n');
|
|
174
130
|
};
|
|
175
131
|
|
|
176
|
-
/**
|
|
177
|
-
* Emit semantic color utilities (`text-*`, `bg-*`, `border-*`, `ring-*`).
|
|
178
|
-
*
|
|
179
|
-
* Tailwind v4's auto-generated color utilities pull from `@theme { --color-* }`,
|
|
180
|
-
* but our semantic tokens live under domain-specific prefixes (`--text-default`,
|
|
181
|
-
* `--bg-canvas`, `--border-default`, `--primary`) so v3's preset generated the
|
|
182
|
-
* classes by axis instead. Without them, `text-primary`, `bg-surface`, and
|
|
183
|
-
* `border-default` (heavily used across the webkit components — unchanged
|
|
184
|
-
* from dev) compile to nothing under v4.
|
|
185
|
-
*
|
|
186
|
-
* Rules:
|
|
187
|
-
* - Prefix-keyed tokens (`bg-*`, `text-*`, `border-*`, `ring-*`) become one
|
|
188
|
-
* utility on the matching axis: `@utility bg-canvas { background-color: var(--bg-canvas); }`.
|
|
189
|
-
* - Bare semantic tokens (`primary`, `accent`, `danger`, `warning`, `success`,
|
|
190
|
-
* `info`, `secondary`, and their `-mask`/`-selected`/`-contrast`/`-border`
|
|
191
|
-
* suffixes) become three utilities so a consumer can use `bg-primary`,
|
|
192
|
-
* `text-primary`, `border-primary` interchangeably.
|
|
193
|
-
* - `code-sintax-*` tokens are consumer-composed via arbitrary values in code
|
|
194
|
-
* highlighters and don't need a utility (skipped).
|
|
195
|
-
*/
|
|
196
132
|
const AXIS_BY_PREFIX = {
|
|
197
133
|
'bg-': { utility: (k) => k, prop: 'background-color' },
|
|
198
134
|
'text-': { utility: (k) => k, prop: 'color' },
|
|
@@ -207,9 +143,6 @@ const emitSemanticColorUtilities = () => {
|
|
|
207
143
|
const { light } = compileThemeVars();
|
|
208
144
|
const keys = Object.keys(light).map((k) => k.replace(/^--/, ''));
|
|
209
145
|
const blocks = [];
|
|
210
|
-
// Skip utilities already defined as typography (textsData) — `text-link`
|
|
211
|
-
// there ships the hover/focus states and would be silently overridden by
|
|
212
|
-
// a bare color-only utility emitted afterwards.
|
|
213
146
|
const emitted = new Set(Object.keys(textsData));
|
|
214
147
|
|
|
215
148
|
for (const key of keys) {
|
|
@@ -225,9 +158,8 @@ const emitSemanticColorUtilities = () => {
|
|
|
225
158
|
blocks.push(`@utility ${utility} { ${axis.prop}: var(--${key}); }`);
|
|
226
159
|
continue;
|
|
227
160
|
}
|
|
228
|
-
// Bare token — expose on all three color axes.
|
|
229
161
|
for (const [prefix, axis] of Object.entries(AXIS_BY_PREFIX)) {
|
|
230
|
-
if (prefix === 'ring-') continue;
|
|
162
|
+
if (prefix === 'ring-') continue;
|
|
231
163
|
const utility = `${prefix}${key}`;
|
|
232
164
|
if (emitted.has(utility)) continue;
|
|
233
165
|
emitted.add(utility);
|
|
@@ -237,17 +169,6 @@ const emitSemanticColorUtilities = () => {
|
|
|
237
169
|
return blocks.join('\n');
|
|
238
170
|
};
|
|
239
171
|
|
|
240
|
-
/**
|
|
241
|
-
* Restore browser affordances that Tailwind v4's preflight removed.
|
|
242
|
-
* v3 shipped `button { cursor: pointer }` by default; v4 does not, so every
|
|
243
|
-
* interactive element loses the hand cursor unless a component overrides it.
|
|
244
|
-
* Disabled controls keep the default cursor.
|
|
245
|
-
*/
|
|
246
|
-
/**
|
|
247
|
-
* Emit a map of `@utility` blocks. A string value is a plain declaration; an object
|
|
248
|
-
* value is a nested rule keyed by a literal selector (`&:first-child { … }`), the way
|
|
249
|
-
* the typography utilities nest their `&:hover`.
|
|
250
|
-
*/
|
|
251
172
|
const emitUtilities = (utilities) =>
|
|
252
173
|
Object.entries(utilities)
|
|
253
174
|
.map(([name, decls]) => {
|
|
@@ -262,12 +183,6 @@ const emitUtilities = (utilities) =>
|
|
|
262
183
|
})
|
|
263
184
|
.join('\n\n');
|
|
264
185
|
|
|
265
|
-
/**
|
|
266
|
-
* The container system as `@utility` blocks — same reason as the typography
|
|
267
|
-
* utilities: `@layer components` classes are opaque to the variant resolver, and a
|
|
268
|
-
* layout class is exactly the kind a consumer wants behind a variant
|
|
269
|
-
* (`md:layout-column`).
|
|
270
|
-
*/
|
|
271
186
|
const emitLayoutUtilities = () => emitUtilities(layoutsUtilities);
|
|
272
187
|
|
|
273
188
|
const emitBaseLayer = () =>
|
|
@@ -286,7 +201,6 @@ const emitBaseLayer = () =>
|
|
|
286
201
|
'}',
|
|
287
202
|
].join('\n');
|
|
288
203
|
|
|
289
|
-
/** Emit `@keyframes` blocks at the top level of the stylesheet. */
|
|
290
204
|
const emitKeyframes = () => {
|
|
291
205
|
const blocks = [];
|
|
292
206
|
for (const [name, steps] of Object.entries(keyframes)) {
|
|
@@ -298,24 +212,6 @@ const emitKeyframes = () => {
|
|
|
298
212
|
return blocks.join('\n\n');
|
|
299
213
|
};
|
|
300
214
|
|
|
301
|
-
// ─── 4. v4 emission (@import "tailwindcss" + @theme) ───────────────────────
|
|
302
|
-
/**
|
|
303
|
-
* v4 puts color primitives, breakpoints, and animation shorthands under
|
|
304
|
-
* `@theme` so Tailwind auto-generates `bg-gray-50`, `text-violet-500`,
|
|
305
|
-
* `sm:` screens, and `animate-*` utilities. Semantic tokens stay in plain
|
|
306
|
-
* `:root` (with `@media` overrides) so we keep full control of the
|
|
307
|
-
* component classes.
|
|
308
|
-
*
|
|
309
|
-
* Notes:
|
|
310
|
-
* - `@theme { --color-* }` → color utilities.
|
|
311
|
-
* - `@theme { --breakpoint-* }` → screens (`sm:`, `md:`, …).
|
|
312
|
-
* - `@theme { --animate-* }` → `animate-*` utilities (the shorthand
|
|
313
|
-
* references a `@keyframes` emitted
|
|
314
|
-
* later in the file).
|
|
315
|
-
* - Semantic shape/typography tokens are NOT in @theme — we own their
|
|
316
|
-
* class definitions in @layer components and they swap responsively
|
|
317
|
-
* via `:root @media` overrides.
|
|
318
|
-
*/
|
|
319
215
|
const V4_SELECTOR = ':root, [data-theme=light], .azion.azion-light';
|
|
320
216
|
|
|
321
217
|
const emitCssV4 = () => {
|
|
@@ -333,12 +229,6 @@ const emitCssV4 = () => {
|
|
|
333
229
|
themeVars[`--animate-${name}`] = shorthand;
|
|
334
230
|
}
|
|
335
231
|
|
|
336
|
-
// Named `duration-*` / `ease-*` utilities. Without these the design system's
|
|
337
|
-
// own `duration-moderate-02` / `ease-productive-entrance` classes compile to
|
|
338
|
-
// NOTHING (Tailwind v4 silently drops an unknown named step), and every
|
|
339
|
-
// component that declares one falls back to Tailwind's default 150ms `ease`.
|
|
340
|
-
// The namespaces are fixed by Tailwind: `--transition-duration-*` backs
|
|
341
|
-
// `duration-*`, `--ease-*` backs `ease-*`.
|
|
342
232
|
for (const [name, value] of Object.entries(duration)) {
|
|
343
233
|
themeVars[`--transition-duration-${name}`] = value;
|
|
344
234
|
}
|
|
@@ -418,7 +308,6 @@ const emitCssV4 = () => {
|
|
|
418
308
|
].join('\n');
|
|
419
309
|
};
|
|
420
310
|
|
|
421
|
-
// ─── 5. Write to disk ──────────────────────────────────────────────────────
|
|
422
311
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
423
312
|
const distRoot = resolve(__dirname, '../../dist');
|
|
424
313
|
|
|
@@ -429,21 +318,12 @@ const fontsCss = await readFile(
|
|
|
429
318
|
|
|
430
319
|
const dir = resolve(distRoot, 'v4');
|
|
431
320
|
await mkdir(dir, { recursive: true });
|
|
432
|
-
// `@import` must precede every other at-rule (CSS spec); `@font-face` before
|
|
433
|
-
// `@import "tailwindcss"` would silently invalidate the import and skip
|
|
434
|
-
// Tailwind's layer setup / utility generation. Splice fonts in AFTER the
|
|
435
|
-
// import line by looking for the marker in the emitted CSS.
|
|
436
321
|
const rawCss = emitCssV4();
|
|
437
322
|
const IMPORT_LINE = '@import "tailwindcss";';
|
|
438
323
|
const importIdx = rawCss.indexOf(IMPORT_LINE);
|
|
439
324
|
if (importIdx === -1) throw new Error('emitCssV4 output is missing the tailwind import line');
|
|
440
325
|
const afterImport = importIdx + IMPORT_LINE.length;
|
|
441
326
|
const css = `${rawCss.slice(0, afterImport)}\n\n${fontsCss}${rawCss.slice(afterImport)}`;
|
|
442
|
-
assertMeasureCommentsMatch(
|
|
443
|
-
await readFile(resolve(__dirname, '../tokens/semantic/layouts.data.js'), 'utf8'),
|
|
444
|
-
container,
|
|
445
|
-
'tokens/semantic/layouts.data.js',
|
|
446
|
-
);
|
|
447
327
|
assertNoZeroWithUnit(css, 'globals.css');
|
|
448
328
|
await writeFile(resolve(dir, 'globals.css'), css, 'utf8');
|
|
449
329
|
await writeFile(resolve(dir, 'globals.scss'), css, 'utf8');
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compile all primitives into a single CSS variables stylesheet.
|
|
3
|
-
*
|
|
4
|
-
* Imports every primitive module (colors, shape, typography, effects,
|
|
5
|
-
* breakpoints, border-widths, ring-offset), resolves `tokenRef(...)` aliases,
|
|
6
|
-
* and produces a `:root { ... }` block. Mirrors `injectThemeCss` (compile-theme.js)
|
|
7
|
-
* but for primitives only — no semantic light/dark split.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
1
|
import { animate } from '../tokens/primitives/animations/animate.js'
|
|
11
2
|
import { ease } from '../tokens/primitives/animations/ease.js'
|
|
12
3
|
import { borderWidths } from '../tokens/primitives/border-widths.js'
|
|
@@ -35,13 +26,6 @@ import { lineHeight } from '../tokens/primitives/typography/line-height.js'
|
|
|
35
26
|
import { tracking } from '../tokens/primitives/typography/tracking.js'
|
|
36
27
|
import { assertResolvedRefs, isTokenRef } from './refs.js'
|
|
37
28
|
|
|
38
|
-
/**
|
|
39
|
-
* Returns two trees:
|
|
40
|
-
* - `refsTree`: deep structure preserved so `tokenRef('shape.container.X')`
|
|
41
|
-
* keeps resolving via path lookup.
|
|
42
|
-
* - `varsTree`: same data with the `shape` / `typography` / `effects`
|
|
43
|
-
* wrappers removed, so emitted CSS vars are flat (no group prefix).
|
|
44
|
-
*/
|
|
45
29
|
export const buildTrees = () => {
|
|
46
30
|
const { brand, ...restColors } = colorPrimitives
|
|
47
31
|
const color = {
|
|
@@ -116,8 +100,6 @@ const resolveRef = (refPath, refsTree) => {
|
|
|
116
100
|
return null
|
|
117
101
|
}
|
|
118
102
|
|
|
119
|
-
// A leaf key of `DEFAULT` collapses to the parent prefix (Tailwind convention),
|
|
120
|
-
// so `{ radius: { DEFAULT: '4px' } }` emits `--radius: 4px;`.
|
|
121
103
|
const varNameFor = (path) => {
|
|
122
104
|
const segments = path[path.length - 1] === 'DEFAULT' ? path.slice(0, -1) : path
|
|
123
105
|
return `--${segments.join('-')}`
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compile semantic theme tokens into a light/dark CSS variables stylesheet.
|
|
3
|
-
*
|
|
4
|
-
* Resolves `tokenRef(...)` aliases from `tokens/theme/*` (primary, secondary,
|
|
5
|
-
* accent, surfaces, background, border, text, ring, code-sintax, feedback/*)
|
|
6
|
-
* against the
|
|
7
|
-
* primitives + brand + (pre-resolved) surfaces. Emits two blocks (light + dark).
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
1
|
import {
|
|
11
2
|
brandPrimitives,
|
|
12
3
|
primitives as colorPrimitives
|
|
@@ -89,7 +80,6 @@ const resolveGroup = (group, surfacesResolved, variant, unresolved, semanticReso
|
|
|
89
80
|
}
|
|
90
81
|
|
|
91
82
|
const compileVariant = (variant, unresolved) => {
|
|
92
|
-
// Surfaces resolved first — other groups depend on them.
|
|
93
83
|
const surfacesResolved = {}
|
|
94
84
|
Object.entries(surfaces[variant]).forEach(([key, value]) => {
|
|
95
85
|
if (!isTokenRef(value)) return
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refs.d.ts","sourceRoot":"","sources":["refs.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"refs.d.ts","sourceRoot":"","sources":["refs.js"],"names":[],"mappings":"AAAO;;EAA4C;AAE5C,gDAA6F;AAE7F,wEAIN"}
|
package/src/scripts/refs.js
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Token reference helpers.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
1
|
export const tokenRef = (path) => ({ __ref: path })
|
|
6
2
|
|
|
7
3
|
export const isTokenRef = (value) => typeof value === 'object' && value !== null && '__ref' in value
|
|
8
4
|
|
|
9
|
-
/**
|
|
10
|
-
* Fail loudly on unresolved refs. A typo'd token must never silently vanish
|
|
11
|
-
* from the compiled CSS or ship as a raw `path.to.token` string — the compilers
|
|
12
|
-
* collect every miss and this throws once with the full list.
|
|
13
|
-
*/
|
|
14
5
|
export const assertResolvedRefs = (context, unresolved) => {
|
|
15
6
|
if (unresolved.length === 0) return
|
|
16
7
|
const lines = unresolved.map((entry) => ` ${entry}`).join('\n')
|
|
@@ -1,31 +1,14 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Zero-with-unit gate for the compiled token stylesheet — the only check that sees token
|
|
3
|
-
* values (authored in JS, so no linter does), run on the final CSS before globals.css is
|
|
4
|
-
* written. A zero length is `0`; inside calc()/min()/max()/clamp() it must carry a unit, and
|
|
5
|
-
* that unit is `rem` (.claude/rules/styling.md). Mirror of the zero checks in packages/webkit
|
|
6
|
-
* token-checks.js, kept in sync — LENGTH_UNITS is the same string. Pure: node built-ins only.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
// Opens a math function; balances parens one level deep (a zero nested deeper falls back to
|
|
10
|
-
// the bare-zero check).
|
|
11
1
|
const MATH_FN = '(?:calc|min|max|clamp)\\((?:[^()]|\\([^()]*\\))*';
|
|
12
2
|
|
|
13
|
-
// Complete CSS length-unit set — must be complete, since a missing unit silently passes.
|
|
14
3
|
export const LENGTH_UNITS =
|
|
15
4
|
'px|rem|em|ex|rex|ch|rch|cap|rcap|ic|ric|lh|rlh|vw|vh|vi|vb|vmin|vmax|svw|svh|svi|svb|svmin|svmax|lvw|lvh|lvi|lvb|lvmin|lvmax|dvw|dvh|dvi|dvb|dvmin|dvmax|cqw|cqh|cqi|cqb|cqmin|cqmax|cm|mm|Q|in|pt|pc';
|
|
16
5
|
|
|
17
|
-
// Mutually exclusive, so a value is reported once. Non-global so `.test()` is stateless —
|
|
18
|
-
// findZeroMisuse adds `g` locally to enumerate matches.
|
|
19
6
|
export const ZERO_WITH_UNIT = new RegExp(`(?<![\\w.])(?<!${MATH_FN})0(?:${LENGTH_UNITS})(?![\\w%])`, 'i');
|
|
20
7
|
export const ZERO_UNIT_IN_MATH = new RegExp(
|
|
21
8
|
`(?<=${MATH_FN})(?<![\\w.])0(?!rem)(?:${LENGTH_UNITS})(?![\\w%])`,
|
|
22
9
|
'i',
|
|
23
10
|
);
|
|
24
11
|
|
|
25
|
-
/**
|
|
26
|
-
* Matches of `regex` in `cssText` as `{ line, n }`. Scans the whole string, not line-by-line,
|
|
27
|
-
* so a calc() wrapped across newlines is still seen as in-math.
|
|
28
|
-
*/
|
|
29
12
|
export const findZeroMisuse = (cssText, regex) => {
|
|
30
13
|
const scan = new RegExp(regex.source, `${regex.flags.replace('g', '')}g`);
|
|
31
14
|
const out = [];
|
|
@@ -38,10 +21,8 @@ export const findZeroMisuse = (cssText, regex) => {
|
|
|
38
21
|
return out;
|
|
39
22
|
};
|
|
40
23
|
|
|
41
|
-
// The `--custom-property` a line declares, to name the token to fix; null off a `--token:` line.
|
|
42
24
|
const tokenOf = (line) => line.match(/(--[\w-]+)\s*:/)?.[1] ?? null;
|
|
43
25
|
|
|
44
|
-
/** Throw if `cssText` misuses a zero length. `source` names the artifact in the message. */
|
|
45
26
|
export const assertNoZeroWithUnit = (cssText, source = 'globals.css') => {
|
|
46
27
|
const bare = findZeroMisuse(cssText, ZERO_WITH_UNIT);
|
|
47
28
|
const inMath = findZeroMisuse(cssText, ZERO_UNIT_IN_MATH);
|
package/src/tokens/README.md
CHANGED
|
@@ -118,7 +118,6 @@ src/
|
|
|
118
118
|
├── compile-primitives.js # flattens primitive trees into CSS vars
|
|
119
119
|
├── compile-theme.js # semantic light/dark compiler (exported as ./theme-colors)
|
|
120
120
|
├── zero-unit.mjs # build gate: a zero length carries no unit
|
|
121
|
-
├── measure-comment.mjs # build gate: a `// Npx` comment matches its rung
|
|
122
121
|
└── build-tokens.mjs # main entrypoint: emits the dist/v4 bundle
|
|
123
122
|
```
|
|
124
123
|
|
|
@@ -207,12 +206,6 @@ The group also ships `layoutsUtilities`, the container-system classes (`.layout-
|
|
|
207
206
|
(`md:layout-column`). Each entry is a rule body: a string value is a declaration, an object value is
|
|
208
207
|
a nested rule keyed by a literal selector (`'&:first-child'`).
|
|
209
208
|
|
|
210
|
-
A measure carries a `// 1620px` annotation for the reader, and **the token value is the source of
|
|
211
|
-
truth for it** — the comment is a convenience, never the decision. `measure-comment.mjs` resolves
|
|
212
|
-
every annotated `var(--container-*)` back to its rung and **fails the build** when the two disagree,
|
|
213
|
-
because nothing else can see this: the annotation is a JS comment, so it never reaches the compiled
|
|
214
|
-
CSS, and no linter resolves a `var()` to the value it names.
|
|
215
|
-
|
|
216
209
|
---
|
|
217
210
|
|
|
218
211
|
## 🔧 Building & consuming
|
package/src/tokens/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"animate.d.ts","sourceRoot":"","sources":["animate.js"],"names":[],"mappings":"AAAA;;;;;EAKC;AAED;;;;;;;;;EASC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"animate.d.ts","sourceRoot":"","sources":["animate.js"],"names":[],"mappings":"AAAA;;;;;EAKC;AAED;;;;;;;;;EASC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;EAyBC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;EAkCC"}
|
|
@@ -37,8 +37,6 @@ export const animate = {
|
|
|
37
37
|
'slide-out-right': `slideOutRight ${duration['moderate-01']} ${curve['productive-exit']}`,
|
|
38
38
|
'progress-indeterminate': `progressIndeterminate ${duration['slow-04']} ${curve['productive-entrance']} infinite`,
|
|
39
39
|
'progress-indeterminate-short': `progressIndeterminateShort ${duration['slow-04']} ${curve['expressive-entrance']} ${duration['slow-03']} infinite`,
|
|
40
|
-
// `linear` (not a curve token) for the same reason as spin/shimmer: an endlessly
|
|
41
|
-
// looping animation must not accelerate, or the seam between repeats is visible.
|
|
42
40
|
'flow-dash': `flowDash ${duration['slow-02']} linear infinite`,
|
|
43
41
|
'texture-wave-a': 'textureWaveA 13s linear infinite',
|
|
44
42
|
'texture-wave-b': 'textureWaveB 19s linear infinite',
|
|
@@ -81,11 +81,6 @@ export namespace keyframes {
|
|
|
81
81
|
'100%': string;
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
|
-
/**
|
|
85
|
-
* Utilities that need CSS properties beyond the `animation` shorthand
|
|
86
|
-
* emitted by Tailwind v4 from `--animate-*`. Serialized into
|
|
87
|
-
* `@layer components` in `dist/v4/globals.css`.
|
|
88
|
-
*/
|
|
89
84
|
export const animateExtras: {
|
|
90
85
|
'animate-popup-scale-in': {
|
|
91
86
|
'transform-origin': string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyframes.d.ts","sourceRoot":"","sources":["keyframes.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"keyframes.d.ts","sourceRoot":"","sources":["keyframes.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmFA;;;;;;;EAGC"}
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Raw `@keyframes` definitions used by `--animate-*` in `animate.js`.
|
|
3
|
-
*
|
|
4
|
-
* Consumed by `scripts/build-tokens.mjs` to emit real `@keyframes` blocks
|
|
5
|
-
* in the Tailwind v4 `dist/v4/globals.css` output. Tailwind v4 registers
|
|
6
|
-
* the utility via `@theme { --animate-<name>: ... }`, but does not
|
|
7
|
-
* generate the `@keyframes` — those live here.
|
|
8
|
-
*
|
|
9
|
-
* Values are plain CSS-style declarations (strings), not the camelCase
|
|
10
|
-
* object form used by the legacy v3 plugin — this way the build script
|
|
11
|
-
* can serialize them verbatim.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
1
|
export const keyframes = {
|
|
15
2
|
fadeIn: {
|
|
16
3
|
'0%': 'opacity: 0',
|
|
@@ -28,8 +15,6 @@ export const keyframes = {
|
|
|
28
15
|
'0%, 100%': 'opacity: 1',
|
|
29
16
|
'50%': 'opacity: 0'
|
|
30
17
|
},
|
|
31
|
-
// Holds the highlight for the first 40% of the run, then fades it back to
|
|
32
|
-
// normal over the remaining 60% — a row-flash, not a permanent tint.
|
|
33
18
|
highlight: {
|
|
34
19
|
'0%, 40%': 'background-color: var(--surface-hover); font-weight: 500',
|
|
35
20
|
'100%': 'background-color: transparent; font-weight: 400'
|
|
@@ -80,11 +65,6 @@ export const keyframes = {
|
|
|
80
65
|
'60%': 'inset-inline-start: 107%; inset-inline-end: -8%',
|
|
81
66
|
'100%': 'inset-inline-start: 107%; inset-inline-end: -8%'
|
|
82
67
|
},
|
|
83
|
-
// Marching dashes along an SVG stroke — the "flowing connection" of a node-based
|
|
84
|
-
// diagram. The travel distance is 24, so the loop is seamless for any
|
|
85
|
-
// `stroke-dasharray` whose cycle DIVIDES 24 (`4 4` = 8, `2 4` = 6, `8 4` = 12): the
|
|
86
|
-
// pattern lands exactly where it started. A cycle that does not divide 24 (`5 5` = 10)
|
|
87
|
-
// visibly jumps on repeat.
|
|
88
68
|
flowDash: {
|
|
89
69
|
'0%': 'stroke-dashoffset: 24',
|
|
90
70
|
'100%': 'stroke-dashoffset: 0'
|
|
@@ -101,11 +81,6 @@ export const keyframes = {
|
|
|
101
81
|
}
|
|
102
82
|
}
|
|
103
83
|
|
|
104
|
-
/**
|
|
105
|
-
* Utilities that need CSS properties beyond the `animation` shorthand
|
|
106
|
-
* emitted by Tailwind v4 from `--animate-*`. Serialized into
|
|
107
|
-
* `@layer components` in `dist/v4/globals.css`.
|
|
108
|
-
*/
|
|
109
84
|
export const animateExtras = {
|
|
110
85
|
'animate-popup-scale-in': { 'transform-origin': 'var(--popup-origin, center)' },
|
|
111
86
|
'animate-popup-scale-out': { 'transform-origin': 'var(--popup-origin, center)' }
|
|
@@ -21,11 +21,6 @@ export const primitives = {
|
|
|
21
21
|
900: '#001833',
|
|
22
22
|
950: '#000C1A'
|
|
23
23
|
},
|
|
24
|
-
// 250 / 750 / 775 fill the two widest gaps in the ramp so an OPAQUE neutral rule has a step
|
|
25
|
-
// to live on. The scale jumped 200 → 300 (229 → 178) and 700 → 800 (77 → 26), and the steps
|
|
26
|
-
// bracketing those gaps are already spoken for by background roles — which is why an opaque
|
|
27
|
-
// border landed exactly on `--bg-selected` / `--bg-disabled` and disappeared. 700 / 800 / 900
|
|
28
|
-
// are the dark background anchors and keep their values untouched.
|
|
29
24
|
gray: {
|
|
30
25
|
50: '#FAFAFA',
|
|
31
26
|
100: '#F5F5F5',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["container.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["container.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;EAcC"}
|
|
@@ -1,34 +1,17 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Container widths — a geometric rhythm, not a hand-picked list.
|
|
3
|
-
*
|
|
4
|
-
* The scale is anchored at both ends: `3xs` stays 256px (the narrowest useful
|
|
5
|
-
* field/rail width) and `7xl` is 1620px (the widest page measure). The eleven
|
|
6
|
-
* slots between them are `256 × r^n` with r = (1620 / 256)^(1/12) ≈ 1.1662 —
|
|
7
|
-
* so every neighbouring pair sits at the same ~+16.6% apart and the whole set
|
|
8
|
-
* reads as one progression instead of two grids spliced together (the previous
|
|
9
|
-
* scale stepped +32, then +64, then +96, then +128).
|
|
10
|
-
*
|
|
11
|
-
* Values are rounded to the 4px grid; `7xl` keeps its exact anchor and `4xl`
|
|
12
|
-
* is nudged 4px to land on 1024 (2.6px off the ideal, and a landmark worth
|
|
13
|
-
* keeping). Ratio between neighbours therefore ranges 1.157–1.172.
|
|
14
|
-
*
|
|
15
|
-
* Rounding is 4px, not 8px, because 1620 is not a multiple of 8 — the anchor
|
|
16
|
-
* defines the grid, so a stricter grid could not reach it.
|
|
17
|
-
*/
|
|
18
1
|
export const container = {
|
|
19
|
-
'3xs': '256px',
|
|
20
|
-
'2xs': '300px',
|
|
21
|
-
xs: '348px',
|
|
22
|
-
sm: '408px',
|
|
23
|
-
md: '472px',
|
|
24
|
-
lg: '552px',
|
|
25
|
-
xl: '644px',
|
|
26
|
-
'2xl': '752px',
|
|
27
|
-
'3xl': '876px',
|
|
28
|
-
'4xl': '1024px',
|
|
29
|
-
'5xl': '1192px',
|
|
30
|
-
'6xl': '1388px',
|
|
31
|
-
'7xl': '1620px'
|
|
2
|
+
'3xs': '256px',
|
|
3
|
+
'2xs': '300px',
|
|
4
|
+
xs: '348px',
|
|
5
|
+
sm: '408px',
|
|
6
|
+
md: '472px',
|
|
7
|
+
lg: '552px',
|
|
8
|
+
xl: '644px',
|
|
9
|
+
'2xl': '752px',
|
|
10
|
+
'3xl': '876px',
|
|
11
|
+
'4xl': '1024px',
|
|
12
|
+
'5xl': '1192px',
|
|
13
|
+
'6xl': '1388px',
|
|
14
|
+
'7xl': '1620px'
|
|
32
15
|
}
|
|
33
16
|
|
|
34
17
|
export default { container }
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Letter-spacing scale, in `rem` so the emitted CSS carries a single measure
|
|
3
|
-
* unit across the whole token set (font sizes, spacings and tracking are all
|
|
4
|
-
* root-relative). Values are the em-scale numbers kept as-is, so `widest`
|
|
5
|
-
* resolves to a fixed 1.6px instead of 10% of the element's font size.
|
|
6
|
-
*/
|
|
7
1
|
export const tracking = {
|
|
8
2
|
tighter: '-0.16rem',
|
|
9
3
|
tight: '-0.025rem',
|
|
@@ -1,24 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SEMANTIC COLOR TOKENS
|
|
3
|
-
*
|
|
4
|
-
* Single source of truth for semantic color tokens.
|
|
5
|
-
*
|
|
6
|
-
* - `semanticColorsData`: token refs grouped by category (`text`, `background`,
|
|
7
|
-
* `border`) and mode (`light`, `dark`). The raw ref source `semanticColors`
|
|
8
|
-
* derives from; only re-exported via `tokens/index.js` today. Note: its
|
|
9
|
-
* `backdrop` / `primary-mask` refs point at `alpha` shades that do not exist
|
|
10
|
-
* (`alpha.neutral`, `alpha.brand`) — fix them before wiring this data to a
|
|
11
|
-
* compiler, or the unresolved-ref guard will reject it.
|
|
12
|
-
* - `semanticColors`: derived map of `var(--…)` strings, grouped by category,
|
|
13
|
-
* consumed by `tokens/theme.js` to extend Tailwind's `textColor`,
|
|
14
|
-
* `backgroundColor`, and `borderColor`. Generates utilities like
|
|
15
|
-
* `text-default`, `bg-surface`, `border-danger` natively — no plugin needed.
|
|
16
|
-
*
|
|
17
|
-
* Adding a new semantic color: add a key under both `light` and `dark` in the
|
|
18
|
-
* relevant category here. The CSS variable and the Tailwind utility are both
|
|
19
|
-
* derived automatically.
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
1
|
import { tokenRef } from '../../scripts/refs.js'
|
|
23
2
|
|
|
24
3
|
export const semanticColorsData = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containers.d.ts","sourceRoot":"","sources":["containers.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"containers.d.ts","sourceRoot":"","sources":["containers.js"],"names":[],"mappings":"AASO,8BADO,OAAO,oBAAoB,EAAE,MAAM,CAqDhD"}
|
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Declarative container tokens (mobile-first).
|
|
3
|
-
*
|
|
4
|
-
* Each entry maps a token key to a breakpoint map. `_` is the default;
|
|
5
|
-
* any other key must exist in tokens/primitives/breakpoints.js.
|
|
6
|
-
*
|
|
7
|
-
* Values are ported from the legacy `containers.js` plugin. The `xl` bucket
|
|
8
|
-
* used to be wrapped in `@media (max-width: xl)` — orphan / never matched
|
|
9
|
-
* cleanly — and was corrected to `min-width` here.
|
|
10
|
-
*/
|
|
11
1
|
export const containersData: {
|
|
12
2
|
px: {
|
|
13
3
|
_: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containers.data.d.ts","sourceRoot":"","sources":["containers.data.js"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"containers.data.d.ts","sourceRoot":"","sources":["containers.data.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;EAIC"}
|