@ttoss/fsl-theme 1.1.22 → 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.
Files changed (66) hide show
  1. package/README.md +14 -12
  2. package/dist/{Types-BiBa17RL.d.cts → Types-BkaxtsMv.d.cts} +61 -13
  3. package/dist/{Types-BiBa17RL.d.mts → Types-BkaxtsMv.d.mts} +61 -13
  4. package/dist/{baseBundle-BWbICg4p.cjs → baseBundle-DdRSa5mf.cjs} +3 -2
  5. package/dist/{baseBundle-DiYlHNG5.mjs → baseBundle-R7WyjyTw.mjs} +3 -2
  6. package/dist/{createTheme-BHGc1IFI.cjs → createTheme--UFgVlEn.cjs} +34 -3
  7. package/dist/{createTheme-C1r5nJco.mjs → createTheme-B6tVIikC.mjs} +29 -4
  8. package/dist/css.cjs +2 -2
  9. package/dist/css.d.cts +1 -1
  10. package/dist/css.d.mts +1 -1
  11. package/dist/css.mjs +2 -2
  12. package/dist/dataviz/index.cjs +2 -2
  13. package/dist/dataviz/index.d.cts +1 -1
  14. package/dist/dataviz/index.d.mts +1 -1
  15. package/dist/dataviz/index.mjs +1 -1
  16. package/dist/dtcg.cjs +26 -9
  17. package/dist/dtcg.d.cts +17 -4
  18. package/dist/dtcg.d.mts +17 -4
  19. package/dist/dtcg.mjs +26 -9
  20. package/dist/{helpers-CIqeJ8yd.cjs → helpers-BU40JvFA.cjs} +27 -5
  21. package/dist/{helpers-Dz7NfNK6.mjs → helpers-BXaKe2s3.mjs} +27 -5
  22. package/dist/{index-BuszkWMy.d.mts → index-7YL90Xqs.d.cts} +9 -12
  23. package/dist/{index-Djro6G4e.d.cts → index-BmCTIOzh.d.mts} +9 -12
  24. package/dist/index.cjs +2 -8
  25. package/dist/index.d.cts +4 -4
  26. package/dist/index.d.mts +4 -4
  27. package/dist/index.mjs +2 -5
  28. package/dist/{react-D2J482kx.d.mts → react-C8JrZf-b.d.mts} +14 -2
  29. package/dist/{react-BKLEzIN8.cjs → react-DLB8nrXQ.cjs} +18 -2
  30. package/dist/{react-BXqSYnmk.d.cts → react-Dt7vGAVG.d.cts} +14 -2
  31. package/dist/react.cjs +1 -1
  32. package/dist/react.d.cts +1 -1
  33. package/dist/react.d.mts +1 -1
  34. package/dist/react.mjs +18 -2
  35. package/dist/runtime-entry.cjs +1 -1
  36. package/dist/runtime-entry.mjs +1 -1
  37. package/dist/{ssrScript-DfmopH-w.mjs → ssrScript-DNLlLDps.mjs} +1 -1
  38. package/dist/{ssrScript-D3mYscp1.cjs → ssrScript-MF5SIONH.cjs} +1 -1
  39. package/dist/themes/bruttal.cjs +19 -4
  40. package/dist/themes/bruttal.d.cts +1 -1
  41. package/dist/themes/bruttal.d.mts +1 -1
  42. package/dist/themes/bruttal.mjs +19 -4
  43. package/dist/{toCssVars-DDowz4wU.cjs → toCssVars-BseqmMcT.cjs} +27 -2
  44. package/dist/{toCssVars-CeckLjW1.mjs → toCssVars-C-9yIZDR.mjs} +27 -2
  45. package/dist/{tokenRegistry-DolhB5Vf.mjs → tokenRegistry-DviyqDeE.mjs} +19 -28
  46. package/dist/{tokenRegistry-B9zMRjpL.cjs → tokenRegistry-f_Bx_BAN.cjs} +19 -28
  47. package/dist/vars.cjs +3 -3
  48. package/dist/vars.d.cts +1 -1
  49. package/dist/vars.d.mts +1 -1
  50. package/dist/vars.mjs +3 -3
  51. package/dist/{withDataviz-CrgXLR5A.mjs → withDataviz-BvpZJnFx.mjs} +2 -2
  52. package/dist/{withDataviz-BzZwFV2e.cjs → withDataviz-CYRf4exT.cjs} +2 -2
  53. package/llms.txt +5 -5
  54. package/package.json +1 -1
  55. package/dist/themes/corporate.cjs +0 -34
  56. package/dist/themes/corporate.d.cts +0 -3
  57. package/dist/themes/corporate.d.mts +0 -3
  58. package/dist/themes/corporate.mjs +0 -31
  59. package/dist/themes/oca.cjs +0 -34
  60. package/dist/themes/oca.d.cts +0 -3
  61. package/dist/themes/oca.d.mts +0 -3
  62. package/dist/themes/oca.mjs +0 -31
  63. package/dist/themes/ventures.cjs +0 -34
  64. package/dist/themes/ventures.d.cts +0 -3
  65. package/dist/themes/ventures.d.mts +0 -3
  66. package/dist/themes/ventures.mjs +0 -31
package/dist/dtcg.cjs CHANGED
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, {
3
3
  value: 'Module'
4
4
  });
5
- const require_helpers = require('./helpers-CIqeJ8yd.cjs');
6
- const require_tokenRegistry = require('./tokenRegistry-B9zMRjpL.cjs');
5
+ const require_helpers = require('./helpers-BU40JvFA.cjs');
6
+ const require_tokenRegistry = require('./tokenRegistry-f_Bx_BAN.cjs');
7
7
 
