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