@uni-design-system/uni-core 4.0.0 → 5.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 (48) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/index.cjs +1492 -852
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/esm/index.js +1468 -853
  5. package/dist/esm/index.js.map +1 -1
  6. package/dist/types/concepts/color/color.factory.d.ts +48 -0
  7. package/dist/types/concepts/color/color.factory.d.ts.map +1 -0
  8. package/dist/types/concepts/color/color.helper.d.ts +15 -0
  9. package/dist/types/concepts/color/color.helper.d.ts.map +1 -1
  10. package/dist/types/concepts/color/color.records.d.ts +9 -0
  11. package/dist/types/concepts/color/color.records.d.ts.map +1 -1
  12. package/dist/types/concepts/color/color.utils.d.ts +17 -0
  13. package/dist/types/concepts/color/color.utils.d.ts.map +1 -1
  14. package/dist/types/concepts/color/index.d.ts +1 -0
  15. package/dist/types/concepts/color/index.d.ts.map +1 -1
  16. package/dist/types/concepts/component/component.types.d.ts +8 -2
  17. package/dist/types/concepts/component/component.types.d.ts.map +1 -1
  18. package/dist/types/concepts/generation/generation.spec.d.ts +2 -0
  19. package/dist/types/concepts/generation/generation.spec.d.ts.map +1 -0
  20. package/dist/types/concepts/generation/generation.types.d.ts +60 -0
  21. package/dist/types/concepts/generation/generation.types.d.ts.map +1 -0
  22. package/dist/types/concepts/generation/index.d.ts +7 -0
  23. package/dist/types/concepts/generation/index.d.ts.map +1 -0
  24. package/dist/types/concepts/generation/oklch.helper.d.ts +22 -0
  25. package/dist/types/concepts/generation/oklch.helper.d.ts.map +1 -0
  26. package/dist/types/concepts/generation/palette.factory.d.ts +23 -0
  27. package/dist/types/concepts/generation/palette.factory.d.ts.map +1 -0
  28. package/dist/types/concepts/generation/shadow.generator.d.ts +13 -0
  29. package/dist/types/concepts/generation/shadow.generator.d.ts.map +1 -0
  30. package/dist/types/concepts/generation/theme-file.emitter.d.ts +26 -0
  31. package/dist/types/concepts/generation/theme-file.emitter.d.ts.map +1 -0
  32. package/dist/types/concepts/generation/theme.generator.d.ts +30 -0
  33. package/dist/types/concepts/generation/theme.generator.d.ts.map +1 -0
  34. package/dist/types/concepts/index.d.ts +1 -0
  35. package/dist/types/concepts/index.d.ts.map +1 -1
  36. package/dist/types/concepts/style/style.types.d.ts +3 -1
  37. package/dist/types/concepts/style/style.types.d.ts.map +1 -1
  38. package/dist/types/concepts/theme/theme.model.d.ts +14 -14
  39. package/dist/types/concepts/theme/theme.model.d.ts.map +1 -1
  40. package/dist/types/concepts/theme/themes/base.theme.d.ts +44 -1
  41. package/dist/types/concepts/theme/themes/base.theme.d.ts.map +1 -1
  42. package/dist/types/concepts/theme/themes/dark.theme.d.ts +3 -2
  43. package/dist/types/concepts/theme/themes/dark.theme.d.ts.map +1 -1
  44. package/dist/types/concepts/theme/themes/light.theme.d.ts +1 -2
  45. package/dist/types/concepts/theme/themes/light.theme.d.ts.map +1 -1
  46. package/package.json +5 -1
  47. package/dist/types/concepts/theme/themes/square.theme.d.ts +0 -3
  48. package/dist/types/concepts/theme/themes/square.theme.d.ts.map +0 -1
package/dist/esm/index.js CHANGED
@@ -29,6 +29,11 @@ var collapseFadeOut = {
29
29
  };
30
30
  //#endregion
31
31
  //#region src/concepts/color/color.records.ts