8
8
  //#region src/roots/toDTCG.ts
9
9
  /**
@@ -26,12 +26,20 @@ const require_tokenRegistry = require('./tokenRegistry-B9zMRjpL.cjs');
26
26
  *
27
27
  * Motion leaves (SemanticMotionEntry) overridden separately:
28
28
  * - `.duration` → 'duration'
29
+ *
30
+ * Border / focus line widths resolve to a `dimension` (`1px`, `2px`) but sit
31
+ * under the untyped `semantic.border.` / `semantic.focus.` prefixes:
32
+ * - `.width` → 'dimension'
33
+ */
34
+ var SUFFIX_TYPE_OVERRIDES = [[".duration", "duration"], [".fontFamily", "fontFamily"], [".fontSize", "dimension"], [".fontWeight", "fontWeight"], [".lineHeight", "number"], [".letterSpacing", "dimension"], [".width", "dimension"], [".ring.color", "color"]];
35
+ /**
36
+ * Infer the DTCG `$type` for a token path, or `undefined` when the token is
37
+ * opaque (keyword/curve/dash-string) and has no valid DTCG scalar type — in
38
+ * which case `toDTCG` omits `$type` rather than emitting an invalid one.
29
39
  */
30
- var SUFFIX_TYPE_OVERRIDES = [[".duration", "duration"], [".fontFamily", "fontFamily"], [".fontSize", "dimension"], [".fontWeight", "fontWeight"], [".lineHeight", "number"], [".letterSpacing", "dimension"], [".ring.color", "color"]];
31
- var inferType = path => {
40
+ var inferDtcgType = path => {
32
41
  for (const [suffix, type] of SUFFIX_TYPE_OVERRIDES) if (path.endsWith(suffix)) return type;
33
42
  for (const [prefix, type] of require_tokenRegistry.DTCG_TYPE_PREFIXES) if (path.startsWith(prefix)) return type;
34
- return "string";
35
43
  };
36
44
  /**
37
45
  * Set a value at a dot-path in a nested object, creating intermediate
@@ -71,8 +79,16 @@ var buildHitExtension = (step, theme) => {
71
79
  * Root 3 — W3C Design Tokens (DTCG JSON).
72
80
  *
73
81
  * Convert a `ThemeTokens` into a structured token tree following the
74
- * W3C Design Tokens Community Group format. Every leaf node has `$value`
75
- * (fully resolved) and `$type` (inferred from the token path).
82
+ * W3C Design Tokens Community Group format (2025.10). Every leaf has a
83
+ * `$value`; `$type` is inferred from the token path and **omitted** for opaque
84
+ * tokens with no valid DTCG scalar type (`$type` is optional per spec).
85
+ *
86
+ * **Profile:** this emits **fully-resolved scalar tokens** — `$value`s are
87
+ * concrete (no `{alias}` refs) and composite shapes (typography, shadow,
88
+ * border, transition) are emitted as their individual scalar leaves, not as
89
+ * DTCG composite objects. This is a conformant DTCG profile; richer
90
+ * alias-preserving / composite output is a deferred enhancement (see
91
+ * CONTRIBUTING.md ADR-013).
76
92
  *
77
93
  * Semantic hit tokens (`semantic.sizing.hit.*`) include a `$extensions`
78
94
  * field declaring their coarse-pointer override value, so non-CSS consumers
@@ -98,10 +114,11 @@ var toDTCG = theme => {
98
114
  const flat = require_helpers.toFlatTokens(theme);
99
115
  const tree = {};
100
116
  for (const [path, value] of Object.entries(flat)) {
117
+ const dtcgType = inferDtcgType(path);
101
118
  const token = {
102
- $value: value,
103
- $type: inferType(path)
119
+ $value: value
104
120
  };
121
+ if (dtcgType !== void 0) token.$type = dtcgType;
105
122
  if (path.startsWith(SEMANTIC_HIT_PREFIX)) {
106
123
  const ext = buildHitExtension(path.slice(20), theme);
107
124
  if (ext) token.$extensions = ext;
package/dist/dtcg.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- import { i as ThemeTokens } from "./Types-BiBa17RL.cjs";
2
+ import { a as ThemeTokens } from "./Types-BkaxtsMv.cjs";
3
3
 
4
4
  //#region src/roots/toDTCG.d.ts
5
5
  /**
@@ -10,7 +10,12 @@ import { i as ThemeTokens } from "./Types-BiBa17RL.cjs";
10
10
  */
11
11
  interface DTCGToken {
12
12
  $value: string | number;
13
- $type: string;
13
+ /**
14
+ * W3C DTCG type. **Optional** — omitted for opaque/keyword tokens that have
15
+ * no valid DTCG scalar type (`$type` is optional in the DTCG spec). There is
16
+ * no `'string'` DTCG type; emitting one would break conformant importers.
17
+ */
18
+ $type?: string;
14
19
  $extensions?: Record<string, unknown>;
15
20
  }
16
21
  /**
@@ -23,8 +28,16 @@ type DTCGTokenTree = DTCGToken | {
23
28
  * Root 3 — W3C Design Tokens (DTCG JSON).
24
29
  *
25
30
  * Convert a `ThemeTokens` into a structured token tree following the
26
- * W3C Design Tokens Community Group format. Every leaf node has `$value`
27
- * (fully resolved) and `$type` (inferred from the token path).
31
+ * W3C Design Tokens Community Group format (2025.10). Every leaf has a
32
+ * `$value`; `$type` is inferred from the token path and **omitted** for opaque
33
+ * tokens with no valid DTCG scalar type (`$type` is optional per spec).
34
+ *
35
+ * **Profile:** this emits **fully-resolved scalar tokens** — `$value`s are
36
+ * concrete (no `{alias}` refs) and composite shapes (typography, shadow,
37
+ * border, transition) are emitted as their individual scalar leaves, not as
38
+ * DTCG composite objects. This is a conformant DTCG profile; richer
39
+ * alias-preserving / composite output is a deferred enhancement (see
40
+ * CONTRIBUTING.md ADR-013).
28
41
  *
29
42
  * Semantic hit tokens (`semantic.sizing.hit.*`) include a `$extensions`
30
43
  * field declaring their coarse-pointer override value, so non-CSS consumers
package/dist/dtcg.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- import { i as ThemeTokens } from "./Types-BiBa17RL.mjs";
2
+ import { a as ThemeTokens } from "./Types-BkaxtsMv.mjs";
3
3
 
4
4
  //#region src/roots/toDTCG.d.ts
5
5
  /**
@@ -10,7 +10,12 @@ import { i as ThemeTokens } from "./Types-BiBa17RL.mjs";
10
10
  */
11
11
  interface DTCGToken {
12
12
  $value: string | number;
13
- $type: string;
13
+ /**
14
+ * W3C DTCG type. **Optional** — omitted for opaque/keyword tokens that have
15
+ * no valid DTCG scalar type (`$type` is optional in the DTCG spec). There is
16
+ * no `'string'` DTCG type; emitting one would break conformant importers.
17
+ */
18
+ $type?: string;
14
19
  $extensions?: Record<string, unknown>;
15
20
  }
16
21
  /**
@@ -23,8 +28,16 @@ type DTCGTokenTree = DTCGToken | {
23
28
  * Root 3 — W3C Design Tokens (DTCG JSON).
24
29
  *
25
30
  * Convert a `ThemeTokens` into a structured token tree following the
26
- * W3C Design Tokens Community Group format. Every leaf node has `$value`
27
- * (fully resolved) and `$type` (inferred from the token path).
31
+ * W3C Design Tokens Community Group format (2025.10). Every leaf has a
32
+ * `$value`; `$type` is inferred from the token path and **omitted** for opaque
33
+ * tokens with no valid DTCG scalar type (`$type` is optional per spec).
34
+ *
35
+ * **Profile:** this emits **fully-resolved scalar tokens** — `$value`s are
36
+ * concrete (no `{alias}` refs) and composite shapes (typography, shadow,
37
+ * border, transition) are emitted as their individual scalar leaves, not as
38
+ * DTCG composite objects. This is a conformant DTCG profile; richer
39
+ * alias-preserving / composite output is a deferred enhancement (see
40
+ * CONTRIBUTING.md ADR-013).
28
41
  *
29
42
  * Semantic hit tokens (`semantic.sizing.hit.*`) include a `$extensions`
30
43
  * field declaring their coarse-pointer override value, so non-CSS consumers
package/dist/dtcg.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
- import { s as toFlatTokens } from "./helpers-Dz7NfNK6.mjs";
3
- import { n as DTCG_TYPE_PREFIXES } from "./tokenRegistry-DolhB5Vf.mjs";
2
+ import { s as toFlatTokens } from "./helpers-BXaKe2s3.mjs";
3
+ import { n as DTCG_TYPE_PREFIXES } from "./tokenRegistry-DviyqDeE.mjs";
4
4
 
5
5
  //#region src/roots/toDTCG.ts
6
6
  /**
@@ -23,12 +23,20 @@ import { n as DTCG_TYPE_PREFIXES } from "./tokenRegistry-DolhB5Vf.mjs";
23
23
  *
24
24
  * Motion leaves (SemanticMotionEntry) overridden separately:
25
25
  * - `.duration` → 'duration'
26
+ *
27
+ * Border / focus line widths resolve to a `dimension` (`1px`, `2px`) but sit
28
+ * under the untyped `semantic.border.` / `semantic.focus.` prefixes:
29
+ * - `.width` → 'dimension'
30
+ */
31
+ var SUFFIX_TYPE_OVERRIDES = [[".duration", "duration"], [".fontFamily", "fontFamily"], [".fontSize", "dimension"], [".fontWeight", "fontWeight"], [".lineHeight", "number"], [".letterSpacing", "dimension"], [".width", "dimension"], [".ring.color", "color"]];
32
+ /**
33
+ * Infer the DTCG `$type` for a token path, or `undefined` when the token is
34
+ * opaque (keyword/curve/dash-string) and has no valid DTCG scalar type — in
35
+ * which case `toDTCG` omits `$type` rather than emitting an invalid one.
26
36
  */
27
- var SUFFIX_TYPE_OVERRIDES = [[".duration", "duration"], [".fontFamily", "fontFamily"], [".fontSize", "dimension"], [".fontWeight", "fontWeight"], [".lineHeight", "number"], [".letterSpacing", "dimension"], [".ring.color", "color"]];
28
- var inferType = path => {
37
+ var inferDtcgType = path => {
29
38
  for (const [suffix, type] of SUFFIX_TYPE_OVERRIDES) if (path.endsWith(suffix)) return type;
30
39
  for (const [prefix, type] of DTCG_TYPE_PREFIXES) if (path.startsWith(prefix)) return type;
31
- return "string";
32
40
  };
33
41
  /**
34
42
  * Set a value at a dot-path in a nested object, creating intermediate
@@ -68,8 +76,16 @@ var buildHitExtension = (step, theme) => {
68
76
  * Root 3 — W3C Design Tokens (DTCG JSON).
69
77
  *
70
78
  * Convert a `ThemeTokens` into a structured token tree following the
71
- * W3C Design Tokens Community Group format. Every leaf node has `$value`
72
- * (fully resolved) and `$type` (inferred from the token path).
79
+ * W3C Design Tokens Community Group format (2025.10). Every leaf has a
80
+ * `$value`; `$type` is inferred from the token path and **omitted** for opaque
81
+ * tokens with no valid DTCG scalar type (`$type` is optional per spec).
82
+ *
83
+ * **Profile:** this emits **fully-resolved scalar tokens** — `$value`s are
84
+ * concrete (no `{alias}` refs) and composite shapes (typography, shadow,
85
+ * border, transition) are emitted as their individual scalar leaves, not as
86
+ * DTCG composite objects. This is a conformant DTCG profile; richer
87
+ * alias-preserving / composite output is a deferred enhancement (see
88
+ * CONTRIBUTING.md ADR-013).
73
89
  *
74
90
  * Semantic hit tokens (`semantic.sizing.hit.*`) include a `$extensions`
75
91
  * field declaring their coarse-pointer override value, so non-CSS consumers
@@ -95,10 +111,11 @@ var toDTCG = theme => {
95
111
  const flat = toFlatTokens(theme);
96
112
  const tree = {};
97
113
  for (const [path, value] of Object.entries(flat)) {
114
+ const dtcgType = inferDtcgType(path);
98
115
  const token = {
99
- $value: value,
100
- $type: inferType(path)
116
+ $value: value
101
117
  };
118
+ if (dtcgType !== void 0) token.$type = dtcgType;
102
119
  if (path.startsWith(SEMANTIC_HIT_PREFIX)) {
103
120
  const ext = buildHitExtension(path.slice(20), theme);
104
121
  if (ext) token.$extensions = ext;
@@ -1,8 +1,19 @@
1
1
  /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
2
  //#region src/roots/helpers.ts
3
- /** Check if a value is a token reference like `{core.colors.brand.500}` */
3
+ /**
4
+ * Check if a value is a **pure** token reference like `{core.colors.brand.500}`.
5
+ *
6
+ * A pure ref is a single `{path}` with no interior braces. Compound expressions
7
+ * (`clamp({a}, {b})`) and multi-ref strings (`{a} {b}`) are NOT pure refs — they
8
+ * start `{`/end `}` but carry interior braces, and must go through the compound
9
+ * resolution path instead. Without the interior-brace check `{a} {b}` would be
10
+ * mis-parsed as the single path `a} {b`.
11
+ */
12
+ var hasInteriorBraces = value => {
13
+ return value.indexOf("{", 1) !== -1 || value.indexOf("}") !== value.length - 1;
14
+ };
4
15
  var isTokenRef = value => {
5
- return typeof value === "string" && value.length > 2 && value.startsWith("{") && value.endsWith("}");
16
+ return typeof value === "string" && value.length > 2 && value.startsWith("{") && value.endsWith("}") && !hasInteriorBraces(value);
6
17
  };
7
18
  /** Extract the inner path from a token reference: `{core.colors.brand.500}` → `core.colors.brand.500` */
8
19
  var extractRefPath = ref => {
@@ -24,6 +35,14 @@ var isPlainObject = value => {
24
35
  return typeof value === "object" && value !== null && !Array.isArray(value);
25
36
  };
26
37
  /**
38
+ * Prototype-chain keys that must never be written from override data —
39
+ * `result['__proto__']` reaches the prototype setter, not an own property.
40
+ * Guards `createTheme`'s public `overrides` against prototype pollution.
41
+ */
42
+ var isUnsafeMergeKey = key => {
43
+ return key === "__proto__" || key === "constructor" || key === "prototype";
44
+ };
45
+ /**
27
46
  * Recursively merges `overrides` into `base`.
28
47
  * - Plain objects are merged recursively.
29
48
  * - All other values (primitives, arrays) are replaced.
@@ -34,6 +53,7 @@ var deepMerge = (base, overrides) => {
34
53
  ...base
35
54
  };
36
55
  for (const key of Object.keys(overrides)) {
56
+ if (isUnsafeMergeKey(key)) continue;
37
57
  const baseVal = result[key];
38
58
  const overVal = overrides[key];
39
59
  if (overVal === void 0) continue;
@@ -114,8 +134,8 @@ var toFlatTokens = (theme, options = {}) => {
114
134
  /**
115
135
  * Resolve all embedded `{path}` refs in a raw string expression.
116
136
  *
117
- * Handles both pure refs (`{core.space.4}`) and compound expressions
118
- * (`clamp({core.space.4}, {core.space.6}, {core.space.12})`).
137
+ * Handles both pure refs (`{core.spacing.4}`) and compound expressions
138
+ * (`clamp({core.spacing.4}, {core.spacing.6}, {core.spacing.12})`).
119
139
  */
120
140
  const resolveInline = (value, seen, ownerKey) => {
121
141
  return value.replace(COMPOUND_REF_RE, (_match, path) => {
@@ -128,7 +148,9 @@ var toFlatTokens = (theme, options = {}) => {
128
148
  reportUnresolved(ownerKey, path, "circular reference");
129
149
  return `{${path}}`;
130
150
  }
131
- const resolved = resolveRef(target, new Set(seen).add(path), ownerKey);
151
+ const childSeen = new Set(seen).add(path);
152
+ const resolved = resolveRef(target, childSeen, ownerKey);
153
+ if (typeof resolved === "string" && resolved.includes("{")) return resolveInline(resolved, childSeen, ownerKey);
132
154
  return String(resolved);
133
155
  });
134
156
  };
@@ -1,8 +1,19 @@
1
1
  /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
2
  //#region src/roots/helpers.ts
3
- /** Check if a value is a token reference like `{core.colors.brand.500}` */
3
+ /**
4
+ * Check if a value is a **pure** token reference like `{core.colors.brand.500}`.
5
+ *
6
+ * A pure ref is a single `{path}` with no interior braces. Compound expressions
7
+ * (`clamp({a}, {b})`) and multi-ref strings (`{a} {b}`) are NOT pure refs — they
8
+ * start `{`/end `}` but carry interior braces, and must go through the compound
9
+ * resolution path instead. Without the interior-brace check `{a} {b}` would be
10
+ * mis-parsed as the single path `a} {b`.
11
+ */
12
+ var hasInteriorBraces = value => {
13
+ return value.indexOf("{", 1) !== -1 || value.indexOf("}") !== value.length - 1;
14
+ };
4
15
  var isTokenRef = value => {
5
- return typeof value === "string" && value.length > 2 && value.startsWith("{") && value.endsWith("}");
16
+ return typeof value === "string" && value.length > 2 && value.startsWith("{") && value.endsWith("}") && !hasInteriorBraces(value);
6
17
  };
7
18
  /** Extract the inner path from a token reference: `{core.colors.brand.500}` → `core.colors.brand.500` */
8
19
  var extractRefPath = ref => {
@@ -24,6 +35,14 @@ var isPlainObject = value => {
24
35
  return typeof value === "object" && value !== null && !Array.isArray(value);
25
36
  };
26
37
  /**
38
+ * Prototype-chain keys that must never be written from override data —
39
+ * `result['__proto__']` reaches the prototype setter, not an own property.
40
+ * Guards `createTheme`'s public `overrides` against prototype pollution.
41
+ */
42
+ var isUnsafeMergeKey = key => {
43
+ return key === "__proto__" || key === "constructor" || key === "prototype";
44
+ };
45
+ /**
27
46
  * Recursively merges `overrides` into `base`.
28
47
  * - Plain objects are merged recursively.
29
48
  * - All other values (primitives, arrays) are replaced.
@@ -34,6 +53,7 @@ var deepMerge = (base, overrides) => {
34
53
  ...base
35
54
  };
36
55
  for (const key of Object.keys(overrides)) {
56
+ if (isUnsafeMergeKey(key)) continue;
37
57
  const baseVal = result[key];
38
58
  const overVal = overrides[key];
39
59
  if (overVal === void 0) continue;
@@ -114,8 +134,8 @@ var toFlatTokens = (theme, options = {}) => {
114
134
  /**
115
135
  * Resolve all embedded `{path}` refs in a raw string expression.
116
136
  *
117
- * Handles both pure refs (`{core.space.4}`) and compound expressions
118
- * (`clamp({core.space.4}, {core.space.6}, {core.space.12})`).
137
+ * Handles both pure refs (`{core.spacing.4}`) and compound expressions
138
+ * (`clamp({core.spacing.4}, {core.spacing.6}, {core.spacing.12})`).
119
139
  */
120
140
  const resolveInline = (value, seen, ownerKey) => {
121
141
  return value.replace(COMPOUND_REF_RE, (_match, path) => {
@@ -128,7 +148,9 @@ var toFlatTokens = (theme, options = {}) => {
128
148
  reportUnresolved(ownerKey, path, "circular reference");
129
149
  return `{${path}}`;
130
150
  }
131
- const resolved = resolveRef(target, new Set(seen).add(path), ownerKey);
151
+ const childSeen = new Set(seen).add(path);
152
+ const resolved = resolveRef(target, childSeen, ownerKey);
153
+ if (typeof resolved === "string" && resolved.includes("{")) return resolveInline(resolved, childSeen, ownerKey);
132
154
  return String(resolved);
133
155
  });
134
156
  };
@@ -1,5 +1,5 @@
1
1
 
2
- import { a as DeepPartial, i as ThemeTokens, r as ThemeBundle, t as ModeOverride } from "./Types-BiBa17RL.mjs";
2
+ import { a as ThemeTokens, i as ThemeBundle, o as DeepPartial, r as ThemeBrief, t as ModeOverride } from "./Types-BkaxtsMv.cjs";
3
3
  //#region src/baseTheme.d.ts
4
4
  /**
5
5
  * **Foundation** — Neutral baseline theme.
@@ -85,7 +85,8 @@ declare const createTheme: ({
85
85
  baseMode,
86
86
  base,
87
87
  overrides,
88
- alternate
88
+ alternate,
89
+ brief
89
90
  }?: {
90
91
  /**
91
92
  * Parent bundle to inherit from. `base`, `baseMode`, and `alternate` all
@@ -104,18 +105,14 @@ declare const createTheme: ({
104
105
  * Pass `null` to opt out of any alternate (single-mode theme).
105
106
  */
106
107
  alternate?: ModeOverride | null;
108
+ /**
109
+ * Machine-readable design brief. Inherited from `extends.meta` when omitted.
110
+ * Orthogonal to tokens — never affects DTCG/CSS output.
111
+ */
112
+ brief?: ThemeBrief;
107
113
  }) => ThemeBundle;
108
114
  //#endregion
109
115
  //#region src/themes/bruttal.d.ts
110
116
  declare const bruttal: ThemeBundle;
111
117
  //#endregion
112
- //#region src/themes/corporate.d.ts
113
- declare const corporate: ThemeBundle;
114
- //#endregion
115
- //#region src/themes/oca.d.ts
116
- declare const oca: ThemeBundle;
117
- //#endregion
118
- //#region src/themes/ventures.d.ts
119
- declare const ventures: ThemeBundle;
120
- //#endregion
121
- export { createTheme as a, bruttal as i, oca as n, baseTheme as o, corporate as r, darkAlternate as s, ventures as t };
118
+ export { darkAlternate as i, createTheme as n, baseTheme as r, bruttal as t };
@@ -1,5 +1,5 @@
1
1
 
2
- import { a as DeepPartial, i as ThemeTokens, r as ThemeBundle, t as ModeOverride } from "./Types-BiBa17RL.cjs";
2
+ import { a as ThemeTokens, i as ThemeBundle, o as DeepPartial, r as ThemeBrief, t as ModeOverride } from "./Types-BkaxtsMv.mjs";
3
3
  //#region src/baseTheme.d.ts
4
4
  /**
5
5
  * **Foundation** — Neutral baseline theme.
@@ -85,7 +85,8 @@ declare const createTheme: ({
85
85
  baseMode,
86
86
  base,
87
87
  overrides,
88
- alternate
88
+ alternate,
89
+ brief
89
90
  }?: {
90
91
  /**
91
92
  * Parent bundle to inherit from. `base`, `baseMode`, and `alternate` all
@@ -104,18 +105,14 @@ declare const createTheme: ({
104
105
  * Pass `null` to opt out of any alternate (single-mode theme).
105
106
  */
106
107
  alternate?: ModeOverride | null;
108
+ /**
109
+ * Machine-readable design brief. Inherited from `extends.meta` when omitted.
110
+ * Orthogonal to tokens — never affects DTCG/CSS output.
111
+ */
112
+ brief?: ThemeBrief;
107
113
  }) => ThemeBundle;
