@cogenta/render 0.1.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 (205) hide show
  1. package/dist/astro/integration.d.ts +57 -0
  2. package/dist/astro/integration.d.ts.map +1 -0
  3. package/dist/astro/integration.js +72 -0
  4. package/dist/astro/integration.js.map +1 -0
  5. package/dist/build/index.d.ts +7 -0
  6. package/dist/build/index.d.ts.map +1 -0
  7. package/dist/build/index.js +7 -0
  8. package/dist/build/index.js.map +1 -0
  9. package/dist/build/integration.d.ts +25 -0
  10. package/dist/build/integration.d.ts.map +1 -0
  11. package/dist/build/integration.js +41 -0
  12. package/dist/build/integration.js.map +1 -0
  13. package/dist/build/plan.d.ts +41 -0
  14. package/dist/build/plan.d.ts.map +1 -0
  15. package/dist/build/plan.js +48 -0
  16. package/dist/build/plan.js.map +1 -0
  17. package/dist/build/refusal.d.ts +14 -0
  18. package/dist/build/refusal.d.ts.map +1 -0
  19. package/dist/build/refusal.js +110 -0
  20. package/dist/build/refusal.js.map +1 -0
  21. package/dist/build/requirements.d.ts +59 -0
  22. package/dist/build/requirements.d.ts.map +1 -0
  23. package/dist/build/requirements.js +74 -0
  24. package/dist/build/requirements.js.map +1 -0
  25. package/dist/build/run-build.d.ts +43 -0
  26. package/dist/build/run-build.d.ts.map +1 -0
  27. package/dist/build/run-build.js +73 -0
  28. package/dist/build/run-build.js.map +1 -0
  29. package/dist/build/targets.d.ts +47 -0
  30. package/dist/build/targets.d.ts.map +1 -0
  31. package/dist/build/targets.js +69 -0
  32. package/dist/build/targets.js.map +1 -0
  33. package/dist/cache/index.d.ts +7 -0
  34. package/dist/cache/index.d.ts.map +1 -0
  35. package/dist/cache/index.js +4 -0
  36. package/dist/cache/index.js.map +1 -0
  37. package/dist/cache/page-cache.d.ts +64 -0
  38. package/dist/cache/page-cache.d.ts.map +1 -0
  39. package/dist/cache/page-cache.js +128 -0
  40. package/dist/cache/page-cache.js.map +1 -0
  41. package/dist/cache/recorder.d.ts +49 -0
  42. package/dist/cache/recorder.d.ts.map +1 -0
  43. package/dist/cache/recorder.js +77 -0
  44. package/dist/cache/recorder.js.map +1 -0
  45. package/dist/cache/tags.d.ts +55 -0
  46. package/dist/cache/tags.d.ts.map +1 -0
  47. package/dist/cache/tags.js +62 -0
  48. package/dist/cache/tags.js.map +1 -0
  49. package/dist/config.d.ts +48 -0
  50. package/dist/config.d.ts.map +1 -0
  51. package/dist/config.js +44 -0
  52. package/dist/config.js.map +1 -0
  53. package/dist/content/client.d.ts +35 -0
  54. package/dist/content/client.d.ts.map +1 -0
  55. package/dist/content/client.js +155 -0
  56. package/dist/content/client.js.map +1 -0
  57. package/dist/content/types.d.ts +104 -0
  58. package/dist/content/types.d.ts.map +1 -0
  59. package/dist/content/types.js +16 -0
  60. package/dist/content/types.js.map +1 -0
  61. package/dist/context/render-context.d.ts +31 -0
  62. package/dist/context/render-context.d.ts.map +1 -0
  63. package/dist/context/render-context.js +152 -0
  64. package/dist/context/render-context.js.map +1 -0
  65. package/dist/context/types.d.ts +49 -0
  66. package/dist/context/types.d.ts.map +1 -0
  67. package/dist/context/types.js +2 -0
  68. package/dist/context/types.js.map +1 -0
  69. package/dist/images/errors.d.ts +20 -0
  70. package/dist/images/errors.d.ts.map +1 -0
  71. package/dist/images/errors.js +58 -0
  72. package/dist/images/errors.js.map +1 -0
  73. package/dist/images/format.d.ts +18 -0
  74. package/dist/images/format.d.ts.map +1 -0
  75. package/dist/images/format.js +34 -0
  76. package/dist/images/format.js.map +1 -0
  77. package/dist/images/geometry.d.ts +46 -0
  78. package/dist/images/geometry.d.ts.map +1 -0
  79. package/dist/images/geometry.js +127 -0
  80. package/dist/images/geometry.js.map +1 -0
  81. package/dist/images/index.d.ts +29 -0
  82. package/dist/images/index.d.ts.map +1 -0
  83. package/dist/images/index.js +30 -0
  84. package/dist/images/index.js.map +1 -0
  85. package/dist/images/pipeline.d.ts +51 -0
  86. package/dist/images/pipeline.d.ts.map +1 -0
  87. package/dist/images/pipeline.js +105 -0
  88. package/dist/images/pipeline.js.map +1 -0
  89. package/dist/images/sharp.d.ts +57 -0
  90. package/dist/images/sharp.d.ts.map +1 -0
  91. package/dist/images/sharp.js +139 -0
  92. package/dist/images/sharp.js.map +1 -0
  93. package/dist/images/srcset.d.ts +33 -0
  94. package/dist/images/srcset.d.ts.map +1 -0
  95. package/dist/images/srcset.js +94 -0
  96. package/dist/images/srcset.js.map +1 -0
  97. package/dist/images/store.d.ts +32 -0
  98. package/dist/images/store.d.ts.map +1 -0
  99. package/dist/images/store.js +54 -0
  100. package/dist/images/store.js.map +1 -0
  101. package/dist/images/types.d.ts +128 -0
  102. package/dist/images/types.d.ts.map +1 -0
  103. package/dist/images/types.js +22 -0
  104. package/dist/images/types.js.map +1 -0
  105. package/dist/images/wasm.d.ts +43 -0
  106. package/dist/images/wasm.d.ts.map +1 -0
  107. package/dist/images/wasm.js +128 -0
  108. package/dist/images/wasm.js.map +1 -0
  109. package/dist/index.d.ts +29 -0
  110. package/dist/index.d.ts.map +1 -0
  111. package/dist/index.js +29 -0
  112. package/dist/index.js.map +1 -0
  113. package/dist/pwa/build.d.ts +39 -0
  114. package/dist/pwa/build.d.ts.map +1 -0
  115. package/dist/pwa/build.js +38 -0
  116. package/dist/pwa/build.js.map +1 -0
  117. package/dist/pwa/client.d.ts +90 -0
  118. package/dist/pwa/client.d.ts.map +1 -0
  119. package/dist/pwa/client.js +76 -0
  120. package/dist/pwa/client.js.map +1 -0
  121. package/dist/pwa/index.d.ts +29 -0
  122. package/dist/pwa/index.d.ts.map +1 -0
  123. package/dist/pwa/index.js +22 -0
  124. package/dist/pwa/index.js.map +1 -0
  125. package/dist/pwa/manifest.d.ts +69 -0
  126. package/dist/pwa/manifest.d.ts.map +1 -0
  127. package/dist/pwa/manifest.js +108 -0
  128. package/dist/pwa/manifest.js.map +1 -0
  129. package/dist/pwa/offline.d.ts +44 -0
  130. package/dist/pwa/offline.d.ts.map +1 -0
  131. package/dist/pwa/offline.js +94 -0
  132. package/dist/pwa/offline.js.map +1 -0
  133. package/dist/pwa/service-worker.d.ts +71 -0
  134. package/dist/pwa/service-worker.d.ts.map +1 -0
  135. package/dist/pwa/service-worker.js +119 -0
  136. package/dist/pwa/service-worker.js.map +1 -0
  137. package/dist/pwa/strategy.d.ts +36 -0
  138. package/dist/pwa/strategy.d.ts.map +1 -0
  139. package/dist/pwa/strategy.js +180 -0
  140. package/dist/pwa/strategy.js.map +1 -0
  141. package/dist/pwa/sw-runtime.d.ts +109 -0
  142. package/dist/pwa/sw-runtime.d.ts.map +1 -0
  143. package/dist/pwa/sw-runtime.js +214 -0
  144. package/dist/pwa/sw-runtime.js.map +1 -0
  145. package/dist/pwa/types.d.ts +107 -0
  146. package/dist/pwa/types.d.ts.map +1 -0
  147. package/dist/pwa/types.js +18 -0
  148. package/dist/pwa/types.js.map +1 -0
  149. package/dist/pwa/version.d.ts +45 -0
  150. package/dist/pwa/version.d.ts.map +1 -0
  151. package/dist/pwa/version.js +89 -0
  152. package/dist/pwa/version.js.map +1 -0
  153. package/dist/skin/color.d.ts +50 -0
  154. package/dist/skin/color.d.ts.map +1 -0
  155. package/dist/skin/color.js +176 -0
  156. package/dist/skin/color.js.map +1 -0
  157. package/dist/skin/css.d.ts +19 -0
  158. package/dist/skin/css.d.ts.map +1 -0
  159. package/dist/skin/css.js +69 -0
  160. package/dist/skin/css.js.map +1 -0
  161. package/dist/skin/errors.d.ts +22 -0
  162. package/dist/skin/errors.d.ts.map +1 -0
  163. package/dist/skin/errors.js +59 -0
  164. package/dist/skin/errors.js.map +1 -0
  165. package/dist/skin/index.d.ts +15 -0
  166. package/dist/skin/index.d.ts.map +1 -0
  167. package/dist/skin/index.js +11 -0
  168. package/dist/skin/index.js.map +1 -0
  169. package/dist/skin/sheet.d.ts +42 -0
  170. package/dist/skin/sheet.d.ts.map +1 -0
  171. package/dist/skin/sheet.js +36 -0
  172. package/dist/skin/sheet.js.map +1 -0
  173. package/dist/skin/tokens.d.ts +90 -0
  174. package/dist/skin/tokens.d.ts.map +1 -0
  175. package/dist/skin/tokens.js +56 -0
  176. package/dist/skin/tokens.js.map +1 -0
  177. package/dist/skin/validate.d.ts +14 -0
  178. package/dist/skin/validate.d.ts.map +1 -0
  179. package/dist/skin/validate.js +272 -0
  180. package/dist/skin/validate.js.map +1 -0
  181. package/dist/theme/load-theme.d.ts +37 -0
  182. package/dist/theme/load-theme.d.ts.map +1 -0
  183. package/dist/theme/load-theme.js +102 -0
  184. package/dist/theme/load-theme.js.map +1 -0
  185. package/dist/theme/manifest.d.ts +48 -0
  186. package/dist/theme/manifest.d.ts.map +1 -0
  187. package/dist/theme/manifest.js +36 -0
  188. package/dist/theme/manifest.js.map +1 -0
  189. package/dist/theme/verify/forbidden.d.ts +39 -0
  190. package/dist/theme/verify/forbidden.d.ts.map +1 -0
  191. package/dist/theme/verify/forbidden.js +107 -0
  192. package/dist/theme/verify/forbidden.js.map +1 -0
  193. package/dist/theme/verify/scan-file.d.ts +15 -0
  194. package/dist/theme/verify/scan-file.d.ts.map +1 -0
  195. package/dist/theme/verify/scan-file.js +151 -0
  196. package/dist/theme/verify/scan-file.js.map +1 -0
  197. package/dist/theme/verify/scanner.d.ts +52 -0
  198. package/dist/theme/verify/scanner.d.ts.map +1 -0
  199. package/dist/theme/verify/scanner.js +304 -0
  200. package/dist/theme/verify/scanner.js.map +1 -0
  201. package/dist/theme/verify/verify-theme.d.ts +44 -0
  202. package/dist/theme/verify/verify-theme.d.ts.map +1 -0
  203. package/dist/theme/verify/verify-theme.js +179 -0
  204. package/dist/theme/verify/verify-theme.js.map +1 -0
  205. package/package.json +56 -0
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Colour parsing and WCAG contrast, written by hand.
3
+ *
4
+ * Why no dependency: a colour library is a supply-chain surface, and the whole
5
+ * point of the skin validator is that a skin generated by a model in L9 is safe
6
+ * *by construction*. The rules it enforces must be auditable in one file, not
7
+ * inherited from a package that may change its rounding next minor version.
8
+ */
9
+ /** WCAG 2.2 AA thresholds. Large text is >=18.66px bold or >=24px regular. */
10
+ export const AA_NORMAL_TEXT = 4.5;
11
+ export const AA_LARGE_TEXT = 3;
12
+ export function aaThreshold(size) {
13
+ return size === 'large' ? AA_LARGE_TEXT : AA_NORMAL_TEXT;
14
+ }
15
+ const HEX = /^#([0-9a-f]{3,8})$/i;
16
+ const FUNCTIONAL = /^(rgb|rgba|hsl|hsla)\(([^()]*)\)$/i;
17
+ /**
18
+ * Parses a CSS colour. The accepted set is deliberately closed to hex, `rgb()`
19
+ * and `hsl()`: named colours, `color()` and `oklch()` would each need their own
20
+ * conversion path before a contrast ratio could be computed, and a colour whose
21
+ * luminance cannot be computed cannot be validated — so it must not be accepted.
22
+ *
23
+ * Returns `null` rather than throwing: the caller owns the error, because only
24
+ * the caller knows which token the value came from.
25
+ */
26
+ export function parseColor(value) {
27
+ const input = value.trim();
28
+ const hex = HEX.exec(input);
29
+ if (hex !== null) {
30
+ return parseHex(hex[1] ?? '');
31
+ }
32
+ const fn = FUNCTIONAL.exec(input);
33
+ if (fn !== null) {
34
+ const name = (fn[1] ?? '').toLowerCase();
35
+ const parts = splitArguments(fn[2] ?? '');
36
+ if (parts === null) {
37
+ return null;
38
+ }
39
+ return name.startsWith('rgb') ? parseRgbArgs(parts) : parseHslArgs(parts);
40
+ }
41
+ return null;
42
+ }
43
+ function parseHex(digits) {
44
+ const expand = (pair) => Number.parseInt(pair, 16);
45
+ if (digits.length === 3 || digits.length === 4) {
46
+ const channels = [...digits].map((c) => expand(c + c));
47
+ return toRgba(channels);
48
+ }
49
+ if (digits.length === 6 || digits.length === 8) {
50
+ const channels = [];
51
+ for (let i = 0; i < digits.length; i += 2) {
52
+ channels.push(expand(digits.slice(i, i + 2)));
53
+ }
54
+ return toRgba(channels);
55
+ }
56
+ return null;
57
+ }
58
+ function toRgba(channels) {
59
+ const [r, g, b, a] = channels;
60
+ if (r === undefined || g === undefined || b === undefined) {
61
+ return null;
62
+ }
63
+ if (![r, g, b].every(Number.isFinite)) {
64
+ return null;
65
+ }
66
+ return { r, g, b, a: a === undefined ? 1 : a / 255 };
67
+ }
68
+ /** Accepts both the legacy comma syntax and the modern `r g b / a` syntax. */
69
+ function splitArguments(raw) {
70
+ const [head, ...rest] = raw.split('/');
71
+ if (rest.length > 1 || head === undefined) {
72
+ return null;
73
+ }
74
+ const first = head.trim();
75
+ const values = first.includes(',')
76
+ ? first.split(',').map((p) => p.trim())
77
+ : first.split(/\s+/).filter((p) => p !== '');
78
+ if (rest.length === 1) {
79
+ values.push((rest[0] ?? '').trim());
80
+ }
81
+ return values.length === 3 || values.length === 4 ? values : null;
82
+ }
83
+ function parseNumber(raw, percentBasis) {
84
+ const text = raw.trim();
85
+ if (text === '') {
86
+ return null;
87
+ }
88
+ const isPercent = text.endsWith('%');
89
+ const parsed = Number(isPercent ? text.slice(0, -1) : text);
90
+ if (!Number.isFinite(parsed)) {
91
+ return null;
92
+ }
93
+ return isPercent ? (parsed / 100) * percentBasis : parsed;
94
+ }
95
+ function clamp(value, min, max) {
96
+ return Math.min(max, Math.max(min, value));
97
+ }
98
+ function parseAlpha(raw) {
99
+ if (raw === undefined) {
100
+ return 1;
101
+ }
102
+ const value = parseNumber(raw, 1);
103
+ return value === null ? null : clamp(value, 0, 1);
104
+ }
105
+ function parseRgbArgs(parts) {
106
+ const alpha = parseAlpha(parts[3]);
107
+ const r = parseNumber(parts[0] ?? '', 255);
108
+ const g = parseNumber(parts[1] ?? '', 255);
109
+ const b = parseNumber(parts[2] ?? '', 255);
110
+ if (alpha === null || r === null || g === null || b === null) {
111
+ return null;
112
+ }
113
+ return { r: clamp(r, 0, 255), g: clamp(g, 0, 255), b: clamp(b, 0, 255), a: alpha };
114
+ }
115
+ function parseHslArgs(parts) {
116
+ const rawHue = parts[0] ?? '';
117
+ const hue = Number(rawHue.replace(/deg$/i, ''));
118
+ const saturation = parseNumber(parts[1] ?? '', 1);
119
+ const lightness = parseNumber(parts[2] ?? '', 1);
120
+ const alpha = parseAlpha(parts[3]);
121
+ if (!Number.isFinite(hue) || saturation === null || lightness === null || alpha === null) {
122
+ return null;
123
+ }
124
+ return { ...hslToRgb(hue, clamp(saturation, 0, 1), clamp(lightness, 0, 1)), a: alpha };
125
+ }
126
+ function hslToRgb(hue, s, l) {
127
+ // CSS Color 4 reference implementation, kept literal so it stays checkable.
128
+ const h = ((hue % 360) + 360) % 360;
129
+ const channel = (n) => {
130
+ const k = (n + h / 30) % 12;
131
+ const a = s * Math.min(l, 1 - l);
132
+ return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));
133
+ };
134
+ return { r: channel(0) * 255, g: channel(8) * 255, b: channel(4) * 255 };
135
+ }
136
+ /** WCAG 2.2 relative luminance. */
137
+ export function relativeLuminance(color) {
138
+ const linear = (channel) => {
139
+ const c = clamp(channel, 0, 255) / 255;
140
+ return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
141
+ };
142
+ return 0.2126 * linear(color.r) + 0.7152 * linear(color.g) + 0.0722 * linear(color.b);
143
+ }
144
+ /** WCAG 2.2 contrast ratio, between 1 and 21. */
145
+ export function contrastRatio(a, b) {
146
+ const la = relativeLuminance(a);
147
+ const lb = relativeLuminance(b);
148
+ const lighter = Math.max(la, lb);
149
+ const darker = Math.min(la, lb);
150
+ return (lighter + 0.05) / (darker + 0.05);
151
+ }
152
+ /**
153
+ * Composites a translucent foreground over an opaque background. A contrast
154
+ * ratio computed on the raw foreground of a translucent colour is wrong — and
155
+ * wrong in the optimistic direction — so it is composited first.
156
+ */
157
+ export function compositeOver(foreground, background) {
158
+ const a = clamp(foreground.a, 0, 1);
159
+ return {
160
+ r: foreground.r * a + background.r * (1 - a),
161
+ g: foreground.g * a + background.g * (1 - a),
162
+ b: foreground.b * a + background.b * (1 - a),
163
+ };
164
+ }
165
+ /**
166
+ * No epsilon on purpose. A pair at 4.4999:1 is below AA; rounding it up to
167
+ * "4.50" is exactly the kind of leniency that makes the guarantee a lie.
168
+ */
169
+ export function meetsContrastAa(ratio, size) {
170
+ return ratio >= aaThreshold(size);
171
+ }
172
+ /** Two decimals, the precision every WCAG reporting tool uses. */
173
+ export function formatRatio(ratio) {
174
+ return `${(Math.floor(ratio * 100) / 100).toFixed(2)}:1`;
175
+ }
176
+ //# sourceMappingURL=color.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.js","sourceRoot":"","sources":["../../src/skin/color.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { SkinTokens } from './tokens.js';
2
+ /**
3
+ * Renders a validated skin as one stylesheet of custom properties.
4
+ *
5
+ * One sheet, no build step: this file *is* the skin. Swapping a skin rewrites
6
+ * it, and nothing downstream has to be recompiled — which is what makes hot
7
+ * swap possible at all (contract D, "changement de skin = réécriture de ce
8
+ * fichier, sans build").
9
+ */
10
+ export declare const CSS_VARIABLE_PREFIX = "--cogenta";
11
+ /** `accentFg` → `accent-fg`. The variable name is part of the theme API. */
12
+ export declare function kebab(name: string): string;
13
+ export declare function cssVariableName(group: string, name: string): string;
14
+ export interface RenderSkinCssOptions {
15
+ /** Selector the variables are attached to. `:root` unless a preview scopes it. */
16
+ readonly selector?: string;
17
+ }
18
+ export declare function renderSkinCss(tokens: SkinTokens, options?: RenderSkinCssOptions): string;
19
+ //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../../src/skin/css.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,aAAa,CAAA;AAItD;;;;;;;GAOG;AAEH,eAAO,MAAM,mBAAmB,cAAc,CAAA;AAE9C,4EAA4E;AAC5E,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1C;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnE;AAiBD,MAAM,WAAW,oBAAoB;IACnC,kFAAkF;IAClF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE,oBAAyB,GAAG,MAAM,CAyC5F"}
@@ -0,0 +1,69 @@
1
+ import { TOKEN_SPECS } from './tokens.js';
2
+ import { computeTypeScale } from './validate.js';
3
+ /**
4
+ * Renders a validated skin as one stylesheet of custom properties.
5
+ *
6
+ * One sheet, no build step: this file *is* the skin. Swapping a skin rewrites
7
+ * it, and nothing downstream has to be recompiled — which is what makes hot
8
+ * swap possible at all (contract D, "changement de skin = réécriture de ce
9
+ * fichier, sans build").
10
+ */
11
+ export const CSS_VARIABLE_PREFIX = '--cogenta';
12
+ /** `accentFg` → `accent-fg`. The variable name is part of the theme API. */
13
+ export function kebab(name) {
14
+ return name.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
15
+ }
16
+ export function cssVariableName(group, name) {
17
+ return `${CSS_VARIABLE_PREFIX}-${group}-${kebab(name)}`;
18
+ }
19
+ /**
20
+ * Density is a word, and a word cannot be multiplied by a spacing unit. The
21
+ * multiplier is what a theme can actually compute with; the word is kept too,
22
+ * for container queries and debugging.
23
+ */
24
+ const DENSITY_SCALE = {
25
+ compact: '0.75',
26
+ comfortable: '1',
27
+ spacious: '1.25',
28
+ };
29
+ function declaration(name, value) {
30
+ return ` ${name}: ${value};`;
31
+ }
32
+ export function renderSkinCss(tokens, options = {}) {
33
+ const selector = options.selector ?? ':root';
34
+ const lines = [];
35
+ // TOKEN_SPECS drives the order, so the output is byte-stable for a given
36
+ // skin: a stable sheet means a stable ETag, and a cache that behaves.
37
+ for (const spec of TOKEN_SPECS) {
38
+ // The group types are object type aliases on purpose: they carry an
39
+ // implicit index signature, so a token can be read by name without a cast.
40
+ const group = tokens[spec.group];
41
+ lines.push(declaration(cssVariableName(spec.group, spec.name), String(group[spec.name])));
42
+ }
43
+ lines.push(declaration(`${CSS_VARIABLE_PREFIX}-space-scale`, DENSITY_SCALE[tokens.space.density]));
44
+ const scale = computeTypeScale(tokens);
45
+ for (const [step, size] of Object.entries(scale)) {
46
+ lines.push(declaration(`${CSS_VARIABLE_PREFIX}-font-size-${step}`, size));
47
+ }
48
+ const reducedMotion = [
49
+ '@media (prefers-reduced-motion: reduce) {',
50
+ ` ${selector} {`,
51
+ ` ${declaration(`${CSS_VARIABLE_PREFIX}-motion-duration`, '0ms')}`,
52
+ ` ${declaration(`${CSS_VARIABLE_PREFIX}-motion-easing`, 'linear')}`,
53
+ ' }',
54
+ '}',
55
+ ].join('\n');
56
+ return [
57
+ '/* Generated by @cogenta/render — skin tokens. Do not edit by hand. */',
58
+ `${selector} {`,
59
+ ...lines,
60
+ '}',
61
+ '',
62
+ // The declared `motion.reduced` is worth nothing unless the sheet acts on
63
+ // it, so the media query is emitted from the same source as the tokens
64
+ // and cannot drift away from them.
65
+ reducedMotion,
66
+ '',
67
+ ].join('\n');
68
+ }
69
+ //# sourceMappingURL=css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css.js","sourceRoot":"","sources":["../../src/skin/css.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAEhD;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAA;AAE9C,4EAA4E;AAC5E,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAA;AAClE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,IAAY;IACzD,OAAO,GAAG,mBAAmB,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAA;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,aAAa,GAA4B;IAC7C,OAAO,EAAE,MAAM;IACf,WAAW,EAAE,GAAG;IAChB,QAAQ,EAAE,MAAM;CACjB,CAAA;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,KAAa;IAC9C,OAAO,KAAK,IAAI,KAAK,KAAK,GAAG,CAAA;AAC/B,CAAC;AAOD,MAAM,UAAU,aAAa,CAAC,MAAkB,EAAE,OAAO,GAAyB,EAAE;IAClF,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAA;IAC5C,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,yEAAyE;IACzE,sEAAsE;IACtE,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,oEAAoE;QACpE,2EAA2E;QAC3E,MAAM,KAAK,GAAwD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACrF,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IAC3F,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,mBAAmB,cAAc,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAElG,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;IACtC,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,mBAAmB,cAAc,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,CAAA;IAC3E,CAAC;IAED,MAAM,aAAa,GAAG;QACpB,2CAA2C;QAC3C,KAAK,QAAQ,IAAI;QACjB,KAAK,WAAW,CAAC,GAAG,mBAAmB,kBAAkB,EAAE,KAAK,CAAC,EAAE;QACnE,KAAK,WAAW,CAAC,GAAG,mBAAmB,gBAAgB,EAAE,QAAQ,CAAC,EAAE;QACpE,KAAK;QACL,GAAG;KACJ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEZ,OAAO;QACL,wEAAwE;QACxE,GAAG,QAAQ,IAAI;QACf,GAAG,KAAK;QACR,GAAG;QACH,EAAE;QACF,0EAA0E;QAC1E,uEAAuE;QACvE,mCAAmC;QACnC,aAAa;QACb,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { CogentaError } from '@cogenta/core';
2
+ /**
3
+ * Every refusal here names what failed and by how much. "Skin invalid" is
4
+ * useless to whoever must fix it — and in L9 the author is a model, which can
5
+ * only correct what the message actually measures.
6
+ */
7
+ export interface ContrastFailure {
8
+ readonly foreground: string;
9
+ readonly background: string;
10
+ readonly foregroundValue: string;
11
+ readonly backgroundValue: string;
12
+ readonly ratio: number;
13
+ readonly required: number;
14
+ }
15
+ export declare function missingTokens(paths: readonly string[]): CogentaError;
16
+ export declare function unknownTokens(paths: readonly string[]): CogentaError;
17
+ export declare function invalidTokens(issues: readonly string[]): CogentaError;
18
+ /** Names each failing pair, its measured ratio, and the shortfall. */
19
+ export declare function insufficientContrast(failures: readonly ContrastFailure[]): CogentaError;
20
+ export declare function nonMonotonicScale(sizes: readonly number[], scale: number): CogentaError;
21
+ export declare function motionNotReduced(): CogentaError;
22
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/skin/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAG5C;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,YAAY,CAOpE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,YAAY,CAOpE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,YAAY,CAOrE;AAED,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,GAAG,YAAY,CAiBvF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAOvF;AAED,wBAAgB,gBAAgB,IAAI,YAAY,CAO/C"}
@@ -0,0 +1,59 @@
1
+ import { CogentaError } from '@cogenta/core';
2
+ import { formatRatio } from './color.js';
3
+ export function missingTokens(paths) {
4
+ return new CogentaError({
5
+ code: 'SKIN_TOKEN_MISSING',
6
+ message: `Skin is missing ${paths.length} token${paths.length === 1 ? '' : 's'}: ${paths.join(', ')}`,
7
+ hint: 'The skin token set of contract D is closed: every token must be present. Copy the missing entries from the theme default tokens.json and give them a value.',
8
+ details: { tokens: paths },
9
+ });
10
+ }
11
+ export function unknownTokens(paths) {
12
+ return new CogentaError({
13
+ code: 'SKIN_TOKEN_UNKNOWN',
14
+ message: `Skin declares ${paths.length} token${paths.length === 1 ? '' : 's'} that contract D does not define: ${paths.join(', ')}`,
15
+ hint: 'A skin may only set the frozen token set. Presentation that is not a token belongs to the theme, not to the skin.',
16
+ details: { tokens: paths },
17
+ });
18
+ }
19
+ export function invalidTokens(issues) {
20
+ return new CogentaError({
21
+ code: 'SKIN_TOKEN_INVALID',
22
+ message: `Skin has ${issues.length} invalid token value${issues.length === 1 ? '' : 's'}:\n${issues.map((i) => ` ${i}`).join('\n')}`,
23
+ hint: 'Colours must be hex, rgb() or hsl(); lengths and durations must carry a unit; no token value may contain CSS syntax such as ; { } or url().',
24
+ details: { issues },
25
+ });
26
+ }
27
+ /** Names each failing pair, its measured ratio, and the shortfall. */
28
+ export function insufficientContrast(failures) {
29
+ const lines = failures.map((f) => ` color.${f.foreground} (${f.foregroundValue}) on color.${f.background} (${f.backgroundValue}) is ${formatRatio(f.ratio)}, needs ${f.required.toFixed(1)}:1 — short by ${(f.required - f.ratio).toFixed(2)}`);
30
+ return new CogentaError({
31
+ code: 'SKIN_CONTRAST_INSUFFICIENT',
32
+ message: `Skin fails WCAG 2.2 AA contrast on ${failures.length} pair${failures.length === 1 ? '' : 's'}:\n${lines.join('\n')}`,
33
+ hint: 'Darken the foreground or lighten the background until the ratio reaches the required value. Contrast is checked at registration precisely so an unreadable skin never reaches a visitor.',
34
+ details: {
35
+ failures: failures.map((f) => ({
36
+ pair: `${f.foreground}/${f.background}`,
37
+ ratio: Number(f.ratio.toFixed(4)),
38
+ required: f.required,
39
+ })),
40
+ },
41
+ });
42
+ }
43
+ export function nonMonotonicScale(sizes, scale) {
44
+ return new CogentaError({
45
+ code: 'SKIN_SCALE_NOT_MONOTONIC',
46
+ message: `Typographic scale of ratio ${scale} is not strictly increasing: computed steps are ${sizes.join(', ')}`,
47
+ hint: 'font.scale must be greater than 1 so that each step is larger than the previous one. A ratio of 1 or below collapses the heading hierarchy.',
48
+ details: { scale, sizes },
49
+ });
50
+ }
51
+ export function motionNotReduced() {
52
+ return new CogentaError({
53
+ code: 'SKIN_MOTION_NOT_REDUCED',
54
+ message: 'Skin declares motion.reduced = false.',
55
+ hint: 'motion.reduced must be true: honouring prefers-reduced-motion is an accessibility requirement, not a skin preference. The generated stylesheet zeroes the motion duration under that media query.',
56
+ details: { token: 'motion.reduced' },
57
+ });
58
+ }
59
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/skin/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Skin system: a closed set of design tokens, validated in hard-refusal mode,
3
+ * rendered to one stylesheet of CSS custom properties and swappable without a
4
+ * build (contract D, `theme@1.0`).
5
+ */
6
+ export type { Rgb, Rgba, TextSize } from './color.js';
7
+ export { AA_LARGE_TEXT, AA_NORMAL_TEXT, aaThreshold, compositeOver, contrastRatio, formatRatio, meetsContrastAa, parseColor, relativeLuminance, } from './color.js';
8
+ export type { RenderSkinCssOptions } from './css.js';
9
+ export { CSS_VARIABLE_PREFIX, cssVariableName, renderSkinCss } from './css.js';
10
+ export type { SkinSheet, SkinStore, SkinStoreOptions } from './sheet.js';
11
+ export { createSkinStore, renderSkin } from './sheet.js';
12
+ export type { ColorTokens, ContrastPair, Density, FontTokens, MotionTokens, RadiusTokens, ShadowTokens, SkinTokens, SpaceTokens, TokenKind, TokenSpec, TypeScaleStep, } from './tokens.js';
13
+ export { CONTRAST_PAIRS, DENSITIES, TOKEN_GROUPS, TOKEN_SPECS, TYPE_SCALE_STEPS, } from './tokens.js';
14
+ export { computeTypeScale, validateSkin } from './validate.js';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/skin/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EACL,aAAa,EACb,cAAc,EACd,WAAW,EACX,aAAa,EACb,aAAa,EACb,WAAW,EACX,eAAe,EACf,UAAU,EACV,iBAAiB,GAClB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC9E,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACxE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACxD,YAAY,EACV,WAAW,EACX,YAAY,EACZ,OAAO,EACP,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,WAAW,EACX,SAAS,EACT,SAAS,EACT,aAAa,GACd,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,cAAc,EACd,SAAS,EACT,YAAY,EACZ,WAAW,EACX,gBAAgB,GACjB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Skin system: a closed set of design tokens, validated in hard-refusal mode,
3
+ * rendered to one stylesheet of CSS custom properties and swappable without a
4
+ * build (contract D, `theme@1.0`).
5
+ */
6
+ export { AA_LARGE_TEXT, AA_NORMAL_TEXT, aaThreshold, compositeOver, contrastRatio, formatRatio, meetsContrastAa, parseColor, relativeLuminance, } from './color.js';
7
+ export { CSS_VARIABLE_PREFIX, cssVariableName, renderSkinCss } from './css.js';
8
+ export { createSkinStore, renderSkin } from './sheet.js';
9
+ export { CONTRAST_PAIRS, DENSITIES, TOKEN_GROUPS, TOKEN_SPECS, TYPE_SCALE_STEPS, } from './tokens.js';
10
+ export { computeTypeScale, validateSkin } from './validate.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/skin/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,aAAa,EACb,cAAc,EACd,WAAW,EACX,aAAa,EACb,aAAa,EACb,WAAW,EACX,eAAe,EACf,UAAU,EACV,iBAAiB,GAClB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAE9E,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAexD,OAAO,EACL,cAAc,EACd,SAAS,EACT,YAAY,EACZ,WAAW,EACX,gBAAgB,GACjB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,42 @@
1
+ import type { RenderSkinCssOptions } from './css.js';
2
+ import type { SkinTokens } from './tokens.js';
3
+ /**
4
+ * Hot skin swap.
5
+ *
6
+ * A skin change validates the tokens and rewrites one stylesheet in memory.
7
+ * There is no compilation, no bundler, and no filesystem work on the critical
8
+ * path — persistence, when a deployment needs it, is an injected callback that
9
+ * runs after the new sheet is already live. That is what keeps the acceptance
10
+ * criterion ("changing a skin triggers no build and takes under a second")
11
+ * true by construction rather than by measurement.
12
+ */
13
+ export interface SkinSheet {
14
+ readonly tokens: SkinTokens;
15
+ readonly css: string;
16
+ /** Content hash of the CSS. Stable for identical tokens. */
17
+ readonly etag: string;
18
+ /** Milliseconds spent validating and rendering. */
19
+ readonly renderedIn: number;
20
+ }
21
+ /** Validates a skin and renders its sheet. Throws if the skin is refused. */
22
+ export declare function renderSkin(input: unknown, options?: RenderSkinCssOptions): SkinSheet;
23
+ export interface SkinStore {
24
+ /** The sheet currently served. */
25
+ current(): SkinSheet;
26
+ /**
27
+ * Swaps the active skin. The current sheet is replaced only once the new one
28
+ * has been validated and rendered, so a refused skin leaves the live site on
29
+ * the previous skin instead of on no skin at all.
30
+ */
31
+ apply(input: unknown): SkinSheet;
32
+ }
33
+ export interface SkinStoreOptions extends RenderSkinCssOptions {
34
+ /**
35
+ * Called after the swap, with the new sheet. Write it to disk, push it to a
36
+ * CDN, or ignore it. Failures here are the caller's to handle: the sheet is
37
+ * already live in memory by the time this runs.
38
+ */
39
+ readonly onSwap?: (sheet: SkinSheet) => void;
40
+ }
41
+ export declare function createSkinStore(initial: unknown, options?: SkinStoreOptions): SkinStore;
42
+ //# sourceMappingURL=sheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../src/skin/sheet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAG7C;;;;;;;;;GASG;AAEH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,mDAAmD;IACnD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAgBD,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,oBAAyB,GAAG,SAAS,CAKxF;AAED,MAAM,WAAW,SAAS;IACxB,kCAAkC;IAClC,OAAO,IAAI,SAAS,CAAA;IACpB;;;;OAIG;IACH,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAAA;CACjC;AAED,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAC5D;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAA;CAC7C;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS,CAc3F"}
@@ -0,0 +1,36 @@
1
+ import { renderSkinCss } from './css.js';
2
+ import { validateSkin } from './validate.js';
3
+ /**
4
+ * FNV-1a, 32-bit. Deliberately not `node:crypto`: this code also runs on the
5
+ * edge target, where the Node crypto module may not exist. The hash is a cache
6
+ * key, never a security boundary.
7
+ */
8
+ function hash(input) {
9
+ let value = 0x811c9dc5;
10
+ for (let i = 0; i < input.length; i++) {
11
+ value ^= input.charCodeAt(i);
12
+ value = Math.imul(value, 0x01000193) >>> 0;
13
+ }
14
+ return value.toString(16).padStart(8, '0');
15
+ }
16
+ /** Validates a skin and renders its sheet. Throws if the skin is refused. */
17
+ export function renderSkin(input, options = {}) {
18
+ const start = performance.now();
19
+ const tokens = validateSkin(input);
20
+ const css = renderSkinCss(tokens, options);
21
+ return { tokens, css, etag: `"${hash(css)}"`, renderedIn: performance.now() - start };
22
+ }
23
+ export function createSkinStore(initial, options = {}) {
24
+ const cssOptions = options.selector === undefined ? {} : { selector: options.selector };
25
+ let sheet = renderSkin(initial, cssOptions);
26
+ return {
27
+ current: () => sheet,
28
+ apply: (input) => {
29
+ const next = renderSkin(input, cssOptions);
30
+ sheet = next;
31
+ options.onSwap?.(next);
32
+ return next;
33
+ },
34
+ };
35
+ }
36
+ //# sourceMappingURL=sheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet.js","sourceRoot":"","sources":["../../src/skin/sheet.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAsB5C;;;;GAIG;AACH,SAAS,IAAI,CAAC,KAAa;IACzB,IAAI,KAAK,GAAG,UAAU,CAAA;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QAC5B,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,CAAA;IAC5C,CAAC;IACD,OAAO,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;AAC5C,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,UAAU,CAAC,KAAc,EAAE,OAAO,GAAyB,EAAE;IAC3E,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;IAC/B,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;IAClC,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC1C,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAA;AACvF,CAAC;AAsBD,MAAM,UAAU,eAAe,CAAC,OAAgB,EAAE,OAAO,GAAqB,EAAE;IAC9E,MAAM,UAAU,GACd,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAA;IACtE,IAAI,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;IAE3C,OAAO;QACL,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK;QACpB,KAAK,EAAE,CAAC,KAAc,EAAa,EAAE;YACnC,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;YAC1C,KAAK,GAAG,IAAI,CAAA;YACZ,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAA;YACtB,OAAO,IAAI,CAAA;QACb,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * The skin token set of contract D (`theme@1.0`).
3
+ *
4
+ * The set is *closed*: a skin that omits a token is refused, and a skin that
5
+ * adds one is refused too. Both halves matter. Omission would leave a variable
6
+ * undefined at render time; addition would let a skin smuggle in presentation
7
+ * the theme never declared, which is the door rule R3 closes on blocks and this
8
+ * closes on skins.
9
+ */
10
+ export declare const DENSITIES: readonly ['compact', 'comfortable', 'spacious'];
11
+ export type Density = (typeof DENSITIES)[number];
12
+ export type ColorTokens = {
13
+ readonly bg: string;
14
+ readonly fg: string;
15
+ readonly accent: string;
16
+ readonly accentFg: string;
17
+ readonly muted: string;
18
+ readonly mutedFg: string;
19
+ readonly border: string;
20
+ };
21
+ export type FontTokens = {
22
+ readonly sans: string;
23
+ readonly serif: string;
24
+ readonly mono: string;
25
+ /** Ratio between two consecutive steps of the typographic scale. */
26
+ readonly scale: number;
27
+ readonly baseSize: string;
28
+ };
29
+ export type SpaceTokens = {
30
+ readonly unit: string;
31
+ readonly density: Density;
32
+ };
33
+ export type RadiusTokens = {
34
+ readonly sm: string;
35
+ readonly md: string;
36
+ readonly lg: string;
37
+ };
38
+ export type MotionTokens = {
39
+ readonly duration: string;
40
+ readonly easing: string;
41
+ /** Declares that the skin honours `prefers-reduced-motion`. Must be true. */
42
+ readonly reduced: boolean;
43
+ };
44
+ export type ShadowTokens = {
45
+ readonly sm: string;
46
+ readonly md: string;
47
+ };
48
+ export interface SkinTokens {
49
+ readonly color: ColorTokens;
50
+ readonly font: FontTokens;
51
+ readonly space: SpaceTokens;
52
+ readonly radius: RadiusTokens;
53
+ readonly motion: MotionTokens;
54
+ readonly shadow: ShadowTokens;
55
+ }
56
+ /** Kinds drive both the structural check and the CSS emitted for a token. */
57
+ export type TokenKind = 'color' | 'length' | 'duration' | 'ratio' | 'text' | 'boolean' | 'density';
58
+ export interface TokenSpec {
59
+ readonly group: keyof SkinTokens;
60
+ readonly name: string;
61
+ readonly kind: TokenKind;
62
+ }
63
+ /**
64
+ * The single source of truth. Validation, CSS rendering and the error messages
65
+ * all read this list, so a token can never exist in one and not the others.
66
+ */
67
+ export declare const TOKEN_SPECS: readonly TokenSpec[];
68
+ export declare const TOKEN_GROUPS: readonly (keyof SkinTokens)[];
69
+ /**
70
+ * The contrast pairs contract D declares, with the text size each one carries.
71
+ *
72
+ * All three are checked at the *normal text* threshold, not the large-text one.
73
+ * `accentFg` on `accent` is the label of a button, `mutedFg` on `muted` is the
74
+ * body of a callout: both routinely carry body-sized text. Declaring them
75
+ * "large" would double the accepted colour space and quietly break real pages.
76
+ * The 3:1 threshold stays available through `meetsContrastAa` for tokens that
77
+ * genuinely only ever carry large text — there are none in `theme@1.0`.
78
+ */
79
+ export interface ContrastPair {
80
+ readonly foreground: keyof ColorTokens;
81
+ readonly background: keyof ColorTokens;
82
+ readonly size: 'normal' | 'large';
83
+ }
84
+ export declare const CONTRAST_PAIRS: readonly ContrastPair[];
85
+ /** Steps of the generated typographic scale, from smallest to largest. */
86
+ export declare const TYPE_SCALE_STEPS: readonly ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl'];
87
+ export type TypeScaleStep = (typeof TYPE_SCALE_STEPS)[number];
88
+ /** `md` is the base size; steps below it divide by the ratio, above multiply. */
89
+ export declare const TYPE_SCALE_BASE_INDEX = 2;
90
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/skin/tokens.ts"],"names":[],"mappings":"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"}