32
+ /**
33
+ * @deprecated HSL saturation ranges are superseded by the perceptual OKLCH
34
+ * chroma model inside `concepts/generation` (see `generateThemes`). Kept for
35
+ * legacy callers of `uniColor`; removal follows the changeset major process.
36
+ */
32
37
  var CategorySaturation = {
33
38
  jewel: {
34
39
  low: 73,
@@ -55,6 +60,10 @@ var CategorySaturation = {
55
60
  high: 0
56
61
  }
57
62
  };
63
+ /**
64
+ * @deprecated HSL lightness ranges are superseded by the perceptual OKLCH
65
+ * tone slots inside `concepts/generation` (see `generateThemes`).
66
+ */
58
67
  var CategoryLightness = {
59
68
  jewel: {
60
69
  low: 56,
@@ -130,6 +139,11 @@ var RoleHues = {
130
139
  };
131
140
  //#endregion
132
141
  //#region src/concepts/color/color.utils.ts
142
+ /**
143
+ * @deprecated Randomized generation is superseded by the deterministic OKLCH
144
+ * engine in `concepts/generation` — same input, same theme. Seeded "surprise
145
+ * me" behavior belongs in the consumer (playground), not the engine.
146
+ */
133
147
  var randomRangeValue = ({ low, high }) => {
134
148
  low = Math.ceil(low);
135
149
  high = Math.floor(high);
@@ -144,6 +158,52 @@ var getAnalogousHues = (hue) => [cycle(hue + 30), cycle(hue + 60)];
144
158
  var getComplimentaryHue = (hue) => cycle(hue + 180);
145
159
  var getTriadicHues = (hue) => [cycle(hue + 120), cycle(hue - 120)];
146
160
  var getSplitComplimentaryHues = (hue) => [cycle(hue + 150), cycle(hue - 150)];
161
+ /**
162
+ * Derive the primary/secondary/tertiary hues from a seed hue using the color
163
+ * wheel relationships in {@link ColorScheme}. Pure angle math — works in any
164
+ * hue space (HSL historically, OKLCH in the generation engine).
165
+ */
166
+ var schemeHues = (hue, scheme) => {
167
+ switch (scheme) {
168
+ case "monochromatic": return {
169
+ primary: hue,
170
+ secondary: hue,
171
+ tertiary: hue
172
+ };
173
+ case "analogous": {
174
+ const [a, b] = getAnalogousHues(hue);
175
+ return {
176
+ primary: hue,
177
+ secondary: a,
178
+ tertiary: b
179
+ };
180
+ }
181
+ case "complimentary": {
182
+ const [a] = getAnalogousHues(hue);
183
+ return {
184
+ primary: hue,
185
+ secondary: getComplimentaryHue(hue),
186
+ tertiary: a
187
+ };
188
+ }
189
+ case "splitComplimentary": {
190
+ const [a, b] = getSplitComplimentaryHues(hue);
191
+ return {
192
+ primary: hue,
193
+ secondary: a,
194
+ tertiary: b
195
+ };
196
+ }
197
+ case "triadic": {
198
+ const [a, b] = getTriadicHues(hue);
199
+ return {
200
+ primary: hue,
201
+ secondary: a,
202
+ tertiary: b
203
+ };
204
+ }
205
+ }
206
+ };
147
207
  //#endregion
148
208
  //#region src/concepts/color/color.helper.ts
149
209
  function HSLAToString({ hue, saturation, lightness, alpha = 1 }) {
@@ -152,6 +212,11 @@ function HSLAToString({ hue, saturation, lightness, alpha = 1 }) {
152
212
  function RGBToString({ red, green, blue }) {
153
213
  return `rgb(${red}, ${green}, ${blue})`;
154
214
  }
215
+ /**
216
+ * @deprecated Random HSL generation produces non-deterministic, perceptually
217
+ * uneven colors. Use the OKLCH engine (`generateThemes` in
218
+ * `concepts/generation`) or `generatePalette` instead.
219
+ */
155
220
  function uniColor({ role, category, alpha = 1 }) {
156
221
  return HSLAToString({
157
222
  hue: randomRangeValue(RoleHues[role]),
@@ -173,234 +238,567 @@ var RGBToHSL = ({ red, green, blue }) => {
173
238
  lightness: 100 * (2 * l - s) / 2
174
239
  };
175
240
  };
176
- //#endregion
177
- //#region src/concepts/elevation/zIndex.ts
178
- var Z_INDEX = {
179
- dropdown: 1e3,
180
- sticky: 1020,
181
- fixed: 1030,
182
- backdrop: 1040,
183
- dialog: 1050,
184
- popover: 1060,
185
- tooltip: 1070,
186
- overlay: 1080
241
+ var clamp$2 = (value, min, max) => Math.min(max, Math.max(min, value));
242
+ var toHex2 = (value) => clamp$2(Math.round(value), 0, 255).toString(16).padStart(2, "0");
243
+ var rgbToHex = ({ red, green, blue }) => `#${toHex2(red)}${toHex2(green)}${toHex2(blue)}`.toUpperCase();
244
+ var hexToRgb = (hex) => {
245
+ let h = hex.replace("#", "").trim();
246
+ if (h.length === 3) h = h.split("").map((c) => c + c).join("");
247
+ const int = parseInt(h, 16);
248
+ return {
249
+ red: int >> 16 & 255,
250
+ green: int >> 8 & 255,
251
+ blue: int & 255
252
+ };
187
253
  };
188
- //#endregion
189
- //#region src/concepts/gradient/gradient.helper.ts
190
- function gradient(config) {
191
- return ``;
192
- }
193
- //#endregion
194
- //#region src/concepts/layout/layout.helper.ts
195
- function getDeviceSize(height, width) {
196
- if (!height || !width) return "md";
197
- const max = Math.max(height, width);
198
- if (max <= 600) return "xs";
199
- if (max <= 960) return "sm";
200
- if (max <= 1264) return "md";
201
- if (max <= 1904) return "lg";
202
- return "xl";
203
- }
204
- function getDeviceOrientation(height, width) {
205
- if (!height || !width) return "landscape";
206
- return height > width ? "portrait" : "landscape";
207
- }
208
- //#endregion
209
- //#region src/concepts/shadow/shadow.utils.ts
210
- var GetBoxShadow = ({ offset, blur, opacity }) => {
211
- return `0 ${offset}px ${blur}px rgba(0,0,0,0.${opacity})`;
254
+ var HSLToRGB = ({ hue = 0, saturation = 0, lightness = 0 }) => {
255
+ const s = clamp$2(saturation, 0, 100) / 100;
256
+ const l = clamp$2(lightness, 0, 100) / 100;
257
+ const c = (1 - Math.abs(2 * l - 1)) * s;
258
+ const hp = (hue % 360 + 360) % 360 / 60;
259
+ const x = c * (1 - Math.abs(hp % 2 - 1));
260
+ const [r1, g1, b1] = hp < 1 ? [
261
+ c,
262
+ x,
263
+ 0
264
+ ] : hp < 2 ? [
265
+ x,
266
+ c,
267
+ 0
268
+ ] : hp < 3 ? [
269
+ 0,
270
+ c,
271
+ x
272
+ ] : hp < 4 ? [
273
+ 0,
274
+ x,
275
+ c
276
+ ] : hp < 5 ? [
277
+ x,
278
+ 0,
279
+ c
280
+ ] : [
281
+ c,
282
+ 0,
283
+ x
284
+ ];
285
+ const m = l - c / 2;
286
+ return {
287
+ red: (r1 + m) * 255,
288
+ green: (g1 + m) * 255,
289
+ blue: (b1 + m) * 255
290
+ };
212
291
  };
213
- var GetBoxShadows = ({ umbra, penumbra }) => {
214
- return GetBoxShadow(umbra) + ", " + GetBoxShadow(penumbra);
292
+ /** Build an sRGB hex string straight from HSL channel values. */
293
+ var HSLToHex = (hsl) => rgbToHex(HSLToRGB(hsl));
294
+ var hexToHSL = (hex) => RGBToHSL(hexToRgb(hex));
295
+ /** WCAG relative luminance of an sRGB color (0 = black, 1 = white). */
296
+ var relativeLuminance = ({ red, green, blue }) => {
297
+ const channel = (value) => {
298
+ const v = value / 255;
299
+ return v <= .03928 ? v / 12.92 : Math.pow((v + .055) / 1.055, 2.4);
300
+ };
301
+ return .2126 * channel(red) + .7152 * channel(green) + .0722 * channel(blue);
302
+ };
303
+ /** WCAG contrast ratio between two colors (1:1 – 21:1). Accepts RGB or hex. */
304
+ var contrastRatio = (a, b) => {
305
+ const la = relativeLuminance(typeof a === "string" ? hexToRgb(a) : a);
306
+ const lb = relativeLuminance(typeof b === "string" ? hexToRgb(b) : b);
307
+ const [hi, lo] = la > lb ? [la, lb] : [lb, la];
308
+ return (hi + .05) / (lo + .05);
215
309
  };
216
310
  //#endregion
217
- //#region src/concepts/shadow/shadow.records.ts
218
- var ShadowMap = {
219
- pressed: {
220
- umbra: {
221
- offset: 1,
222
- blur: 2,
223
- opacity: 24
224
- },
225
- penumbra: {
226
- offset: 1,
227
- blur: 3,
228
- opacity: 12
229
- }
230
- },
231
- raised: {
232
- umbra: {
233
- offset: 3,
234
- blur: 6,
235
- opacity: 23
236
- },
237
- penumbra: {
238
- offset: 3,
239
- blur: 6,
240
- opacity: 16
241
- }
242
- },
243
- focussed: {
244
- umbra: {
245
- offset: 6,
246
- blur: 6,
247
- opacity: 23
248
- },
249
- penumbra: {
250
- offset: 10,
251
- blur: 20,
252
- opacity: 19
311
+ //#region src/concepts/generation/oklch.helper.ts
312
+ var clamp$1 = (value, min, max) => Math.min(max, Math.max(min, value));
313
+ var srgbToLinear = (channel) => channel <= .04045 ? channel / 12.92 : Math.pow((channel + .055) / 1.055, 2.4);
314
+ var linearToSrgb = (channel) => channel <= .0031308 ? 12.92 * channel : 1.055 * Math.pow(channel, 1 / 2.4) - .055;
315
+ var linearRgbToOklab = ({ r, g, b }) => {
316
+ const l = Math.cbrt(.4122214708 * r + .5363325363 * g + .0514459929 * b);
317
+ const m = Math.cbrt(.2119034982 * r + .6806995451 * g + .1073969566 * b);
318
+ const s = Math.cbrt(.0883024619 * r + .2817188376 * g + .6299787005 * b);
319
+ return {
320
+ l: .2104542553 * l + .793617785 * m - .0040720468 * s,
321
+ a: 1.9779984951 * l - 2.428592205 * m + .4505937099 * s,
322
+ b: .0259040371 * l + .7827717662 * m - .808675766 * s
323
+ };
324
+ };
325
+ var oklabToLinearRgb = (l, a, b) => {
326
+ const l_ = Math.pow(l + .3963377774 * a + .2158037573 * b, 3);
327
+ const m_ = Math.pow(l - .1055613458 * a - .0638541728 * b, 3);
328
+ const s_ = Math.pow(l - .0894841775 * a - 1.291485548 * b, 3);
329
+ return {
330
+ r: 4.0767416621 * l_ - 3.3077115913 * m_ + .2309699292 * s_,
331
+ g: -1.2684380046 * l_ + 2.6097574011 * m_ - .3413193965 * s_,
332
+ b: -.0041960863 * l_ - .7034186147 * m_ + 1.707614701 * s_
333
+ };
334
+ };
335
+ var oklchToLinearRgb = ({ l, c, h }) => {
336
+ const rad = h * Math.PI / 180;
337
+ return oklabToLinearRgb(l, c * Math.cos(rad), c * Math.sin(rad));
338
+ };
339
+ var GAMUT_EPSILON = 1e-4;
340
+ var inSrgbGamut = ({ r, g, b }) => r >= -GAMUT_EPSILON && r <= 1 + GAMUT_EPSILON && g >= -GAMUT_EPSILON && g <= 1 + GAMUT_EPSILON && b >= -GAMUT_EPSILON && b <= 1 + GAMUT_EPSILON;
341
+ /** Parse a hex color (`#RGB` or `#RRGGBB`) into OKLCH. */
342
+ var hexToOklch = (hex) => {
343
+ const { red, green, blue } = hexToRgb(hex);
344
+ const { l, a, b } = linearRgbToOklab({
345
+ r: srgbToLinear(red / 255),
346
+ g: srgbToLinear(green / 255),
347
+ b: srgbToLinear(blue / 255)
348
+ });
349
+ const c = Math.hypot(a, b);
350
+ const h = c < 1e-6 ? 0 : Math.atan2(b, a) * 180 / Math.PI;
351
+ return {
352
+ l,
353
+ c,
354
+ h: h < 0 ? h + 360 : h
355
+ };
356
+ };
357
+ /**
358
+ * Render OKLCH as an sRGB hex string. Out-of-gamut colors are mapped back
359
+ * into sRGB by reducing chroma only — lightness and hue are preserved, so
360
+ * vivid seeds desaturate gracefully instead of shifting hue or clipping.
361
+ */
362
+ var oklchToHex = (color) => {
363
+ const target = {
364
+ l: clamp$1(color.l, 0, 1),
365
+ c: Math.max(color.c, 0),
366
+ h: color.h
367
+ };
368
+ let rgb = oklchToLinearRgb(target);
369
+ if (!inSrgbGamut(rgb)) {
370
+ let low = 0;
371
+ let high = target.c;
372
+ for (let i = 0; i < 24; i++) {
373
+ const mid = (low + high) / 2;
374
+ if (inSrgbGamut(oklchToLinearRgb({
375
+ ...target,
376
+ c: mid
377
+ }))) low = mid;
378
+ else high = mid;
253
379
  }
380
+ rgb = oklchToLinearRgb({
381
+ ...target,
382
+ c: low
383
+ });
384
+ }
385
+ return rgbToHex(toSrgb255(rgb));
386
+ };
387
+ var toSrgb255 = ({ r, g, b }) => ({
388
+ red: 255 * linearToSrgb(clamp$1(r, 0, 1)),
389
+ green: 255 * linearToSrgb(clamp$1(g, 0, 1)),
390
+ blue: 255 * linearToSrgb(clamp$1(b, 0, 1))
391
+ });
392
+ //#endregion
393
+ //#region src/concepts/generation/palette.factory.ts
394
+ var toneMap = (dark) => dark ? {
395
+ accent: .78,
396
+ container: .42,
397
+ roleSurface: .26,
398
+ background: .18,
399
+ surface: .21,
400
+ surfaceVariant: .32,
401
+ outline: .66,
402
+ onSurface: .93,
403
+ mutedText: .76,
404
+ inverse: .93,
405
+ onInverse: .25,
406
+ onDeep: .2,
407
+ onLight: .985,
408
+ grey: .72,
409
+ disabledContainer: .3
410
+ } : {
411
+ accent: .55,
412
+ container: .9,
413
+ roleSurface: .97,
414
+ background: .995,
415
+ surface: .985,
416
+ surfaceVariant: .94,
417
+ outline: .6,
418
+ onSurface: .25,
419
+ mutedText: .48,
420
+ inverse: .3,
421
+ onInverse: .97,
422
+ onDeep: .24,
423
+ onLight: .985,
424
+ grey: .5,
425
+ disabledContainer: .96
426
+ };
427
+ var CategoryChroma = {
428
+ jewel: .17,
429
+ pastel: .055,
430
+ earth: .08,
431
+ neutral: .03,
432
+ florescent: .26,
433
+ shades: 0
434
+ };
435
+ /** Dark-mode accents cap chroma so they don't vibrate on dark surfaces. */
436
+ var DARK_ACCENT_CHROMA_CAP = .16;
437
+ var SemanticColors = {
438
+ error: {
439
+ hue: 27,
440
+ chroma: .2
254
441
  },
255
- navigation: {
256
- umbra: {
257
- offset: 10,
258
- blur: 10,
259
- opacity: 22
260
- },
261
- penumbra: {
262
- offset: 14,
263
- blur: 28,
264
- opacity: 25
265
- }
442
+ warn: {
443
+ hue: 55,
444
+ chroma: .18
266
445
  },
267
- modal: {
268
- umbra: {
269
- offset: 15,
270
- blur: 12,
271
- opacity: 22
272
- },
273
- penumbra: {
274
- offset: 19,
275
- blur: 38,
276
- opacity: 30
277
- }
446
+ success: {
447
+ hue: 152,
448
+ chroma: .16
278
449
  }
279
450
  };
280
- var ShadowCssMap = {
281
- pressed: GetBoxShadows(ShadowMap["pressed"]),
282
- raised: GetBoxShadows(ShadowMap["raised"]),
283
- focussed: GetBoxShadows(ShadowMap["focussed"]),
284
- navigation: GetBoxShadows(ShadowMap["navigation"]),
285
- modal: GetBoxShadows(ShadowMap["modal"])
451
+ var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
452
+ /**
453
+ * Generate a complete {@link Colors} token set in OKLCH. Same contract as
454
+ * `generatePalette` (which delegates here), plus soft brand targets and a
455
+ * contrast-check sink for {@link ContrastReport} consumers.
456
+ */
457
+ var generateColors = (config) => {
458
+ const { seed, scheme, category, mode = "light", accentSaturationFloor = 18, brand = {}, targets = {}, checks } = config;
459
+ const dark = mode === "dark";
460
+ const t = toneMap(dark);
461
+ const anchor = hexToOklch(brand.primary ?? targets.primary ?? seed);
462
+ const hues = schemeHues(anchor.h, scheme);
463
+ const chromaFloor = accentSaturationFloor / 100 * .28;
464
+ let accentC = Math.max(CategoryChroma[category], chromaFloor);
465
+ if (dark) accentC = Math.min(accentC, DARK_ACCENT_CHROMA_CAP);
466
+ const containerC = Math.max(CategoryChroma[category] * .45, accentC * .35);
467
+ const surfaceC = Math.min(CategoryChroma[category], .012);
468
+ const tone = (hue, c, l) => oklchToHex({
469
+ l,
470
+ c,
471
+ h: hue
472
+ });
473
+ /**
474
+ * The WCAG guard-rail: walk the foreground's OKLCH lightness away from the
475
+ * background until the pair meets `target` (≤ 50 steps). Hue is never
476
+ * touched; chroma only shrinks as a last resort when L runs out of room.
477
+ */
478
+ const ensureContrast = (fg, bg, target) => {
479
+ const out = { ...fg };
480
+ let hex = oklchToHex(out);
481
+ if (contrastRatio(hex, bg) >= target) return out;
482
+ const bgY = relativeLuminance(hexToRgb(bg));
483
+ const darkCeiling = (bgY + .05) / .05;
484
+ const lightCeiling = 1.05 / (bgY + .05);
485
+ let lighten = relativeLuminance(hexToRgb(hex)) >= bgY;
486
+ if (lighten && lightCeiling < target && darkCeiling >= target) lighten = false;
487
+ if (!lighten && darkCeiling < target && lightCeiling >= target) lighten = true;
488
+ const step = lighten ? .015 : -.015;
489
+ for (let i = 0; i < 50 && contrastRatio(hex, bg) < target; i++) {
490
+ if (step > 0 && out.l < .995 || step < 0 && out.l > .02) out.l = clamp(out.l + step, 0, 1);
491
+ else out.c = Math.max(0, out.c - .02);
492
+ hex = oklchToHex(out);
493
+ }
494
+ return out;
495
+ };
496
+ /** Guard-railed token: adjust toward `target` contrast, then record the pair. */
497
+ const contrasted = (fg, bgHex, target) => oklchToHex(ensureContrast(fg, bgHex, target));
498
+ const record = (foreground, background, foregroundColor, backgroundColor, required) => {
499
+ if (!checks) return;
500
+ const ratio = contrastRatio(foregroundColor, backgroundColor);
501
+ checks.push({
502
+ mode,
503
+ foreground,
504
+ background,
505
+ foregroundColor,
506
+ backgroundColor,
507
+ ratio: Math.round(ratio * 100) / 100,
508
+ required,
509
+ pass: ratio >= required,
510
+ level: ratio < required ? "fail" : ratio >= 7 ? "AAA" : "AA"
511
+ });
512
+ };
513
+ const background = tone(anchor.h, surfaceC, t.background);
514
+ const surface = tone(anchor.h, surfaceC, t.surface);
515
+ const surfaceVariant = tone(anchor.h, surfaceC, t.surfaceVariant);
516
+ const onColor = (hue, bg, c) => {
517
+ const deep = {
518
+ l: t.onDeep,
519
+ c: Math.min(c, .05),
520
+ h: hue
521
+ };
522
+ const light = {
523
+ l: t.onLight,
524
+ c: Math.min(c, .02),
525
+ h: hue
526
+ };
527
+ return contrasted(contrastRatio(oklchToHex(deep), bg) >= contrastRatio(oklchToHex(light), bg) ? deep : light, bg, 4.5);
528
+ };
529
+ const adaptPinForDark = (hex) => {
530
+ const pin = hexToOklch(hex);
531
+ pin.l = Math.max(pin.l, .6);
532
+ return oklchToHex(ensureContrast(pin, background, 3));
533
+ };
534
+ /**
535
+ * Resolve a role's base color: hard pins are verbatim in light mode and
536
+ * lightness-lifted in dark; soft targets and generated tones are pulled to
537
+ * ≥ 4.5:1 as standalone ink on `background` and `surface` (§3.6).
538
+ */
539
+ const baseFor = (name, hue, c) => {
540
+ const pinned = brand[name];
541
+ if (pinned) return dark ? adaptPinForDark(pinned) : pinned;
542
+ const target = targets[name];
543
+ let base;
544
+ if (target) {
545
+ base = hexToOklch(target);
546
+ if (dark) {
547
+ base.c = Math.min(base.c, DARK_ACCENT_CHROMA_CAP);
548
+ base.l = Math.max(base.l, t.accent - .08);
549
+ }
550
+ } else base = {
551
+ l: t.accent,
552
+ c,
553
+ h: hue
554
+ };
555
+ return oklchToHex(ensureContrast(ensureContrast(base, background, 4.5), surface, 4.5));
556
+ };
557
+ const disabled = dark ? "rgba(255,255,255,0.12)" : "rgba(0,0,0,0.12)";
558
+ const onDisabled = dark ? "rgba(255,255,255,0.38)" : "rgba(0,0,0,0.38)";
559
+ const role = (name, base, cC = containerC) => {
560
+ const { h, c } = hexToOklch(base);
561
+ const container = tone(h, cC, t.container);
562
+ const roleSurface = tone(h, surfaceC, t.roleSurface);
563
+ const onBase = onColor(h, base, c);
564
+ const onContainer = onColor(h, container, c);
565
+ const onContainerVariant = contrasted({
566
+ l: t.mutedText,
567
+ c: Math.min(cC, .06),
568
+ h
569
+ }, container, 4.5);
570
+ const borderHex = oklchToHex(ensureContrast(ensureContrast(hexToOklch(base), container, 3), surface, 3));
571
+ const onRoleSurface = onColor(h, roleSurface, surfaceC);
572
+ const onRoleSurfaceVariant = contrasted(hexToOklch(base), roleSurface, 4.5);
573
+ record(`on-${name}`, name, onBase, base, 4.5);
574
+ record(`on-${name}-container`, `${name}-container`, onContainer, container, 4.5);
575
+ record(`on-${name}-container-variant`, `${name}-container`, onContainerVariant, container, 4.5);
576
+ record(`on-${name}-container-border`, `${name}-container`, borderHex, container, 3);
577
+ record(`on-${name}-container-border`, "surface", borderHex, surface, 3);
578
+ record(`on-${name}-surface`, `${name}-surface`, onRoleSurface, roleSurface, 4.5);
579
+ record(`on-${name}-surface-variant`, `${name}-surface`, onRoleSurfaceVariant, roleSurface, 4.5);
580
+ record(name, "background", base, background, 4.5);
581
+ record(name, "surface", base, surface, 4.5);
582
+ return {
583
+ [name]: base,
584
+ [`on-${name}`]: onBase,
585
+ [`${name}-container`]: container,
586
+ [`on-${name}-container`]: onContainer,
587
+ [`on-${name}-container-variant`]: onContainerVariant,
588
+ [`on-${name}-container-border`]: borderHex,
589
+ [`${name}-surface`]: roleSurface,
590
+ [`on-${name}-surface`]: onRoleSurface,
591
+ [`on-${name}-surface-variant`]: onRoleSurfaceVariant
592
+ };
593
+ };
594
+ const primaryBase = baseFor("primary", hues.primary, accentC);
595
+ const secondaryBase = baseFor("secondary", hues.secondary, accentC);
596
+ const tertiaryBase = baseFor("tertiary", hues.tertiary, accentC);
597
+ const quaternaryGrey = brand.quaternary ? dark ? adaptPinForDark(brand.quaternary) : brand.quaternary : oklchToHex(ensureContrast({
598
+ l: t.grey,
599
+ c: surfaceC,
600
+ h: anchor.h
601
+ }, surface, 3));
602
+ const quaternarySurface = tone(anchor.h, surfaceC, t.roleSurface);
603
+ const onQuaternary = onColor(anchor.h, quaternaryGrey, surfaceC);
604
+ const onQuaternarySurface = onColor(anchor.h, quaternarySurface, surfaceC);
605
+ const onQuaternarySurfaceVariant = contrasted(hexToOklch(primaryBase), quaternarySurface, 4.5);
606
+ const onQuaternaryContainerVariant = contrasted({
607
+ l: t.mutedText,
608
+ c: Math.min(containerC, .06),
609
+ h: anchor.h
610
+ }, quaternarySurface, 4.5);
611
+ record("on-quaternary", "quaternary", onQuaternary, quaternaryGrey, 4.5);
612
+ record("on-quaternary-surface", "quaternary-surface", onQuaternarySurface, quaternarySurface, 4.5);
613
+ record("on-quaternary-surface-variant", "quaternary-surface", onQuaternarySurfaceVariant, quaternarySurface, 4.5);
614
+ const semantic = (name) => {
615
+ const { hue, chroma } = SemanticColors[name];
616
+ const base = baseFor(name, hue, dark ? Math.min(chroma, DARK_ACCENT_CHROMA_CAP) : chroma);
617
+ const { h } = hexToOklch(base);
618
+ const container = tone(h, containerC + .04, t.container);
619
+ const onBase = onColor(h, base, chroma);
620
+ const onContainer = onColor(h, container, chroma);
621
+ record(`on-${name}`, name, onBase, base, 4.5);
622
+ record(`on-${name}-container`, `${name}-container`, onContainer, container, 4.5);
623
+ record(name, "background", base, background, 4.5);
624
+ record(name, "surface", base, surface, 4.5);
625
+ return {
626
+ base,
627
+ container,
628
+ onBase,
629
+ onContainer,
630
+ h
631
+ };
632
+ };
633
+ const error = semantic("error");
634
+ const warn = semantic("warn");
635
+ const success = semantic("success");
636
+ const semanticExtras = (name, s) => {
637
+ const variant = contrasted({
638
+ l: t.mutedText,
639
+ c: .06,
640
+ h: s.h
641
+ }, s.container, 4.5);
642
+ const border = oklchToHex(ensureContrast(ensureContrast(hexToOklch(s.base), s.container, 3), surface, 3));
643
+ record(`on-${name}-container-variant`, `${name}-container`, variant, s.container, 4.5);
644
+ record(`on-${name}-container-border`, `${name}-container`, border, s.container, 3);
645
+ return {
646
+ variant,
647
+ border
648
+ };
649
+ };
650
+ const warnExtras = semanticExtras("warn", warn);
651
+ const successExtras = semanticExtras("success", success);
652
+ const onBackground = tone(anchor.h, surfaceC, t.onSurface);
653
+ const onBackgroundVariant = contrasted({
654
+ l: t.mutedText,
655
+ c: surfaceC,
656
+ h: anchor.h
657
+ }, background, 4.5);
658
+ const onSurface = tone(anchor.h, surfaceC, t.onSurface);
659
+ const onSurfaceVariant = contrasted({
660
+ l: dark ? t.mutedText : t.mutedText - .14,
661
+ c: surfaceC,
662
+ h: anchor.h
663
+ }, surfaceVariant, 4.5);
664
+ record("on-background", "background", onBackground, background, 4.5);
665
+ record("on-background-variant", "background", onBackgroundVariant, background, 4.5);
666
+ record("on-surface", "surface", onSurface, surface, 4.5);
667
+ record("on-surface-variant", "surface-variant", onSurfaceVariant, surfaceVariant, 4.5);
668
+ const inverseSurface = tone(anchor.h, surfaceC, t.inverse);
669
+ const onInverse = tone(anchor.h, surfaceC, t.onInverse);
670
+ const inversePrimary = contrasted(hexToOklch(primaryBase), inverseSurface, 4.5);
671
+ record("on-inverse-surface", "inverse-surface", onInverse, inverseSurface, 4.5);
672
+ record("on-inverse-surface-primary", "inverse-surface", inversePrimary, inverseSurface, 4.5);
673
+ record("on-inverse-container", "inverse-container", onInverse, inverseSurface, 4.5);
674
+ const outline = oklchToHex(ensureContrast(ensureContrast({
675
+ l: t.outline,
676
+ c: Math.min(surfaceC, .02),
677
+ h: hues.primary
678
+ }, surface, 3), background, 3));
679
+ record("outline", "surface", outline, surface, 3);
680
+ record("outline", "background", outline, background, 3);
681
+ return {
682
+ ...role("primary", primaryBase),
683
+ ...role("secondary", secondaryBase),
684
+ ...role("tertiary", tertiaryBase),
685
+ quaternary: quaternaryGrey,
686
+ "on-quaternary": onQuaternary,
687
+ "quaternary-surface": quaternarySurface,
688
+ "on-quaternary-surface": onQuaternarySurface,
689
+ "on-quaternary-surface-variant": onQuaternarySurfaceVariant,
690
+ "on-quaternary-container-variant": onQuaternaryContainerVariant,
691
+ "on-quaternary-container-border": quaternaryGrey,
692
+ error: error.base,
693
+ "on-error": error.onBase,
694
+ "error-container": error.container,
695
+ "on-error-container": error.onContainer,
696
+ warn: warn.base,
697
+ "on-warn": warn.onBase,
698
+ "warn-container": warn.container,
699
+ "on-warn-container": warn.onContainer,
700
+ "on-warn-container-variant": warnExtras.variant,
701
+ "on-warn-container-border": warnExtras.border,
702
+ success: success.base,
703
+ "on-success": success.onBase,
704
+ "success-container": success.container,
705
+ "on-success-container": success.onContainer,
706
+ "on-success-container-variant": successExtras.variant,
707
+ "on-success-container-border": successExtras.border,
708
+ background,
709
+ "on-background": onBackground,
710
+ "on-background-variant": onBackgroundVariant,
711
+ surface,
712
+ "on-surface": onSurface,
713
+ "surface-variant": surfaceVariant,
714
+ "on-surface-variant": onSurfaceVariant,
715
+ "inverse-surface": inverseSurface,
716
+ "on-inverse-surface": onInverse,
717
+ "on-inverse-surface-primary": inversePrimary,
718
+ "on-inverse-surface-variant": inversePrimary,
719
+ "inverse-container": inverseSurface,
720
+ "on-inverse-container": onInverse,
721
+ outline,
722
+ shadow: "#000000",
723
+ scrim: "#000000",
724
+ "surface-tint": primaryBase,
725
+ transparent: "rgba(0,0,0,0)",
726
+ ghost: "rgba(0,0,0,0)",
727
+ disabled,
728
+ "on-disabled": onDisabled,
729
+ "disabled-container": tone(hues.primary, surfaceC, t.disabledContainer),
730
+ "on-disabled-container": onDisabled,
731
+ "disabled-surface": disabled,
732
+ "on-disabled-surface": dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)",
733
+ "on-disabled-surface-variant": dark ? "rgba(255,255,255,0.4)" : "rgba(0,0,0,0.4)"
734
+ };
286
735
  };
287
736
  //#endregion
288
- //#region src/concepts/style/inputs.constants.ts
289
- var removeInputPlatformStyling = {
290
- appearance: "none",
291
- background: "none",
292
- border: "none",
293
- outline: "none",
294
- boxShadow: "none",
295
- padding: 0,
296
- width: "100%"
297
- };
737
+ //#region src/concepts/color/color.factory.ts
738
+ /**
739
+ * Generate a complete {@link Colors} token set from a single seed color, a
740
+ * {@link ColorScheme} and a {@link ColorCategory}. Produces a light or dark
741
+ * variant of the same palette; `on-*` colors are driven to WCAG AA contrast
742
+ * so text stays legible for any seed.
743
+ *
744
+ * Delegates to the OKLCH engine in `concepts/generation` — all lightness and
745
+ * chroma math is perceptual, and every derived pair passes through the WCAG
746
+ * guard-rail. Accepts the engine's extended config, so callers may also pass
747
+ * soft `targets` (brand-faithful but guard-railed) and a `checks` sink. Use
748
+ * `generateThemes()` for the light+dark pair plus a {@link ContrastReport}.
749
+ */
750
+ var generatePalette = (config) => generateColors(config);
298
751
  //#endregion
299
- //#region src/concepts/theme/palettes/theme.palette.ts
300
- var genericLightTheme = {
301
- primary: "#0066B2",
302
- secondary: "#008528",
303
- tertiary: "#D97706",
304
- quaternary: "#52525B",
305
- warn: "#DC2626",
306
- success: "#008528",
307
- light: "#F4F4F5",
308
- onLight: "#18181B",
309
- onLightVariant: "rgba(24, 24, 27, 0.6)",
310
- dark: "#18181B",
311
- onDark: "rgba(255, 255, 255, 0.85)",
312
- background: "#FFFFFF",
313
- disabled: "rgba(24, 24, 27, 0.08)",
314
- onDisabled: "rgba(24, 24, 27, 0.4)"
752
+ //#region src/concepts/elevation/zIndex.ts
753
+ var Z_INDEX = {
754
+ dropdown: 1e3,
755
+ sticky: 1020,
756
+ fixed: 1030,
757
+ backdrop: 1040,
758
+ dialog: 1050,
759
+ popover: 1060,
760
+ tooltip: 1070,
761
+ overlay: 1080
315
762
  };
316
763
  //#endregion
317
- //#region src/concepts/typography/typography.records.ts
318
- var FontWeightMap = {
319
- thin: 100,
320
- "extra-light": 200,
321
- light: 200,
322
- normal: 400,
323
- medium: 500,
324
- "semi-bold": 600,
325
- bold: 700,
326
- "extra-bold": 800,
327
- black: 900,
328
- "extra-black": 950
764
+ //#region src/concepts/generation/shadow.generator.ts
765
+ var rgba = (hex, alpha) => {
766
+ const { red, green, blue } = hexToRgb(hex);
767
+ return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
329
768
  };
330
- //#endregion
331
- //#region src/concepts/typography/typeface.helpers.ts
332
- var px = (value) => `${value}px`;
333
769
  /**
334
- * Converts a TextStyle (numeric, design-token oriented) into a
335
- * TypeFaceDefinition (CSS-ready) so a theme's `typefaces` map can be
336
- * derived from its `typography` block instead of being duplicated.
770
+ * Brand-tinted, theme-scoped elevation shadows (PRD §3.5.C).
771
+ *
772
+ * Light mode replaces the dead-neutral black stacks with a shadow ink pulled
773
+ * toward the brand hue — dark and low-chroma enough to read as shadow, tinted
774
+ * enough to kill the grey "mud" where shadows meet brand surfaces. Dark mode
775
+ * goes near-zero: elevation is carried by the surface lightness steps, with
776
+ * only a faint veil kept on floating overlays (menus/dialogs genuinely need
777
+ * separation) and the `warn` glow tinted by the theme's own error color.
337
778
  */
338
- var toTypeface = (style) => ({
339
- fontFamily: style.fontFamily,
340
- fontSize: px(style.fontSize),
341
- lineHeight: px(style.lineHeight),
342
- ...style.letterSpacing !== void 0 && { letterSpacing: px(style.letterSpacing) },
343
- ...style.textTransform === "uppercase" && { textTransform: "uppercase" },
344
- ...style.fontWeight !== void 0 && { fontWeight: style.fontWeight },
345
- ...style.fontStyle && { fontStyle: style.fontStyle }
346
- });
347
- var toTypefaces = (typography) => Object.fromEntries(Object.entries(typography).map(([role, style]) => [role, toTypeface(style)]));
779
+ var generateShadows = (colors, mode = "light") => {
780
+ const error = colors["error"] ?? "#CC2827";
781
+ if (mode === "dark") return {
782
+ raised: "none",
783
+ menu: `0px 4px 12px ${rgba("#000000", .45)}`,
784
+ dialog: `0px 8px 28px ${rgba("#000000", .55)}`,
785
+ warn: `0 0 5px ${rgba(error, .55)}, inset 0 0 5px ${rgba(error, .35)}`
786
+ };
787
+ const { h } = hexToOklch(colors["primary"] ?? "#000000");
788
+ const ink = oklchToHex({
789
+ l: .22,
790
+ c: .035,
791
+ h
792
+ });
793
+ return {
794
+ raised: `${rgba(ink, .2)} 0px 2px 1px -1px, ${rgba(ink, .14)} 0px 1px 1px 0px, ${rgba(ink, .12)} 0px 1px 3px 0px`,
795
+ menu: `${rgba(ink, .2)} 0px 3px 3px -2px, ${rgba(ink, .14)} 0px 3px 4px 0px, ${rgba(ink, .12)} 0px 1px 8px 0px`,
796
+ dialog: `${rgba(ink, .2)} 0px 3px 5px -1px, ${rgba(ink, .14)} 0px 6px 10px 0px, ${rgba(ink, .12)} 0px 1px 18px 0px`,
797
+ warn: `0 0 5px ${rgba(error, .5)}, inset 0 0 5px ${rgba(error, .3)}`
798
+ };
799
+ };
348
800
  //#endregion
349
801
  //#region src/concepts/theme/themes/base.theme.ts
350
- var BaseButton = {
351
- borderRadius: 100,
352
- color: "primary-container",
353
- contentColor: "on-primary-container",
354
- verticalPadding: {
355
- xxs: 2,
356
- xs: 5,
357
- sm: 8,
358
- md: 12,
359
- lg: 16,
360
- xl: 20,
361
- xxl: 24
362
- },
363
- horizontalPadding: {
364
- xxs: 4,
365
- xs: 8,
366
- sm: 12,
367
- md: 18,
368
- lg: 24,
369
- xl: 30,
370
- xxl: 36
371
- }
372
- };
373
- var BaseContainer = {
374
- color: "primary-container",
375
- contentColor: "on-primary-container",
376
- borderRadii: {
377
- xxs: 4,
378
- xs: 8,
379
- sm: 12,
380
- md: 16,
381
- lg: 20,
382
- xl: 24,
383
- xxl: 28
384
- },
385
- horizontalPadding: {
386
- xxs: 6,
387
- xs: 12,
388
- sm: 18,
389
- md: 24,
390
- lg: 30,
391
- xl: 36,
392
- xxl: 42
393
- },
394
- contentSpacing: {
395
- xxs: 4,
396
- xs: 8,
397
- sm: 12,
398
- md: 16,
399
- lg: 20,
400
- xl: 24,
401
- xxl: 28
402
- }
403
- };
404
802
  var BaseTypography = {
405
803
  "display-large": {
406
804
  fontFamily: "Red Hat Display",
@@ -532,684 +930,869 @@ var BaseTypography = {
532
930
  fontSize: 14,
533
931
  lineHeight: 22,
534
932
  fontStyle: "italic"
535
- }
536
- };
537
- var BaseTheme = {
538
- id: "BaseTheme",
539
- name: "Base Theme",
540
- colors: {
541
- primary: "#6750A4",
542
- "on-primary": "#FFFFFF",
543
- "primary-container": "#EADDFF",
544
- "on-primary-container": "#21005E",
545
- secondary: "#625B71",
546
- "on-secondary": "#FFFFFF",
547
- "secondary-container": "#E8DEF8",
548
- "on-secondary-container": "#1E192B",
549
- tertiary: "#7D5260",
550
- "on-tertiary": "#FFFFFF",
551
- "tertiary-container": "#FFD8E4",
552
- "on-tertiary-container": "#370B1E",
553
- error: "#B3261E",
554
- "on-error": "#FFFFFF",
555
- "error-container": "#F9DEDC",
556
- "on-error-container": "#370B1E",
557
- background: "#FFFBFE",
558
- "on-background": "#1C1B1F",
559
- surface: "#FFFBFE",
560
- "on-surface": "#1C1B1F",
561
- "surface-variant": "#E7E0EC",
562
- "on-surface-variant": "#49454E",
563
- outline: "#79747E",
564
- shadow: "#000000",
565
- "surface-tint": "#6750A4",
566
- "inverse-surface": "#313033",
567
- "on-inverse-surface": "#F4EFF4",
568
- "on-inverse-surface-primary": "#D0BCFF",
569
- scrim: "#000000",
570
- transparent: "rgba(0,0,0,0)",
571
- ghost: "rgba(0,0,0,0)",
572
- quaternary: "#79747E",
573
- "on-quaternary": "#FFFFFF",
574
- warn: "#B3261E",
575
- "on-warn": "#FFFFFF",
576
- success: "#2E7D32",
577
- "on-success": "#FFFFFF",
578
- disabled: "rgba(0,0,0,0.12)",
579
- "on-disabled": "rgba(0,0,0,0.38)",
580
- "on-primary-container-variant": "rgba(0,0,0,0.4)",
581
- "on-primary-container-border": "#6750A4",
582
- "on-secondary-container-variant": "rgba(0,0,0,0.4)",
583
- "on-secondary-container-border": "#625B71",
584
- "on-tertiary-container-variant": "rgba(0,0,0,0.4)",
585
- "on-tertiary-container-border": "#7D5260",
586
- "warn-container": "#F9DEDC",
587
- "on-warn-container": "#8C1D18",
588
- "on-warn-container-variant": "rgba(0,0,0,0.4)",
589
- "on-warn-container-border": "#8C1D18",
590
- "success-container": "#C6F0CD",
591
- "on-success-container": "#1E5128",
592
- "on-success-container-variant": "rgba(0,0,0,0.4)",
593
- "on-success-container-border": "#1E5128",
594
- "disabled-container": "#F2F2F2",
595
- "on-disabled-container": "rgba(0,0,0,0.38)",
596
- "inverse-container": "#313033",
597
- "on-inverse-container": "#F4EFF4",
598
- "primary-surface": genericLightTheme.background,
599
- "on-primary-surface": genericLightTheme.onLight,
600
- "on-primary-surface-variant": genericLightTheme.primary,
601
- "secondary-surface": "#F3EDF7",
602
- "on-secondary-surface": "#1C1B1F",
603
- "on-secondary-surface-variant": "#6750A4",
604
- "tertiary-surface": "#F2F2F2",
605
- "on-tertiary-surface": "#1C1B1F",
606
- "on-tertiary-surface-variant": "#6750A4",
607
- "quaternary-surface": "#E8DEF8",
608
- "on-quaternary-surface": "#1C1B1F",
609
- "on-quaternary-surface-variant": "#6750A4",
610
- "disabled-surface": "rgba(0,0,0,0.12)",
611
- "on-disabled-surface": "rgba(0,0,0,0.5)",
612
- "on-disabled-surface-variant": "rgba(0,0,0,0.4)",
613
- "on-inverse-surface-variant": "#D0BCFF",
614
- "on-background-variant": "#959595"
615
- },
616
- typography: BaseTypography,
617
- borders: {
618
- primary: `1px solid ${genericLightTheme.primary}`,
619
- secondary: `1px solid ${genericLightTheme.secondary}`,
620
- tertiary: `1px solid ${genericLightTheme.tertiary}`,
621
- quaternary: `1px solid ${genericLightTheme.quaternary}`,
622
- warn: `1px solid ${genericLightTheme.warn}`,
623
- success: `1px solid ${genericLightTheme.secondary}`,
624
- light: `1px solid ${genericLightTheme.light}`,
625
- dark: `1px solid ${genericLightTheme.dark}`,
626
- dotted: `1px dotted ${genericLightTheme.dark}`
627
- },
628
- shadows: {
629
- raised: "rgba(0, 0, 0, 0.2) 0px 2px 1px -1px, rgba(0, 0, 0, 0.14) 0px 1px 1px 0px, rgba(0, 0, 0, 0.12) 0px 1px 3px 0px",
630
- menu: "rgba(0, 0, 0, 0.2) 0px 3px 3px -2px, rgba(0, 0, 0, 0.14) 0px 3px 4px 0px, rgba(0, 0, 0, 0.12) 0px 1px 8px 0px;",
631
- dialog: "rgba(0, 0, 0, 0.2) 0px 3px 5px -1px, rgba(0, 0, 0, 0.14) 0px 6px 10px 0px, rgba(0, 0, 0, 0.12) 0px 1px 18px 0px",
632
- warn: "0 0 5px rgba(255, 0, 0, 0.5), inset 0 0 5px rgba(255, 0, 0, 0.3)"
633
- },
634
- spacing: {
635
- none: "none",
636
- xxs: "2px",
637
- xs: "4px",
638
- sm: "8px",
639
- md: "16px",
640
- lg: "32px",
641
- xl: "64px"
642
933
  },
643
- thicknesses: {
644
- thin: 1,
645
- standard: 2,
646
- thick: 4
934
+ badge: {
935
+ fontFamily: "Red Hat Display",
936
+ fontSize: 16,
937
+ lineHeight: 24
647
938
  },
648
- radii: {
649
- none: "none",
650
- xxs: "4px",
651
- xs: "8px",
652
- sm: "16px",
653
- md: "24px",
654
- lg: "32px",
655
- max: "999px"
939
+ tag: {
940
+ fontFamily: "Red Hat Display",
941
+ fontSize: 15,
942
+ lineHeight: 20,
943
+ fontWeight: 600
656
944
  },
657
- buttons: {
658
- elevated: {
659
- ...BaseButton,
660
- color: "surface",
661
- contentColor: "on-surface",
662
- shadowElevation: "raised"
663
- },
664
- filled: {
665
- ...BaseButton,
666
- color: "primary"
667
- },
668
- "filled-secondary": {
669
- ...BaseButton,
670
- color: "secondary",
671
- contentColor: "on-secondary"
672
- },
673
- outlined: {
674
- ...BaseButton,
675
- color: "transparent",
676
- borderColor: "primary",
677
- contentColor: "on-primary",
678
- borderWidth: 1
679
- },
680
- text: {
681
- ...BaseButton,
682
- color: "transparent",
683
- contentColor: "on-surface"
945
+ input: {
946
+ fontFamily: "Red Hat Display",
947
+ fontSize: 14,
948
+ lineHeight: 24
949
+ }
950
+ };
951
+ var BaseShadows = {
952
+ raised: "rgba(0, 0, 0, 0.2) 0px 2px 1px -1px, rgba(0, 0, 0, 0.14) 0px 1px 1px 0px, rgba(0, 0, 0, 0.12) 0px 1px 3px 0px",
953
+ menu: "rgba(0, 0, 0, 0.2) 0px 3px 3px -2px, rgba(0, 0, 0, 0.14) 0px 3px 4px 0px, rgba(0, 0, 0, 0.12) 0px 1px 8px 0px;",
954
+ dialog: "rgba(0, 0, 0, 0.2) 0px 3px 5px -1px, rgba(0, 0, 0, 0.14) 0px 6px 10px 0px, rgba(0, 0, 0, 0.12) 0px 1px 18px 0px",
955
+ warn: "0 0 5px rgba(255, 0, 0, 0.5), inset 0 0 5px rgba(255, 0, 0, 0.3)"
956
+ };
957
+ var BaseSpacing = {
958
+ none: "none",
959
+ xxs: "2px",
960
+ xs: "4px",
961
+ sm: "8px",
962
+ md: "16px",
963
+ lg: "32px",
964
+ xl: "64px"
965
+ };
966
+ var BaseThicknesses = {
967
+ thin: 1,
968
+ standard: 2,
969
+ thick: 4
970
+ };
971
+ var BaseRadii = {
972
+ none: "none",
973
+ xxs: "4px",
974
+ xs: "8px",
975
+ sm: "16px",
976
+ md: "24px",
977
+ lg: "32px",
978
+ max: "999px"
979
+ };
980
+ var buildBorders = (c) => ({
981
+ primary: `1px solid ${c.primary}`,
982
+ secondary: `1px solid ${c.secondary}`,
983
+ tertiary: `1px solid ${c.tertiary}`,
984
+ quaternary: `1px solid ${c.quaternary}`,
985
+ warn: `1px solid ${c.warn}`,
986
+ success: `1px solid ${c.success}`,
987
+ light: `1px solid ${c.outline}`,
988
+ dark: `1px solid ${c["on-background"]}`,
989
+ dotted: `1px dotted ${c["on-background"]}`
990
+ });
991
+ var buildComponents = (c) => ({
992
+ alert: { options: {
993
+ topPosition: 40,
994
+ borderRadius: "sm",
995
+ transitionSpeed: .35,
996
+ elevation: "md"
997
+ } },
998
+ checkbox: { options: { size: 20 } },
999
+ dialog: { options: {
1000
+ borderRadius: "lg",
1001
+ color: "primary-surface",
1002
+ border: "quaternary",
1003
+ padding: "sm",
1004
+ elevation: "dialog",
1005
+ backdrop: {
1006
+ background: "rgba(255, 255, 255, 0.6)",
1007
+ backdropFilter: "blur(2px)"
1008
+ }
1009
+ } },
1010
+ dialogHeader: { options: {
1011
+ borderRadius: "max",
1012
+ color: "primary",
1013
+ height: 48,
1014
+ textRole: "title-large",
1015
+ textAlign: "center",
1016
+ closeButtonIcon: "close",
1017
+ closeButtonSize: "md"
1018
+ } },
1019
+ dropdown: { options: {
1020
+ border: "none",
1021
+ borderRadius: "xxs",
1022
+ color: "primary-surface",
1023
+ shadow: "menu"
1024
+ } },
1025
+ footer: { options: {
1026
+ height: 52,
1027
+ color: "primary",
1028
+ logoHeight: 18.6,
1029
+ logoPadding: "md"
1030
+ } },
1031
+ input: { options: {
1032
+ typeFace: "input",
1033
+ color: "primary-surface",
1034
+ textColor: "on-primary-surface",
1035
+ disabledColor: "disabled-surface",
1036
+ disabledTextColor: "on-disabled-surface",
1037
+ border: "light",
1038
+ borderRadius: "xs",
1039
+ errorShadow: "warn",
1040
+ errorBorder: "warn",
1041
+ height: 32,
1042
+ paddingLeft: "sm",
1043
+ focusOutline: `2px solid ${c.primary}`,
1044
+ focusOutlineOffset: 2
1045
+ } },
1046
+ multiSelectDropdown: { options: {
1047
+ textRole: "input",
1048
+ textColor: "on-primary-surface",
1049
+ dividerBorder: "light",
1050
+ searchInputBorder: "light",
1051
+ searchInputBorderRadius: "xxs",
1052
+ focusOutline: `2px solid ${c.primary}`,
1053
+ focusOutlineOffset: 2
1054
+ } },
1055
+ badge: { options: { borderRadius: "xxs" } },
1056
+ button: {
1057
+ fixed: {
1058
+ position: "relative",
1059
+ overflow: "hidden",
1060
+ outline: "0",
1061
+ border: "0",
1062
+ cursor: "pointer",
1063
+ fontFamily: "Euphemia, sans-serif",
1064
+ transition: "all 0.28s ease"
684
1065
  },
685
- icon: {
686
- ...BaseButton,
687
- color: "transparent",
688
- contentColor: "on-surface",
689
- horizontalPadding: BaseButton.verticalPadding
1066
+ variants: {
1067
+ ghost: {
1068
+ backgroundColor: "transparent",
1069
+ color: "currentcolor",
1070
+ "&:hover": { backgroundColor: "rgba(0,0,0,0.06)" }
1071
+ },
1072
+ primary: {
1073
+ backgroundColor: c.primary,
1074
+ color: c["on-primary"],
1075
+ border: "0",
1076
+ "&:hover": { filter: "brightness(0.92)" }
1077
+ },
1078
+ secondary: {
1079
+ backgroundColor: "transparent",
1080
+ color: c.secondary,
1081
+ border: `1px solid ${c.secondary}`,
1082
+ "&:hover": {
1083
+ backgroundColor: c.secondary,
1084
+ color: c["on-secondary"]
1085
+ }
1086
+ },
1087
+ tertiary: {
1088
+ backgroundColor: c.tertiary,
1089
+ color: c["on-tertiary"],
1090
+ border: "0",
1091
+ "&:hover": { filter: "brightness(0.92)" }
1092
+ },
1093
+ warn: {
1094
+ backgroundColor: c.warn,
1095
+ color: c["on-warn"],
1096
+ border: "0",
1097
+ "&:hover": { filter: "brightness(0.92)" }
1098
+ },
1099
+ success: {
1100
+ backgroundColor: c.success,
1101
+ color: c["on-success"],
1102
+ border: "0",
1103
+ "&:hover": { filter: "brightness(0.92)" }
1104
+ },
1105
+ disabled: {
1106
+ backgroundColor: `${c.disabled} !important`,
1107
+ color: `${c["on-disabled"]} !important`,
1108
+ border: "0"
1109
+ }
690
1110
  },
691
- "floating-action": {
692
- ...BaseButton,
693
- color: "secondary",
694
- contentColor: "on-secondary",
695
- borderRadii: {
696
- xxs: 3,
697
- xs: 5,
698
- sm: 8,
699
- md: 12,
700
- lg: 16,
701
- xl: 12,
702
- xxl: 20
1111
+ sizes: {
1112
+ sm: {
1113
+ height: 22,
1114
+ borderRadius: 11,
1115
+ fontSize: 12,
1116
+ padding: "0 12px",
1117
+ fontFamily: "Euphemia Bold, sans-serif",
1118
+ fontWeight: 600
703
1119
  },
704
- shadowElevation: "navigation",
705
- verticalPadding: {
706
- xxs: 4,
707
- xs: 8,
708
- sm: 12,
709
- md: 18,
710
- lg: 24,
711
- xl: 30,
712
- xxl: 36
1120
+ md: {
1121
+ height: 26,
1122
+ borderRadius: 13,
1123
+ fontSize: 16,
1124
+ padding: "0 16px"
713
1125
  },
714
- horizontalPadding: {
715
- xxs: 4,
716
- xs: 8,
717
- sm: 12,
718
- md: 18,
719
- lg: 24,
720
- xl: 30,
721
- xxl: 36
1126
+ lg: {
1127
+ height: 36,
1128
+ borderRadius: 18,
1129
+ fontSize: 18,
1130
+ padding: "0 18px"
1131
+ },
1132
+ xl: {
1133
+ height: 48,
1134
+ borderRadius: 24,
1135
+ fontSize: 24,
1136
+ padding: "0 22px"
722
1137
  }
723
1138
  }
724
1139
  },
725
- containers: {
726
- card: {
727
- ...BaseContainer,
728
- color: "surface",
729
- contentColor: "on-surface",
730
- shadowMode: "interactive"
731
- },
732
- screen: {
733
- ...BaseContainer,
734
- color: "background",
735
- contentColor: "on-background"
1140
+ iconButton: {
1141
+ variants: {
1142
+ ghost: {
1143
+ backgroundColor: "transparent",
1144
+ color: "currentcolor"
1145
+ },
1146
+ primary: {
1147
+ backgroundColor: c.primary,
1148
+ color: c["on-primary"]
1149
+ },
1150
+ secondary: {
1151
+ backgroundColor: c.secondary,
1152
+ color: c["on-secondary"]
1153
+ },
1154
+ tertiary: {
1155
+ backgroundColor: c.tertiary,
1156
+ color: c["on-tertiary"]
1157
+ },
1158
+ warn: {
1159
+ backgroundColor: c.warn,
1160
+ color: c["on-warn"]
1161
+ },
1162
+ success: {
1163
+ backgroundColor: c.success,
1164
+ color: c["on-success"]
1165
+ },
1166
+ disabled: {
1167
+ backgroundColor: "transparent !important",
1168
+ color: `${c["on-disabled"]} !important`
1169
+ }
736
1170
  },
737
- modal: {
738
- ...BaseContainer,
739
- borderRadii: {
740
- xxs: 8,
741
- xs: 16,
742
- sm: 22,
743
- md: 28,
744
- lg: 32,
745
- xl: 38,
746
- xxl: 44
1171
+ sizes: {
1172
+ sm: {
1173
+ height: 22,
1174
+ minHeight: 22,
1175
+ width: 22,
1176
+ minWidth: 22,
1177
+ fontSize: 18
1178
+ },
1179
+ md: {
1180
+ height: 26,
1181
+ minHeight: 26,
1182
+ width: 26,
1183
+ minWidth: 26,
1184
+ fontSize: 22
747
1185
  },
748
- color: "surface",
749
- contentColor: "on-surface",
750
- shadowMode: "static",
751
- shadowElevation: "modal",
752
- maxWidth: 560
1186
+ lg: {
1187
+ height: 36,
1188
+ minHeight: 36,
1189
+ width: 36,
1190
+ minWidth: 36,
1191
+ fontSize: 30
1192
+ },
1193
+ xl: {
1194
+ height: 40,
1195
+ minHeight: 40,
1196
+ width: 40,
1197
+ minWidth: 40,
1198
+ fontSize: 34
1199
+ }
753
1200
  }
754
1201
  },
755
- typefaces: {
756
- ...toTypefaces(BaseTypography),
757
- badge: {
758
- fontFamily: "Red Hat Display",
759
- fontSize: "16px",
760
- lineHeight: "24px"
761
- },
762
- tag: {
763
- fontFamily: "Red Hat Display",
764
- fontSize: "15px",
765
- lineHeight: "20px",
766
- fontWeight: 600
1202
+ progressGauge: {
1203
+ fixed: { textFill: c["on-background"] },
1204
+ variants: {
1205
+ primary: {
1206
+ backgroundColor: "#b3d4ea",
1207
+ color: c.primary
1208
+ },
1209
+ secondary: {
1210
+ backgroundColor: "#b3e7c2",
1211
+ color: c.secondary
1212
+ },
1213
+ tertiary: {
1214
+ backgroundColor: "#ffe2b3",
1215
+ color: c.tertiary
1216
+ },
1217
+ warn: {
1218
+ backgroundColor: "#ffc2b3",
1219
+ color: c.warn
1220
+ },
1221
+ success: {
1222
+ backgroundColor: "#b3e7c2",
1223
+ color: c.success
1224
+ }
767
1225
  },
768
- input: {
769
- fontFamily: "Red Hat Display",
770
- fontSize: "14px",
771
- lineHeight: "24px"
1226
+ sizes: {
1227
+ sm: { height: "54px" },
1228
+ md: { height: "68px" },
1229
+ lg: { height: "82px" },
1230
+ xl: { height: "104px" }
772
1231
  }
773
1232
  },
774
- icons: {},
775
- components: {
776
- alert: { options: {
777
- topPosition: 40,
778
- borderRadius: "sm",
779
- transitionSpeed: .35,
780
- elevation: "md"
781
- } },
782
- checkbox: { options: { size: 20 } },
783
- dialog: { options: {
784
- borderRadius: "lg",
785
- color: "primary-surface",
786
- border: "quaternary",
787
- padding: "sm",
788
- elevation: "dialog",
789
- backdrop: {
790
- background: "rgba(255, 255, 255, 0.6)",
791
- backdropFilter: "blur(2px)"
792
- }
793
- } },
794
- dialogHeader: { options: {
795
- borderRadius: "max",
796
- color: "primary",
797
- height: 48,
798
- textRole: "title-large",
799
- textAlign: "center",
800
- closeButtonIcon: "close",
801
- closeButtonSize: "md"
802
- } },
803
- dropdown: { options: {
804
- border: "none",
805
- borderRadius: "xxs",
806
- color: "primary-surface",
807
- shadow: "menu"
808
- } },
809
- footer: { options: {
810
- height: 52,
811
- color: "primary",
812
- logoHeight: 18.6,
813
- logoPadding: "md"
814
- } },
815
- input: { options: {
816
- typeFace: "input",
817
- color: "primary-surface",
818
- textColor: "on-primary-surface",
819
- disabledColor: "disabled-surface",
820
- disabledTextColor: "on-disabled-surface",
821
- border: "light",
822
- borderRadius: "xs",
823
- errorShadow: "warn",
824
- errorBorder: "warn",
825
- height: 32,
826
- paddingLeft: "sm",
827
- focusOutline: `2px solid ${genericLightTheme.primary}`,
828
- focusOutlineOffset: 2
829
- } },
830
- multiSelectDropdown: { options: {
831
- textRole: "input",
832
- textColor: "on-primary-surface",
833
- dividerBorder: "light",
834
- searchInputBorder: "light",
835
- searchInputBorderRadius: "xxs",
836
- focusOutline: `2px solid ${genericLightTheme.primary}`,
837
- focusOutlineOffset: 2
838
- } },
839
- badge: { options: { borderRadius: "xxs" } },
840
- button: {
841
- fixed: {
842
- position: "relative",
843
- overflow: "hidden",
844
- outline: "0",
845
- border: "0",
846
- cursor: "pointer",
847
- fontFamily: "Euphemia, sans-serif",
848
- transition: "all 0.28s ease"
1233
+ card: {
1234
+ fixed: {
1235
+ borderStyle: "solid",
1236
+ borderWidth: "1px",
1237
+ borderRadius: "8px",
1238
+ overflow: "hidden"
1239
+ },
1240
+ variants: {
1241
+ primary: {
1242
+ borderColor: c.primary,
1243
+ backgroundColor: c.background
849
1244
  },
850
- colors: {
851
- ghost: {
852
- backgroundColor: "transparent",
853
- color: "currentcolor"
854
- },
855
- primary: {
856
- backgroundColor: genericLightTheme.primary,
857
- color: genericLightTheme.onDark
858
- },
859
- secondary: {
860
- backgroundColor: genericLightTheme.secondary,
861
- color: genericLightTheme.onDark
862
- },
863
- tertiary: {
864
- backgroundColor: genericLightTheme.tertiary,
865
- color: genericLightTheme.onDark
866
- },
867
- warn: {
868
- backgroundColor: genericLightTheme.warn,
869
- color: genericLightTheme.onDark
870
- },
871
- disabled: {
872
- backgroundColor: `${genericLightTheme.disabled} !important`,
873
- color: "#fff !important"
874
- },
875
- success: {
876
- backgroundColor: genericLightTheme.success,
877
- color: genericLightTheme.onDark
878
- }
1245
+ secondary: {
1246
+ borderColor: c.secondary,
1247
+ backgroundColor: c.background
879
1248
  },
880
- sizes: {
881
- sm: {
882
- height: 22,
883
- borderRadius: 11,
884
- fontSize: 12,
885
- padding: "0 12px",
886
- fontFamily: "Euphemia Bold, sans-serif",
887
- fontWeight: 600
888
- },
889
- md: {
890
- height: 26,
891
- borderRadius: 13,
892
- fontSize: 16,
893
- padding: "0 16px"
894
- },
895
- lg: {
896
- height: 36,
897
- borderRadius: 18,
898
- fontSize: 18,
899
- padding: "0 18px"
900
- },
901
- xl: {
902
- height: 48,
903
- borderRadius: 24,
904
- fontSize: 24,
905
- padding: "0 22px"
906
- }
907
- }
908
- },
909
- iconButton: {
910
- colors: {
911
- ghost: {
912
- backgroundColor: "transparent",
913
- color: "currentcolor"
914
- },
915
- primary: {
916
- backgroundColor: genericLightTheme.primary,
917
- color: genericLightTheme.onDark
918
- },
919
- secondary: {
920
- backgroundColor: genericLightTheme.secondary,
921
- color: genericLightTheme.onDark
922
- },
923
- tertiary: {
924
- backgroundColor: genericLightTheme.tertiary,
925
- color: genericLightTheme.onDark
926
- },
927
- warn: {
928
- backgroundColor: genericLightTheme.warn,
929
- color: genericLightTheme.onDark
930
- },
931
- success: {
932
- backgroundColor: genericLightTheme.success,
933
- color: genericLightTheme.onDark
934
- },
935
- disabled: {
936
- backgroundColor: "transparent !important",
937
- color: "rgba(0,0,0,0.25) !important"
938
- }
1249
+ tertiary: {
1250
+ borderColor: c.tertiary,
1251
+ backgroundColor: c.background
939
1252
  },
940
- sizes: {
941
- sm: {
942
- height: 22,
943
- minHeight: 22,
944
- width: 22,
945
- minWidth: 22,
946
- fontSize: 18
947
- },
948
- md: {
949
- height: 26,
950
- minHeight: 26,
951
- width: 26,
952
- minWidth: 26,
953
- fontSize: 22
954
- },
955
- lg: {
956
- height: 36,
957
- minHeight: 36,
958
- width: 36,
959
- minWidth: 36,
960
- fontSize: 30
961
- },
962
- xl: {
963
- height: 40,
964
- minHeight: 40,
965
- width: 40,
966
- minWidth: 40,
967
- fontSize: 34
968
- }
969
- }
970
- },
971
- progressGauge: {
972
- fixed: { textFill: genericLightTheme.onLight },
973
- colors: {
974
- primary: {
975
- backgroundColor: "#b3d4ea",
976
- color: genericLightTheme.primary
977
- },
978
- secondary: {
979
- backgroundColor: "#b3e7c2",
980
- color: genericLightTheme.secondary
981
- },
982
- tertiary: {
983
- backgroundColor: "#ffe2b3",
984
- color: genericLightTheme.tertiary
985
- },
986
- warn: {
987
- backgroundColor: "#ffc2b3",
988
- color: genericLightTheme.warn
989
- },
990
- success: {
991
- backgroundColor: "#b3e7c2",
992
- color: genericLightTheme.success
993
- }
1253
+ warn: {
1254
+ borderColor: c.warn,
1255
+ backgroundColor: c.background
994
1256
  },
995
- sizes: {
996
- sm: { height: "54px" },
997
- md: { height: "68px" },
998
- lg: { height: "82px" },
999
- xl: { height: "104px" }
1257
+ success: {
1258
+ borderColor: c.success,
1259
+ backgroundColor: c.background
1000
1260
  }
1001
- },
1002
- card: {
1003
- fixed: {
1004
- borderStyle: "solid",
1005
- borderWidth: "1px",
1006
- borderRadius: "8px",
1007
- overflow: "hidden"
1261
+ }
1262
+ },
1263
+ cardHeader: {
1264
+ fixed: { padding: "12px 24px" },
1265
+ variants: {
1266
+ primary: {
1267
+ backgroundColor: c.primary,
1268
+ color: c["on-primary"]
1008
1269
  },
1009
- colors: {
1010
- primary: {
1011
- borderColor: genericLightTheme.primary,
1012
- backgroundColor: genericLightTheme.background
1013
- },
1014
- secondary: {
1015
- borderColor: genericLightTheme.secondary,
1016
- backgroundColor: genericLightTheme.background
1017
- },
1018
- tertiary: {
1019
- borderColor: genericLightTheme.tertiary,
1020
- backgroundColor: genericLightTheme.background
1021
- },
1022
- warn: {
1023
- borderColor: genericLightTheme.warn,
1024
- backgroundColor: genericLightTheme.background
1025
- },
1026
- success: {
1027
- borderColor: genericLightTheme.success,
1028
- backgroundColor: genericLightTheme.background
1029
- }
1270
+ secondary: {
1271
+ backgroundColor: c.secondary,
1272
+ color: c["on-secondary"]
1273
+ },
1274
+ tertiary: {
1275
+ backgroundColor: c.tertiary,
1276
+ color: c["on-tertiary"]
1277
+ },
1278
+ warn: {
1279
+ backgroundColor: c.warn,
1280
+ color: c["on-warn"]
1281
+ },
1282
+ success: {
1283
+ backgroundColor: c.success,
1284
+ color: c["on-success"]
1030
1285
  }
1286
+ }
1287
+ },
1288
+ cardContent: { fixed: { padding: "12px 24px" } },
1289
+ dataSearch: { options: {
1290
+ border: "light",
1291
+ borderRadius: "xs",
1292
+ color: "primary-surface",
1293
+ placeholderColor: "disabled"
1294
+ } },
1295
+ dataTable: { options: {
1296
+ color: "primary-surface",
1297
+ border: "light",
1298
+ borderRadius: "sm",
1299
+ elevation: void 0,
1300
+ headerPadding: "sm",
1301
+ footerPadding: "sm",
1302
+ thTextRole: "headline-small",
1303
+ thColor: "primary-container",
1304
+ thVerticalBorder: "dotted",
1305
+ thHorizontalBorder: "light",
1306
+ thPadding: "sm",
1307
+ tdTextRole: "title-small",
1308
+ tdColor: "primary-surface",
1309
+ tdStickyColor: "primary-container",
1310
+ tdPadding: "sm",
1311
+ tdVerticalBorder: "dotted",
1312
+ tdHorizontalBorder: "light",
1313
+ rowHoverColor: "primary-container",
1314
+ loadingOverlayColor: "scrim",
1315
+ loadingSpinnerColor: "primary",
1316
+ loadingSpinnerSize: 40
1317
+ } },
1318
+ notificationBadge: { options: {
1319
+ borderRadius: "sm",
1320
+ offset: -10
1321
+ } },
1322
+ paginator: { options: {
1323
+ gap: "xs",
1324
+ textRole: "label",
1325
+ inputBorder: "light",
1326
+ inputBorderRadius: "xs",
1327
+ pageBorderRadius: "xs",
1328
+ currentPageBorder: "light",
1329
+ currentPageBorderRadius: "xs"
1330
+ } },
1331
+ snackbar: { options: {
1332
+ bottomPosition: 40,
1333
+ transitionDelay: "0.35s",
1334
+ autoCloseDelay: 35e3
1335
+ } },
1336
+ symbol: { options: {
1337
+ fill: 0,
1338
+ weight: 400,
1339
+ grade: 0,
1340
+ opticalSize: 24
1341
+ } },
1342
+ toggle: { options: { size: 20 } },
1343
+ tooltip: { options: {
1344
+ border: void 0,
1345
+ borderRadius: "xs",
1346
+ shadow: "raised",
1347
+ color: "inverse-surface",
1348
+ typeface: "label"
1349
+ } }
1350
+ });
1351
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1352
+ var deepMerge = (base, override) => {
1353
+ if (!override) return base;
1354
+ const out = { ...base };
1355
+ for (const [key, value] of Object.entries(override)) out[key] = isRecord(value) && isRecord(out[key]) ? deepMerge(out[key], value) : value;
1356
+ return out;
1357
+ };
1358
+ var createTheme = ({ id, name, colors, icons = {}, radii = BaseRadii, shadows = BaseShadows, borders, components }) => ({
1359
+ id,
1360
+ name,
1361
+ colors,
1362
+ typography: BaseTypography,
1363
+ borders: deepMerge(buildBorders(colors), borders),
1364
+ radii,
1365
+ shadows,
1366
+ spacing: BaseSpacing,
1367
+ thicknesses: BaseThicknesses,
1368
+ icons,
1369
+ components: deepMerge(buildComponents(colors), components)
1370
+ });
1371
+ /**
1372
+ * Build a full {@link UniTheme} straight from a {@link PaletteConfig} — the
1373
+ * one-call path a theme builder uses to turn a brand color (or a seed +
1374
+ * scheme + category) into a complete, ready-to-apply theme.
1375
+ */
1376
+ var createThemeFromPalette = (config) => {
1377
+ const colors = generatePalette(config);
1378
+ return createTheme({
1379
+ id: config.id ?? "CustomTheme",
1380
+ name: config.name ?? "Custom Theme",
1381
+ colors,
1382
+ shadows: generateShadows(colors, config.mode ?? "light"),
1383
+ icons: config.icons
1384
+ });
1385
+ };
1386
+ /**
1387
+ * Seed for the shipped Light/Dark themes. Swap these three values (or call
1388
+ * `generatePalette` with your own) to reskin the entire system — every color
1389
+ * token is derived, so there is nothing else to hand-author.
1390
+ */
1391
+ var BASE_PALETTE_CONFIG = {
1392
+ seed: "#4F46E5",
1393
+ scheme: "triadic",
1394
+ category: "neutral"
1395
+ };
1396
+ var lightColors = generatePalette({
1397
+ ...BASE_PALETTE_CONFIG,
1398
+ mode: "light"
1399
+ });
1400
+ var BaseTheme = createTheme({
1401
+ id: "BaseTheme",
1402
+ name: "Base Theme",
1403
+ colors: lightColors
1404
+ });
1405
+ //#endregion
1406
+ //#region src/concepts/generation/theme.generator.ts
1407
+ /** Radii presets per shape language (PRD §3.5.A). Same keys as `BaseRadii`. */
1408
+ var ShapeRadii = {
1409
+ sharp: {
1410
+ none: "none",
1411
+ xxs: "0px",
1412
+ xs: "0px",
1413
+ sm: "0px",
1414
+ md: "0px",
1415
+ lg: "0px",
1416
+ max: "0px"
1417
+ },
1418
+ modern: {
1419
+ none: "none",
1420
+ xxs: "4px",
1421
+ xs: "8px",
1422
+ sm: "16px",
1423
+ md: "24px",
1424
+ lg: "32px",
1425
+ max: "999px"
1426
+ },
1427
+ playful: {
1428
+ none: "none",
1429
+ xxs: "8px",
1430
+ xs: "16px",
1431
+ sm: "24px",
1432
+ md: "32px",
1433
+ lg: "48px",
1434
+ max: "9999px"
1435
+ }
1436
+ };
1437
+ /** Shortest angular distance between two hue angles, in degrees (0–180). */
1438
+ var hueDistance = (a, b) => {
1439
+ const d = Math.abs(a - b) % 360;
1440
+ return d > 180 ? 360 - d : d;
1441
+ };
1442
+ /**
1443
+ * Classify 2–3 brand hues against {@link ColorScheme} by their angular
1444
+ * distances from the primary hue. Heuristic bands, widest match wins.
1445
+ */
1446
+ var classifyScheme = (primaryHue, otherHues) => {
1447
+ const distances = otherHues.map((h) => hueDistance(primaryHue, h));
1448
+ if (distances.length === 0) return "analogous";
1449
+ if (distances.every((d) => d < 15)) return "monochromatic";
1450
+ if (distances.every((d) => d <= 65)) return "analogous";
1451
+ if (distances.some((d) => d >= 165)) return "complimentary";
1452
+ if (distances.length > 1 && distances.every((d) => d >= 130)) return "splitComplimentary";
1453
+ return "triadic";
1454
+ };
1455
+ /**
1456
+ * Infer a tonal category from the seed's own chroma, so an unstated "vibe"
1457
+ * preserves the brand's character — vivid stays vivid, muted stays muted.
1458
+ */
1459
+ var inferCategory = (seedHex) => {
1460
+ const { c } = hexToOklch(seedHex);
1461
+ if (c >= .13) return "jewel";
1462
+ if (c >= .07) return "earth";
1463
+ if (c >= .03) return "pastel";
1464
+ return "neutral";
1465
+ };
1466
+ /**
1467
+ * The theme generation engine (PRD §3.3): brand seed(s) in, complete WCAG-AA
1468
+ * light+dark {@link Colors} pair out, with a machine-readable contrast report.
1469
+ * Pure and deterministic — identical input yields identical output.
1470
+ */
1471
+ var generateThemes = (input) => {
1472
+ const seeds = (Array.isArray(input.seed) ? input.seed : [input.seed]).slice(0, 3);
1473
+ const [primary, secondary, tertiary] = seeds;
1474
+ const scheme = input.scheme ?? (seeds.length > 1 ? classifyScheme(hexToOklch(primary).h, seeds.slice(1).map((s) => hexToOklch(s).h)) : "analogous");
1475
+ const category = input.vibe ?? inferCategory(primary);
1476
+ const applyVibe = (hex) => {
1477
+ if (!input.vibe) return hex;
1478
+ const color = hexToOklch(hex);
1479
+ return oklchToHex({
1480
+ ...color,
1481
+ c: Math.min(color.c, CategoryChroma[input.vibe])
1482
+ });
1483
+ };
1484
+ const targets = { primary: applyVibe(primary) };
1485
+ if (secondary) targets.secondary = applyVibe(secondary);
1486
+ if (tertiary) targets.tertiary = applyVibe(tertiary);
1487
+ const checks = [];
1488
+ const base = {
1489
+ seed: primary,
1490
+ scheme,
1491
+ category,
1492
+ targets,
1493
+ checks
1494
+ };
1495
+ const lightColors = generateColors({
1496
+ ...base,
1497
+ mode: "light"
1498
+ });
1499
+ const darkColors = generateColors({
1500
+ ...base,
1501
+ mode: "dark"
1502
+ });
1503
+ const worstRatio = checks.reduce((worst, check) => Math.min(worst, check.ratio), 21);
1504
+ return {
1505
+ lightColors,
1506
+ darkColors,
1507
+ radii: input.shape ? ShapeRadii[input.shape] : void 0,
1508
+ lightShadows: generateShadows(lightColors, "light"),
1509
+ darkShadows: generateShadows(darkColors, "dark"),
1510
+ report: {
1511
+ checks,
1512
+ worstRatio,
1513
+ pass: checks.every((check) => check.pass)
1514
+ }
1515
+ };
1516
+ };
1517
+ /**
1518
+ * Convenience wrapper: {@link generateThemes} piped through `createTheme()`,
1519
+ * returning a registration-ready light/dark {@link UniTheme} pair.
1520
+ */
1521
+ var generateUniThemes = (input) => {
1522
+ const { lightColors, darkColors, radii, lightShadows, darkShadows } = generateThemes(input);
1523
+ const name = input.name ?? "Brand";
1524
+ const id = name.replace(/\W+/g, "") || "Brand";
1525
+ return {
1526
+ light: createTheme({
1527
+ id: `${id}Light`,
1528
+ name: `${name} Light`,
1529
+ colors: lightColors,
1530
+ radii,
1531
+ shadows: lightShadows
1532
+ }),
1533
+ dark: createTheme({
1534
+ id: `${id}Dark`,
1535
+ name: `${name} Dark`,
1536
+ colors: darkColors,
1537
+ radii,
1538
+ shadows: darkShadows
1539
+ })
1540
+ };
1541
+ };
1542
+ //#endregion
1543
+ //#region src/concepts/generation/theme-file.emitter.ts
1544
+ var IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
1545
+ var asKey = (k) => IDENT.test(k) ? k : `'${k}'`;
1546
+ var recordLiteral = (record, indent) => Object.entries(record).map(([k, v]) => `${indent}${asKey(k)}: '${v}',`).join("\n");
1547
+ var bordersLiteral = () => [
1548
+ "/**",
1549
+ " * Named border primitives. These mirror the derived defaults — edit them, or",
1550
+ " * add your own under any token name and point component options (or the",
1551
+ " * `components` overrides below) at it. Every component deriving from a",
1552
+ " * shared token picks up the change.",
1553
+ " */",
1554
+ "const borders = (colors: Colors): Borders => ({",
1555
+ " primary: `1px solid ${colors['primary']}`,",
1556
+ " secondary: `1px solid ${colors['secondary']}`,",
1557
+ " tertiary: `1px solid ${colors['tertiary']}`,",
1558
+ " quaternary: `1px solid ${colors['quaternary']}`,",
1559
+ " warn: `1px solid ${colors['warn']}`,",
1560
+ " success: `1px solid ${colors['success']}`,",
1561
+ " light: `1px solid ${colors['outline']}`,",
1562
+ " dark: `1px solid ${colors['on-background']}`,",
1563
+ " dotted: `1px dotted ${colors['on-background']}`,",
1564
+ "});"
1565
+ ].join("\n");
1566
+ var themeExport = (exportName, displayName, colorsConst, shadowsConst, radii) => [
1567
+ `export const ${exportName}: UniTheme = createTheme({`,
1568
+ ` id: '${exportName}',`,
1569
+ ` name: '${displayName}',`,
1570
+ ` colors: ${colorsConst},`,
1571
+ ` borders: borders(${colorsConst}),`,
1572
+ ` components: components(${colorsConst}),`,
1573
+ ` shadows: ${shadowsConst},`,
1574
+ ...radii ? [" radii,"] : [],
1575
+ "});"
1576
+ ].join("\n");
1577
+ /**
1578
+ * Render a static `uni-theme.ts` from a brand seed — the file the `ng add`
1579
+ * schematic writes and the MCP `generate_uni_theme` tool returns.
1580
+ *
1581
+ * The file is the system's **source of truth**: literal colors, the border
1582
+ * primitives spelled out, and a sparse `components` override section — so a
1583
+ * human (or an AI agent) can retheme by editing tokens in place, with no
1584
+ * runtime generation. Deterministic: same input, same file.
1585
+ */
1586
+ var emitThemeFile = (input) => {
1587
+ const { darkMode = true, name = "Brand" } = input;
1588
+ const { lightColors, darkColors, radii, lightShadows, darkShadows, report } = generateThemes(input);
1589
+ const id = name.replace(/\W+/g, "") || "Brand";
1590
+ const regenerate = [
1591
+ `--brand=${(Array.isArray(input.seed) ? input.seed : [input.seed]).join(",")}`,
1592
+ input.vibe && `--vibe=${input.vibe}`,
1593
+ input.scheme && `--scheme=${input.scheme}`,
1594
+ input.shape && `--shape=${input.shape}`,
1595
+ !darkMode && "--dark-mode=false"
1596
+ ].filter(Boolean).join(" ");
1597
+ const reportSummary = `${report.checks.length} contrast pairs checked · worst ${report.worstRatio}:1 · ${report.pass ? "all AA" : `${report.checks.filter((c) => !c.pass).length} failing`}`;
1598
+ const modes = [{
1599
+ exportName: `${id}Light`,
1600
+ displayName: `${name} Light`,
1601
+ colorsConst: "lightColors",
1602
+ colors: lightColors,
1603
+ shadowsConst: "lightShadows",
1604
+ shadows: lightShadows
1605
+ }, ...darkMode ? [{
1606
+ exportName: `${id}Dark`,
1607
+ displayName: `${name} Dark`,
1608
+ colorsConst: "darkColors",
1609
+ colors: darkColors,
1610
+ shadowsConst: "darkShadows",
1611
+ shadows: darkShadows
1612
+ }] : []];
1613
+ return {
1614
+ content: [
1615
+ "/**",
1616
+ ` * ${name} theme for Uni — generated data, yours to edit.`,
1617
+ " *",
1618
+ ` * Regenerate colors: ng add @uni-design-system/uni-angular ${regenerate}`,
1619
+ " * (or the `generate-uni-theme` MCP tool). Edits are never overwritten silently —",
1620
+ " * regeneration rewrites this file, so commit before regenerating.",
1621
+ ` * ${reportSummary}.`,
1622
+ " */",
1623
+ "import {",
1624
+ " createTheme,",
1625
+ " type Borders,",
1626
+ " type Colors,",
1627
+ " type ComponentThemes,",
1628
+ " type Shadows,",
1629
+ " type UniTheme,",
1630
+ "} from '@uni-design-system/uni-core';",
1631
+ "",
1632
+ ...modes.map(({ colorsConst, colors }) => `const ${colorsConst}: Colors = {\n${recordLiteral(colors, " ")}\n};\n`),
1633
+ "/** Brand-tinted elevation shadows — theme-scoped, edit freely. */",
1634
+ ...modes.map(({ shadowsConst, shadows }) => `const ${shadowsConst}: Shadows = {\n${recordLiteral(shadows, " ")}\n};\n`),
1635
+ bordersLiteral(),
1636
+ "",
1637
+ "/**",
1638
+ " * Sparse component overrides, deep-merged over Uni component defaults: only",
1639
+ " * what you write here changes. Point components at your own primitives, e.g.:",
1640
+ " * button: { variants: { secondary: { border: `2px dashed ${colors['tertiary']}` } } },",
1641
+ " * input: { options: { borderRadius: 'max' } },",
1642
+ " */",
1643
+ "const components = (colors: Colors): ComponentThemes => ({});",
1644
+ "",
1645
+ ...radii ? [
1646
+ `/** Shape language: '${input.shape}'. */`,
1647
+ `const radii = {\n${recordLiteral(radii, " ")}\n};`,
1648
+ ""
1649
+ ] : [],
1650
+ ...modes.map(({ exportName, displayName, colorsConst, shadowsConst }) => `${themeExport(exportName, displayName, colorsConst, shadowsConst, !!radii)}\n`),
1651
+ "/** First key wins as the default theme when registered via UNI_THEMES. */",
1652
+ `export const ${id}Themes = { ${modes.map((m) => m.exportName).join(", ")} };`,
1653
+ ""
1654
+ ].join("\n"),
1655
+ providerSnippet: [
1656
+ `import { UNI_THEMES } from '@uni-design-system/uni-angular';`,
1657
+ `import { ${id}Themes } from './uni-theme';`,
1658
+ "",
1659
+ "// app.config.ts → providers:",
1660
+ `{ provide: UNI_THEMES, useValue: ${id}Themes },`
1661
+ ].join("\n"),
1662
+ report,
1663
+ reportSummary
1664
+ };
1665
+ };
1666
+ //#endregion
1667
+ //#region src/concepts/gradient/gradient.helper.ts
1668
+ function gradient(config) {
1669
+ return ``;
1670
+ }
1671
+ //#endregion
1672
+ //#region src/concepts/layout/layout.helper.ts
1673
+ function getDeviceSize(height, width) {
1674
+ if (!height || !width) return "md";
1675
+ const max = Math.max(height, width);
1676
+ if (max <= 600) return "xs";
1677
+ if (max <= 960) return "sm";
1678
+ if (max <= 1264) return "md";
1679
+ if (max <= 1904) return "lg";
1680
+ return "xl";
1681
+ }
1682
+ function getDeviceOrientation(height, width) {
1683
+ if (!height || !width) return "landscape";
1684
+ return height > width ? "portrait" : "landscape";
1685
+ }
1686
+ //#endregion
1687
+ //#region src/concepts/shadow/shadow.utils.ts
1688
+ var GetBoxShadow = ({ offset, blur, opacity }) => {
1689
+ return `0 ${offset}px ${blur}px rgba(0,0,0,0.${opacity})`;
1690
+ };
1691
+ var GetBoxShadows = ({ umbra, penumbra }) => {
1692
+ return GetBoxShadow(umbra) + ", " + GetBoxShadow(penumbra);
1693
+ };
1694
+ //#endregion
1695
+ //#region src/concepts/shadow/shadow.records.ts
1696
+ var ShadowMap = {
1697
+ pressed: {
1698
+ umbra: {
1699
+ offset: 1,
1700
+ blur: 2,
1701
+ opacity: 24
1031
1702
  },
1032
- cardHeader: {
1033
- fixed: { padding: "12px 24px" },
1034
- colors: {
1035
- primary: {
1036
- backgroundColor: genericLightTheme.primary,
1037
- color: genericLightTheme.onDark
1038
- },
1039
- secondary: {
1040
- backgroundColor: genericLightTheme.secondary,
1041
- color: genericLightTheme.onDark
1042
- },
1043
- tertiary: {
1044
- backgroundColor: genericLightTheme.tertiary,
1045
- color: genericLightTheme.onDark
1046
- },
1047
- warn: {
1048
- backgroundColor: genericLightTheme.warn,
1049
- color: genericLightTheme.onDark
1050
- },
1051
- success: {
1052
- backgroundColor: genericLightTheme.success,
1053
- color: genericLightTheme.onDark
1054
- }
1055
- }
1703
+ penumbra: {
1704
+ offset: 1,
1705
+ blur: 3,
1706
+ opacity: 12
1707
+ }
1708
+ },
1709
+ raised: {
1710
+ umbra: {
1711
+ offset: 3,
1712
+ blur: 6,
1713
+ opacity: 23
1056
1714
  },
1057
- cardContent: { fixed: { padding: "12px 24px" } },
1058
- dataSearch: { options: {
1059
- border: "light",
1060
- borderRadius: "xs",
1061
- color: "primary-surface",
1062
- placeholderColor: "disabled"
1063
- } },
1064
- dataTable: { options: {
1065
- color: "primary-surface",
1066
- border: "light",
1067
- borderRadius: "sm",
1068
- elevation: void 0,
1069
- headerPadding: "sm",
1070
- footerPadding: "sm",
1071
- thTextRole: "headline-small",
1072
- thColor: "primary-container",
1073
- thVerticalBorder: "dotted",
1074
- thHorizontalBorder: "light",
1075
- thPadding: "sm",
1076
- tdTextRole: "title-small",
1077
- tdColor: "primary-surface",
1078
- tdStickyColor: "primary-container",
1079
- tdPadding: "sm",
1080
- tdVerticalBorder: "dotted",
1081
- tdHorizontalBorder: "light",
1082
- rowHoverColor: "primary-container",
1083
- loadingOverlayColor: "scrim",
1084
- loadingSpinnerColor: "primary",
1085
- loadingSpinnerSize: 40
1086
- } },
1087
- notificationBadge: { options: {
1088
- borderRadius: "sm",
1089
- offset: -10
1090
- } },
1091
- paginator: { options: {
1092
- gap: "xs",
1093
- textRole: "label",
1094
- inputBorder: "light",
1095
- inputBorderRadius: "xs",
1096
- pageBorderRadius: "xs",
1097
- currentPageBorder: "light",
1098
- currentPageBorderRadius: "xs"
1099
- } },
1100
- snackbar: { options: {
1101
- bottomPosition: 40,
1102
- transitionDelay: "0.35s",
1103
- autoCloseDelay: 35e3
1104
- } },
1105
- symbol: { options: {
1106
- fill: 0,
1107
- weight: 400,
1108
- grade: 0,
1109
- opticalSize: 24
1110
- } },
1111
- toggle: { options: { size: 20 } },
1112
- tooltip: { options: {
1113
- border: void 0,
1114
- borderRadius: "xs",
1115
- shadow: "raised",
1116
- color: "inverse-surface",
1117
- typeface: "label"
1118
- } }
1715
+ penumbra: {
1716
+ offset: 3,
1717
+ blur: 6,
1718
+ opacity: 16
1719
+ }
1720
+ },
1721
+ focussed: {
1722
+ umbra: {
1723
+ offset: 6,
1724
+ blur: 6,
1725
+ opacity: 23
1726
+ },
1727
+ penumbra: {
1728
+ offset: 10,
1729
+ blur: 20,
1730
+ opacity: 19
1731
+ }
1732
+ },
1733
+ navigation: {
1734
+ umbra: {
1735
+ offset: 10,
1736
+ blur: 10,
1737
+ opacity: 22
1738
+ },
1739
+ penumbra: {
1740
+ offset: 14,
1741
+ blur: 28,
1742
+ opacity: 25
1743
+ }
1744
+ },
1745
+ modal: {
1746
+ umbra: {
1747
+ offset: 15,
1748
+ blur: 12,
1749
+ opacity: 22
1750
+ },
1751
+ penumbra: {
1752
+ offset: 19,
1753
+ blur: 38,
1754
+ opacity: 30
1755
+ }
1119
1756
  }
1120
1757
  };
1758
+ var ShadowCssMap = {
1759
+ pressed: GetBoxShadows(ShadowMap["pressed"]),
1760
+ raised: GetBoxShadows(ShadowMap["raised"]),
1761
+ focussed: GetBoxShadows(ShadowMap["focussed"]),
1762
+ navigation: GetBoxShadows(ShadowMap["navigation"]),
1763
+ modal: GetBoxShadows(ShadowMap["modal"])
1764
+ };
1765
+ //#endregion
1766
+ //#region src/concepts/style/inputs.constants.ts
1767
+ var removeInputPlatformStyling = {
1768
+ appearance: "none",
1769
+ background: "none",
1770
+ border: "none",
1771
+ outline: "none",
1772
+ boxShadow: "none",
1773
+ padding: 0,
1774
+ width: "100%"
1775
+ };
1121
1776
  //#endregion
1122
1777
  //#region src/concepts/theme/themes/dark.theme.ts
1123
- var DarkTheme = {
1124
- ...BaseTheme,
1778
+ var darkColors = generatePalette({
1779
+ ...BASE_PALETTE_CONFIG,
1780
+ mode: "dark"
1781
+ });
1782
+ var DarkTheme = createTheme({
1125
1783
  id: "DarkTheme",
1126
1784
  name: "Dark Theme",
1127
- colors: {
1128
- primary: "#D0BCFF",
1129
- "on-primary": "#371E73",
1130
- "primary-container": "#4F378B",
1131
- "on-primary-container": "#EADDFF",
1132
- secondary: "#CCC2DC",
1133
- "on-secondary": "#332D41",
1134
- "secondary-container": "#4A4458",
1135
- "on-secondary-container": "#E8DEF8",
1136
- tertiary: "#EFB8C8",
1137
- "on-tertiary": "#492532",
1138
- "tertiary-container": "#633B48",
1139
- "on-tertiary-container": "#FFD8E4",
1140
- error: "#F2B8B5",
1141
- "on-error": "#601410",
1142
- "error-container": "#8C1D18",
1143
- "on-error-container": "#F9DEDC",
1144
- background: "#1C1B1F",
1145
- "on-background": "#E6E1E5",
1146
- surface: "#1C1B1F",
1147
- "on-surface": "#E6E1E5",
1148
- "surface-variant": "#49454F",
1149
- "on-surface-variant": "#CAC4D0",
1150
- outline: "#938F99",
1151
- shadow: "#000000",
1152
- "surface-tint": "#D0BCFF",
1153
- "inverse-surface": "#E6E1E5",
1154
- "inverse-on-surface": "#313033",
1155
- "inverse-on-surface-primary": "#6750A4",
1156
- "on-inverse-surface": "#313033",
1157
- "on-inverse-surface-primary": "#6750A4",
1158
- scrim: "#000000",
1159
- transparent: "rgba(0,0,0,0)",
1160
- ghost: "rgba(0,0,0,0)",
1161
- quaternary: "#938F99",
1162
- "on-quaternary": "#1C1B1F",
1163
- warn: "#F2B8B5",
1164
- "on-warn": "#601410",
1165
- success: "#7FD98F",
1166
- "on-success": "#00390F",
1167
- disabled: "rgba(255,255,255,0.12)",
1168
- "on-disabled": "rgba(255,255,255,0.38)",
1169
- "on-primary-container-variant": "rgba(255,255,255,0.4)",
1170
- "on-primary-container-border": "#EADDFF",
1171
- "on-secondary-container-variant": "rgba(255,255,255,0.4)",
1172
- "on-secondary-container-border": "#E8DEF8",
1173
- "on-tertiary-container-variant": "rgba(255,255,255,0.4)",
1174
- "on-tertiary-container-border": "#FFD8E4",
1175
- "warn-container": "#8C1D18",
1176
- "on-warn-container": "#F9DEDC",
1177
- "on-warn-container-variant": "rgba(255,255,255,0.4)",
1178
- "on-warn-container-border": "#F9DEDC",
1179
- "success-container": "#1E5128",
1180
- "on-success-container": "#C6F0CD",
1181
- "on-success-container-variant": "rgba(255,255,255,0.4)",
1182
- "on-success-container-border": "#C6F0CD",
1183
- "disabled-container": "#2B2930",
1184
- "on-disabled-container": "rgba(255,255,255,0.38)",
1185
- "inverse-container": "#E6E1E5",
1186
- "on-inverse-container": "#313033",
1187
- "primary-surface": "#1C1B1F",
1188
- "on-primary-surface": "#E6E1E5",
1189
- "on-primary-surface-variant": "#D0BCFF",
1190
- "secondary-surface": "#211F26",
1191
- "on-secondary-surface": "#E6E1E5",
1192
- "on-secondary-surface-variant": "#D0BCFF",
1193
- "tertiary-surface": "#2B2930",
1194
- "on-tertiary-surface": "#E6E1E5",
1195
- "on-tertiary-surface-variant": "#D0BCFF",
1196
- "quaternary-surface": "#36343B",
1197
- "on-quaternary-surface": "#E6E1E5",
1198
- "on-quaternary-surface-variant": "#D0BCFF",
1199
- "disabled-surface": "rgba(255,255,255,0.12)",
1200
- "on-disabled-surface": "rgba(255,255,255,0.5)",
1201
- "on-disabled-surface-variant": "rgba(255,255,255,0.4)",
1202
- "on-inverse-surface-variant": "#6750A4",
1203
- "on-background-variant": "#8F8C93"
1204
- }
1205
- };
1785
+ colors: darkColors,
1786
+ shadows: generateShadows(darkColors, "dark")
1787
+ });
1206
1788
  //#endregion
1207
1789
  //#region src/concepts/theme/themes/light.theme.ts
1208
- var LightTheme = {
1209
- ...BaseTheme,
1790
+ var LightTheme = createTheme({
1210
1791
  id: "LightTheme",
1211
- name: "Light Theme"
1212
- };
1792
+ name: "Light Theme",
1793
+ colors: lightColors,
1794
+ shadows: generateShadows(lightColors, "light")
1795
+ });
1213
1796
  //#endregion
1214
1797
  //#region src/concepts/theme/theme.records.ts
1215
1798
  var UniThemes = {
@@ -1218,6 +1801,38 @@ var UniThemes = {
1218
1801
  };
1219
1802
  var DefaultThemeId = Object.keys(UniThemes)[0];
1220
1803
  //#endregion
1804
+ //#region src/concepts/typography/typography.records.ts
1805
+ var FontWeightMap = {
1806
+ thin: 100,
1807
+ "extra-light": 200,
1808
+ light: 200,
1809
+ normal: 400,
1810
+ medium: 500,
1811
+ "semi-bold": 600,
1812
+ bold: 700,
1813
+ "extra-bold": 800,
1814
+ black: 900,
1815
+ "extra-black": 950
1816
+ };
1817
+ //#endregion
1818
+ //#region src/concepts/typography/typeface.helpers.ts
1819
+ var px = (value) => `${value}px`;
1820
+ /**
1821
+ * Converts a TextStyle (numeric, design-token oriented) into a
1822
+ * TypeFaceDefinition (CSS-ready) so a theme's `typefaces` map can be
1823
+ * derived from its `typography` block instead of being duplicated.
1824
+ */
1825
+ var toTypeface = (style) => ({
1826
+ fontFamily: style.fontFamily,
1827
+ fontSize: px(style.fontSize),
1828
+ lineHeight: px(style.lineHeight),
1829
+ ...style.letterSpacing !== void 0 && { letterSpacing: px(style.letterSpacing) },
1830
+ ...style.textTransform === "uppercase" && { textTransform: "uppercase" },
1831
+ ...style.fontWeight !== void 0 && { fontWeight: style.fontWeight },
1832
+ ...style.fontStyle && { fontStyle: style.fontStyle }
1833
+ });
1834
+ var toTypefaces = (typography) => Object.fromEntries(Object.entries(typography).map(([role, style]) => [role, toTypeface(style)]));
1835
+ //#endregion
1221
1836
  //#region src/utils/getValue.ts
1222
1837
  function getValue(data, path, defaultValue) {
1223
1838
  const value = path.split(/[.[\]]/).filter(Boolean).reduce((value, key) => value?.[key], data);
@@ -1235,6 +1850,6 @@ var debounce = (callback, timeout) => {
1235
1850
  };
1236
1851
  };
1237
1852
  //#endregion
1238
- export { BaseTheme, CategoryLightness, CategorySaturation, DarkTheme, DefaultThemeId, FontWeightMap, HSLAToString, LightTheme, RGBToHSL, RGBToString, RoleHues, ShadowCssMap, ShadowMap, UniThemes, Z_INDEX, collapseFadeOut, cycle, debounce, expandFadeIn, fadeIn, fadeOut, getAnalogousHues, getComplimentaryHue, getDeviceOrientation, getDeviceSize, getSplitComplimentaryHues, getTriadicHues, getValue, gradient, randomRangeValue, removeInputPlatformStyling, toTypeface, toTypefaces, uniColor };
1853
+ export { BASE_PALETTE_CONFIG, BaseTheme, CategoryChroma, CategoryLightness, CategorySaturation, DarkTheme, DefaultThemeId, FontWeightMap, HSLAToString, HSLToHex, HSLToRGB, LightTheme, RGBToHSL, RGBToString, RoleHues, ShadowCssMap, ShadowMap, ShapeRadii, UniThemes, Z_INDEX, classifyScheme, collapseFadeOut, contrastRatio, createTheme, createThemeFromPalette, cycle, darkColors, debounce, emitThemeFile, expandFadeIn, fadeIn, fadeOut, generateColors, generatePalette, generateShadows, generateThemes, generateUniThemes, getAnalogousHues, getComplimentaryHue, getDeviceOrientation, getDeviceSize, getSplitComplimentaryHues, getTriadicHues, getValue, gradient, hexToHSL, hexToOklch, hexToRgb, inferCategory, lightColors, oklchToHex, randomRangeValue, relativeLuminance, removeInputPlatformStyling, rgbToHex, schemeHues, toTypeface, toTypefaces, uniColor };
1239
1854
 
1240
1855
  //# sourceMappingURL=index.js.map