108
114
  //#endregion
109
115
  //#region src/themes/bruttal.d.ts
110
116
  declare const bruttal: ThemeBundle;
111
117
  //#endregion
112
- //#region src/themes/corporate.d.ts
113
- declare const corporate: ThemeBundle;
114
- //#endregion
115
- //#region src/themes/oca.d.ts
116
- declare const oca: ThemeBundle;
117
- //#endregion
118
- //#region src/themes/ventures.d.ts
119
- declare const ventures: ThemeBundle;
120
- //#endregion
121
- export { createTheme as a, bruttal as i, oca as n, baseTheme as o, corporate as r, darkAlternate as s, ventures as t };
118
+ export { darkAlternate as i, createTheme as n, baseTheme as r, bruttal as t };
package/dist/index.cjs CHANGED
@@ -2,15 +2,9 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, {
3
3
  value: 'Module'
4
4
  });
5
- const require_createTheme = require('./createTheme-BHGc1IFI.cjs');
5
+ const require_createTheme = require('./createTheme--UFgVlEn.cjs');
6
6
  const require_themes_bruttal = require('./themes/bruttal.cjs');
7
- const require_themes_corporate = require('./themes/corporate.cjs');
8
- const require_themes_oca = require('./themes/oca.cjs');
9
- const require_themes_ventures = require('./themes/ventures.cjs');
10
7
  exports.baseTheme = require_createTheme.baseTheme;
11
8
  exports.bruttal = require_themes_bruttal.bruttal;
12
- exports.corporate = require_themes_corporate.corporate;
13
9
  exports.createTheme = require_createTheme.createTheme;
14
- exports.darkAlternate = require_createTheme.darkAlternate;
15
- exports.oca = require_themes_oca.oca;
16
- exports.ventures = require_themes_ventures.ventures;
10
+ exports.darkAlternate = require_createTheme.darkAlternate;
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
- import { a as DeepPartial, i as ThemeTokens, n as SemanticTokens, r as ThemeBundle, t as ModeOverride } from "./Types-BiBa17RL.cjs";
3
- import { a as createTheme, i as bruttal, n as oca, o as baseTheme, r as corporate, s as darkAlternate, t as ventures } from "./index-Djro6G4e.cjs";
2
+ import { a as ThemeTokens, i as ThemeBundle, n as SemanticTokens, o as DeepPartial, r as ThemeBrief, t as ModeOverride } from "./Types-BkaxtsMv.cjs";
3
+ import { i as darkAlternate, n as createTheme, r as baseTheme, t as bruttal } from "./index-7YL90Xqs.cjs";
4
4
  import { o as ThemeMode } from "./ssrScript-BVysxDws.cjs";
5
- import { c as ThemeStylesProps, n as ThemeHeadProps } from "./react-BXqSYnmk.cjs";
6
- export { type DeepPartial, type ModeOverride, type SemanticTokens, type ThemeBundle, type ThemeHeadProps, type ThemeMode, type ThemeStylesProps, type ThemeTokens, baseTheme, bruttal, corporate, createTheme, darkAlternate, oca, ventures };
5
+ import { c as ThemeStylesProps, n as ThemeHeadProps } from "./react-Dt7vGAVG.cjs";
6
+ export { type DeepPartial, type ModeOverride, type SemanticTokens, type ThemeBrief, type ThemeBundle, type ThemeHeadProps, type ThemeMode, type ThemeStylesProps, type ThemeTokens, baseTheme, bruttal, createTheme, darkAlternate };
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
- import { a as DeepPartial, i as ThemeTokens, n as SemanticTokens, r as ThemeBundle, t as ModeOverride } from "./Types-BiBa17RL.mjs";
3
- import { a as createTheme, i as bruttal, n as oca, o as baseTheme, r as corporate, s as darkAlternate, t as ventures } from "./index-BuszkWMy.mjs";
2
+ import { a as ThemeTokens, i as ThemeBundle, n as SemanticTokens, o as DeepPartial, r as ThemeBrief, t as ModeOverride } from "./Types-BkaxtsMv.mjs";
3
+ import { i as darkAlternate, n as createTheme, r as baseTheme, t as bruttal } from "./index-BmCTIOzh.mjs";
4
4
  import { o as ThemeMode } from "./ssrScript-BVysxDws.mjs";
5
- import { c as ThemeStylesProps, n as ThemeHeadProps } from "./react-D2J482kx.mjs";
6
- export { type DeepPartial, type ModeOverride, type SemanticTokens, type ThemeBundle, type ThemeHeadProps, type ThemeMode, type ThemeStylesProps, type ThemeTokens, baseTheme, bruttal, corporate, createTheme, darkAlternate, oca, ventures };
5
+ import { c as ThemeStylesProps, n as ThemeHeadProps } from "./react-C8JrZf-b.mjs";
6
+ export { type DeepPartial, type ModeOverride, type SemanticTokens, type ThemeBrief, type ThemeBundle, type ThemeHeadProps, type ThemeMode, type ThemeStylesProps, type ThemeTokens, baseTheme, bruttal, createTheme, darkAlternate };
package/dist/index.mjs CHANGED
@@ -1,7 +1,4 @@
1
1
  /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
- import { i as darkAlternate, n as createTheme, r as baseTheme } from "./createTheme-C1r5nJco.mjs";
2
+ import { a as darkAlternate, i as baseTheme, n as createTheme } from "./createTheme-B6tVIikC.mjs";
3
3
  import { bruttal } from "./themes/bruttal.mjs";
4
- import { corporate } from "./themes/corporate.mjs";
5
- import { oca } from "./themes/oca.mjs";
6
- import { ventures } from "./themes/ventures.mjs";
7
- export { baseTheme, bruttal, corporate, createTheme, darkAlternate, oca, ventures };
4
+ export { baseTheme, bruttal, createTheme, darkAlternate };
@@ -1,5 +1,5 @@
1
1
 
2
- import { n as SemanticTokens, r as ThemeBundle } from "./Types-BiBa17RL.mjs";
2
+ import { i as ThemeBundle, n as SemanticTokens } from "./Types-BkaxtsMv.mjs";
3
3
  import { a as ResolvedMode, o as ThemeMode, t as ThemeScriptConfig } from "./ssrScript-BVysxDws.mjs";
4
4
  import * as React from "react";
5
5
 
@@ -24,7 +24,15 @@ interface ThemeProviderProps {
24
24
  *
25
25
  * Passing `theme` enables `useTokens()` and `useResolvedTokens()` for all
26
26
  * descendants, and automatically injects the CSS Custom Properties `<style>`
27
- * tag into the document head (React 19 hoisting).
27
+ * tag into the document head (React 19 hoisting, deduped by `href`).
28
+ *
29
+ * **React version:** auto-injection into `<head>` requires **React 19** style
30
+ * hoisting. On React 18 the `<style>` renders inline where the provider sits
31
+ * (not hoisted); use `<ThemeHead>` / `<ThemeStyles>` in your `<head>` for
32
+ * explicit injection there — but do not also pass `theme` here, since the
33
+ * href-less `<ThemeHead>`/`<ThemeStyles>` tag does not dedup against this
34
+ * provider's href-keyed one. The stable `href` only collapses multiple themed
35
+ * `<ThemeProvider>`s sharing a `themeId` into one tag on 19.
28
36
  *
29
37
  * @example
30
38
  * ```tsx
@@ -301,6 +309,10 @@ interface ThemeStylesProps {
301
309
  * `dangerouslySetInnerHTML` is safe: content comes exclusively from
302
310
  * `toCssVars()` (a pure internal function) — no user input is interpolated.
303
311
  *
312
+ * Renders a plain inline `<style>` where you place it (put it in `<head>`).
313
+ * Do **not** also pass `theme` to `<ThemeProvider>` — that injects a second
314
+ * copy; pass `theme` to the head component only (see README SSR section).
315
+ *
304
316
  * @example
305
317
  * ```tsx
306
318
  * // SSR escape hatch — no themeId needed for canonical 1-theme model
@@ -26,14 +26,25 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  }) : target, mod));
27
27
 
28
28
  //#endregion
29
- const require_helpers = require('./helpers-CIqeJ8yd.cjs');
29
+ const require_helpers = require('./helpers-BU40JvFA.cjs');
30
30
  const require_css = require('./css.cjs');
31
- const require_ssrScript = require('./ssrScript-D3mYscp1.cjs');
31
+ const require_ssrScript = require('./ssrScript-MF5SIONH.cjs');
32
32
  let react = require("react");
33
33
  react = __toESM(react);
34
34
  let react_jsx_runtime = require("react/jsx-runtime");
35
35
 
36
36
  //#region src/react.tsx
37
+ /**
38
+ * Stable `href` for the theme's hoistable `<style>` tag. React 19 keys style
39
+ * hoisting **and dedup** on `href` + `precedence`, so re-renders and multiple
40
+ * `<ThemeProvider>`s sharing a `themeId` collapse to a single tag, while
41
+ * distinct `themeId`s coexist (micro-frontends). Note: `ThemeStyles` /
42
+ * `ThemeHead` render an href-less inline `<style>`, so they do **not** dedup
43
+ * against this hoisted tag — don't combine them with a themed `ThemeProvider`.
44
+ */
45
+ var themeStyleHref = themeId => {
46
+ return `tt-theme-${themeId ?? "root"}`;
47
+ };
37
48
  var COARSE_QUERY = "(any-pointer: coarse)";
38
49
  /**
39
50
  * Subscribe to coarse-pointer media query changes.
@@ -188,6 +199,7 @@ var ThemeProvider = ({
188
199
  });
189
200
  if (theme) return /* @__PURE__ */(0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, {
190
201
  children: [/* @__PURE__ */(0, react_jsx_runtime.jsx)("style", {
202
+ href: themeStyleHref(themeId),
191
203
  precedence: "default",
192
204
  children: cssContent
193
205
  }), /* @__PURE__ */(0, react_jsx_runtime.jsx)(ResolvedTokensCtx.Provider, {
@@ -344,6 +356,10 @@ var ThemeScript = ({
344
356
  * `dangerouslySetInnerHTML` is safe: content comes exclusively from
345
357
  * `toCssVars()` (a pure internal function) — no user input is interpolated.
346
358
  *
359
+ * Renders a plain inline `<style>` where you place it (put it in `<head>`).
360
+ * Do **not** also pass `theme` to `<ThemeProvider>` — that injects a second
361
+ * copy; pass `theme` to the head component only (see README SSR section).
362
+ *
347
363
  * @example
348
364
  * ```tsx
349
365
  * // SSR escape hatch — no themeId needed for canonical 1-theme model
@@ -1,5 +1,5 @@
1
1
 
2
- import { n as SemanticTokens, r as ThemeBundle } from "./Types-BiBa17RL.cjs";
2
+ import { i as ThemeBundle, n as SemanticTokens } from "./Types-BkaxtsMv.cjs";
3
3
  import { a as ResolvedMode, o as ThemeMode, t as ThemeScriptConfig } from "./ssrScript-BVysxDws.cjs";
4
4
  import * as React from "react";
5
5
 
@@ -24,7 +24,15 @@ interface ThemeProviderProps {
24
24
  *
25
25
  * Passing `theme` enables `useTokens()` and `useResolvedTokens()` for all
26
26
  * descendants, and automatically injects the CSS Custom Properties `<style>`
27
- * tag into the document head (React 19 hoisting).
27
+ * tag into the document head (React 19 hoisting, deduped by `href`).
28
+ *
29
+ * **React version:** auto-injection into `<head>` requires **React 19** style
30
+ * hoisting. On React 18 the `<style>` renders inline where the provider sits
31
+ * (not hoisted); use `<ThemeHead>` / `<ThemeStyles>` in your `<head>` for
32
+ * explicit injection there — but do not also pass `theme` here, since the
33
+ * href-less `<ThemeHead>`/`<ThemeStyles>` tag does not dedup against this
34
+ * provider's href-keyed one. The stable `href` only collapses multiple themed
35
+ * `<ThemeProvider>`s sharing a `themeId` into one tag on 19.
28
36
  *
29
37
  * @example
30
38
  * ```tsx
@@ -301,6 +309,10 @@ interface ThemeStylesProps {
301
309
  * `dangerouslySetInnerHTML` is safe: content comes exclusively from
302
310
  * `toCssVars()` (a pure internal function) — no user input is interpolated.
303
311
  *
312
+ * Renders a plain inline `<style>` where you place it (put it in `<head>`).
313
+ * Do **not** also pass `theme` to `<ThemeProvider>` — that injects a second
314
+ * copy; pass `theme` to the head component only (see README SSR section).
315
+ *
304
316
  * @example
305
317
  * ```tsx
306
318
  * // SSR escape hatch — no themeId needed for canonical 1-theme model
package/dist/react.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, {
3
3
  value: 'Module'
4
4
  });
5
- const require_react = require('./react-BKLEzIN8.cjs');
5
+ const require_react = require('./react-DLB8nrXQ.cjs');
6
6
  exports.ThemeHead = require_react.ThemeHead;
7
7
  exports.ThemeProvider = require_react.ThemeProvider;
8
8
  exports.ThemeScript = require_react.ThemeScript;
package/dist/react.d.cts CHANGED
@@ -1,4 +1,4 @@
1
1
 
2
2
  import { a as ResolvedMode, o as ThemeMode } from "./ssrScript-BVysxDws.cjs";
3
- import { a as ThemeScript, c as ThemeStylesProps, d as useResolvedTokens, f as useTokens, i as ThemeProviderProps, l as UseColorModeResult, n as ThemeHeadProps, o as ThemeScriptProps, r as ThemeProvider, s as ThemeStyles, t as ThemeHead, u as useColorMode } from "./react-BXqSYnmk.cjs";
3
+ import { a as ThemeScript, c as ThemeStylesProps, d as useResolvedTokens, f as useTokens, i as ThemeProviderProps, l as UseColorModeResult, n as ThemeHeadProps, o as ThemeScriptProps, r as ThemeProvider, s as ThemeStyles, t as ThemeHead, u as useColorMode } from "./react-Dt7vGAVG.cjs";
4
4
  export { type ResolvedMode, ThemeHead, ThemeHeadProps, type ThemeMode, ThemeProvider, ThemeProviderProps, ThemeScript, ThemeScriptProps, ThemeStyles, ThemeStylesProps, UseColorModeResult, useColorMode, useResolvedTokens, useTokens };
package/dist/react.d.mts CHANGED
@@ -1,4 +1,4 @@
1
1
 
2
2
  import { a as ResolvedMode, o as ThemeMode } from "./ssrScript-BVysxDws.mjs";
3
- import { a as ThemeScript, c as ThemeStylesProps, d as useResolvedTokens, f as useTokens, i as ThemeProviderProps, l as UseColorModeResult, n as ThemeHeadProps, o as ThemeScriptProps, r as ThemeProvider, s as ThemeStyles, t as ThemeHead, u as useColorMode } from "./react-D2J482kx.mjs";
3
+ import { a as ThemeScript, c as ThemeStylesProps, d as useResolvedTokens, f as useTokens, i as ThemeProviderProps, l as UseColorModeResult, n as ThemeHeadProps, o as ThemeScriptProps, r as ThemeProvider, s as ThemeStyles, t as ThemeHead, u as useColorMode } from "./react-C8JrZf-b.mjs";
4
4
  export { type ResolvedMode, ThemeHead, ThemeHeadProps, type ThemeMode, ThemeProvider, ThemeProviderProps, ThemeScript, ThemeScriptProps, ThemeStyles, ThemeStylesProps, UseColorModeResult, useColorMode, useResolvedTokens, useTokens };