@bison-lab/tokens 3.6.0 → 3.7.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.
- package/dist/index.d.mts +121 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +122 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -568,6 +568,17 @@ declare function relativeLuminance(color: ColorInput): number;
|
|
|
568
568
|
declare function contrastRatio(a: ColorInput, b: ColorInput): number;
|
|
569
569
|
/** The WCAG text ratings a ratio earns: 3:1 large text, 4.5:1 AA, 7:1 AAA. */
|
|
570
570
|
declare function rateContrast(ratio: number): ContrastRating;
|
|
571
|
+
/** The level word both `ContrastStrip` and the Theme admin field show. */
|
|
572
|
+
declare function contrastLevelLabel(level: ContrastLevel): string;
|
|
573
|
+
interface ContrastVerdict {
|
|
574
|
+
meets: boolean;
|
|
575
|
+
text: string;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Whether `sample` clears `target`, and the sentence both renderers print
|
|
579
|
+
* (`"meets 4.5:1"` / `"below 7:1"`).
|
|
580
|
+
*/
|
|
581
|
+
declare function contrastVerdict(sample: Pick<ContrastSample, "ratio">, target: number): ContrastVerdict;
|
|
571
582
|
/**
|
|
572
583
|
* Measures every text-carrying pairing the palette derives for these
|
|
573
584
|
* colours, in light and dark. Advice, not enforcement: nothing here refuses
|
|
@@ -580,5 +591,114 @@ declare function rateContrast(ratio: number): ContrastRating;
|
|
|
580
591
|
*/
|
|
581
592
|
declare function auditTheme(config: ContrastThemeInput, options?: AuditThemeOptions): ContrastCheck[];
|
|
582
593
|
//#endregion
|
|
583
|
-
|
|
594
|
+
//#region src/preset-hints.d.ts
|
|
595
|
+
/**
|
|
596
|
+
* The label and hint the CLI and the Theme Global show for each preset
|
|
597
|
+
* value. One record, so the two cannot drift.
|
|
598
|
+
*/
|
|
599
|
+
interface PresetHint {
|
|
600
|
+
label: string;
|
|
601
|
+
hint: string;
|
|
602
|
+
}
|
|
603
|
+
declare const presetHints: {
|
|
604
|
+
readonly greyScale: {
|
|
605
|
+
readonly slate: {
|
|
606
|
+
readonly label: "Slate";
|
|
607
|
+
readonly hint: "Cool blue-grey — modern, tech-forward";
|
|
608
|
+
};
|
|
609
|
+
readonly gray: {
|
|
610
|
+
readonly label: "Gray";
|
|
611
|
+
readonly hint: "Balanced blue-grey — neutral default";
|
|
612
|
+
};
|
|
613
|
+
readonly zinc: {
|
|
614
|
+
readonly label: "Zinc";
|
|
615
|
+
readonly hint: "Cool desaturated — minimal, sharp";
|
|
616
|
+
};
|
|
617
|
+
readonly neutral: {
|
|
618
|
+
readonly label: "Neutral";
|
|
619
|
+
readonly hint: "Pure grey — zero hue bias";
|
|
620
|
+
};
|
|
621
|
+
readonly stone: {
|
|
622
|
+
readonly label: "Stone";
|
|
623
|
+
readonly hint: "Warm earthy grey — organic, approachable";
|
|
624
|
+
};
|
|
625
|
+
};
|
|
626
|
+
readonly radius: {
|
|
627
|
+
readonly sharp: {
|
|
628
|
+
readonly label: "Sharp";
|
|
629
|
+
readonly hint: "0px — square corners";
|
|
630
|
+
};
|
|
631
|
+
readonly subtle: {
|
|
632
|
+
readonly label: "Subtle";
|
|
633
|
+
readonly hint: "6px — barely rounded";
|
|
634
|
+
};
|
|
635
|
+
readonly rounded: {
|
|
636
|
+
readonly label: "Rounded";
|
|
637
|
+
readonly hint: "8px — balanced (default)";
|
|
638
|
+
};
|
|
639
|
+
readonly pill: {
|
|
640
|
+
readonly label: "Pill";
|
|
641
|
+
readonly hint: "12px — soft, bubbly";
|
|
642
|
+
};
|
|
643
|
+
};
|
|
644
|
+
readonly shadow: {
|
|
645
|
+
readonly flat: {
|
|
646
|
+
readonly label: "Flat";
|
|
647
|
+
readonly hint: "No shadows — clean, modern";
|
|
648
|
+
};
|
|
649
|
+
readonly subtle: {
|
|
650
|
+
readonly label: "Subtle";
|
|
651
|
+
readonly hint: "Soft low-opacity shadows (default)";
|
|
652
|
+
};
|
|
653
|
+
readonly elevated: {
|
|
654
|
+
readonly label: "Elevated";
|
|
655
|
+
readonly hint: "Prominent layered shadows";
|
|
656
|
+
};
|
|
657
|
+
};
|
|
658
|
+
readonly motion: {
|
|
659
|
+
readonly snappy: {
|
|
660
|
+
readonly label: "Snappy";
|
|
661
|
+
readonly hint: "Fast, spring-like (150ms)";
|
|
662
|
+
};
|
|
663
|
+
readonly smooth: {
|
|
664
|
+
readonly label: "Smooth";
|
|
665
|
+
readonly hint: "Balanced ease-out (200ms, default)";
|
|
666
|
+
};
|
|
667
|
+
readonly minimal: {
|
|
668
|
+
readonly label: "Minimal";
|
|
669
|
+
readonly hint: "Barely-there, linear (100ms)";
|
|
670
|
+
};
|
|
671
|
+
};
|
|
672
|
+
readonly density: {
|
|
673
|
+
readonly compact: {
|
|
674
|
+
readonly label: "Compact";
|
|
675
|
+
readonly hint: "Tight padding, smaller components";
|
|
676
|
+
};
|
|
677
|
+
readonly default: {
|
|
678
|
+
readonly label: "Default";
|
|
679
|
+
readonly hint: "Balanced spacing";
|
|
680
|
+
};
|
|
681
|
+
readonly spacious: {
|
|
682
|
+
readonly label: "Spacious";
|
|
683
|
+
readonly hint: "Generous padding, larger components";
|
|
684
|
+
};
|
|
685
|
+
};
|
|
686
|
+
readonly defaultTheme: {
|
|
687
|
+
readonly system: {
|
|
688
|
+
readonly label: "System";
|
|
689
|
+
readonly hint: "Follow OS preference (recommended)";
|
|
690
|
+
};
|
|
691
|
+
readonly light: {
|
|
692
|
+
readonly label: "Light";
|
|
693
|
+
readonly hint: "Always start in light mode";
|
|
694
|
+
};
|
|
695
|
+
readonly dark: {
|
|
696
|
+
readonly label: "Dark";
|
|
697
|
+
readonly hint: "Always start in dark mode";
|
|
698
|
+
};
|
|
699
|
+
};
|
|
700
|
+
};
|
|
701
|
+
type PresetHintFamily = keyof typeof presetHints;
|
|
702
|
+
//#endregion
|
|
703
|
+
export { type AnimationPresets, type AuditThemeOptions, type BrandColors, type BrandScales, type BuildThemeCssOptions, type ColorInput, type ColorScale, type ContrastCheck, type ContrastLevel, type ContrastRating, type ContrastRole, type ContrastSample, type ContrastThemeInput, type ContrastVerdict, DEFAULT_DARK_SELECTOR, DESTRUCTIVE_SCALE_HEX, type DensityPreset, type FontWeightMap, GREY_SCALES, type GreyScale, type HSL, type MotionPreset, type MotionVariant, type OKLCH, type PresetHint, type PresetHintFamily, type RadiusPreset, SHADE_STEPS, type SemanticPalette, type ShadeStep, type ShadowPreset, type StaggerContainerVariant, type ThemeConfig, type ZIndexToken, auditTheme, brandColorsFromConfig, buildThemeCss, contrastLevelLabel, contrastRatio, contrastVerdict, defaultFontWeights, densityPresets, deriveDarkPalette, deriveLightPalette, generateBrandScales, generateColorScale, generateDestructiveScaleCSS, generatePaletteCSS, generateScaleCSS, getAnimationPresets, getDestructiveColorScale, hexToHSL, hexToOklch, hslToString, isThemeHex, motionPresets, oklchToHslString, presetHints, radiusPresets, rateContrast, relativeLuminance, shadowPresets, spacingScale, themeFontIds, typeScale, zIndexTokens };
|
|
584
704
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/colors.ts","../src/oklch.ts","../src/radius.ts","../src/shadows.ts","../src/motion.ts","../src/density.ts","../src/typography.ts","../src/spacing.ts","../src/z-index.ts","../src/animation-presets.ts","../src/theme.ts","../src/contrast.ts"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/colors.ts","../src/oklch.ts","../src/radius.ts","../src/shadows.ts","../src/motion.ts","../src/density.ts","../src/typography.ts","../src/spacing.ts","../src/z-index.ts","../src/animation-presets.ts","../src/theme.ts","../src/contrast.ts","../src/preset-hints.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1137,6 +1137,27 @@ function rateContrast(ratio) {
|
|
|
1137
1137
|
level: aaa ? "aaa" : aa ? "aa" : aaLarge ? "aa-large" : "fail"
|
|
1138
1138
|
};
|
|
1139
1139
|
}
|
|
1140
|
+
const LEVEL_LABEL = {
|
|
1141
|
+
aaa: "AAA",
|
|
1142
|
+
aa: "AA",
|
|
1143
|
+
"aa-large": "AA large",
|
|
1144
|
+
fail: "Fails"
|
|
1145
|
+
};
|
|
1146
|
+
/** The level word both `ContrastStrip` and the Theme admin field show. */
|
|
1147
|
+
function contrastLevelLabel(level) {
|
|
1148
|
+
return LEVEL_LABEL[level];
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Whether `sample` clears `target`, and the sentence both renderers print
|
|
1152
|
+
* (`"meets 4.5:1"` / `"below 7:1"`).
|
|
1153
|
+
*/
|
|
1154
|
+
function contrastVerdict(sample, target) {
|
|
1155
|
+
const meets = sample.ratio >= target;
|
|
1156
|
+
return {
|
|
1157
|
+
meets,
|
|
1158
|
+
text: `${meets ? "meets" : "below"} ${target}:1`
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1140
1161
|
/** Every pairing in the system that carries text, plus the focus ring. */
|
|
1141
1162
|
const PAIRINGS = [
|
|
1142
1163
|
{
|
|
@@ -1303,6 +1324,106 @@ function auditTheme(config, options = {}) {
|
|
|
1303
1324
|
});
|
|
1304
1325
|
}
|
|
1305
1326
|
//#endregion
|
|
1306
|
-
|
|
1327
|
+
//#region src/preset-hints.ts
|
|
1328
|
+
const presetHints = {
|
|
1329
|
+
greyScale: {
|
|
1330
|
+
slate: {
|
|
1331
|
+
label: "Slate",
|
|
1332
|
+
hint: "Cool blue-grey — modern, tech-forward"
|
|
1333
|
+
},
|
|
1334
|
+
gray: {
|
|
1335
|
+
label: "Gray",
|
|
1336
|
+
hint: "Balanced blue-grey — neutral default"
|
|
1337
|
+
},
|
|
1338
|
+
zinc: {
|
|
1339
|
+
label: "Zinc",
|
|
1340
|
+
hint: "Cool desaturated — minimal, sharp"
|
|
1341
|
+
},
|
|
1342
|
+
neutral: {
|
|
1343
|
+
label: "Neutral",
|
|
1344
|
+
hint: "Pure grey — zero hue bias"
|
|
1345
|
+
},
|
|
1346
|
+
stone: {
|
|
1347
|
+
label: "Stone",
|
|
1348
|
+
hint: "Warm earthy grey — organic, approachable"
|
|
1349
|
+
}
|
|
1350
|
+
},
|
|
1351
|
+
radius: {
|
|
1352
|
+
sharp: {
|
|
1353
|
+
label: "Sharp",
|
|
1354
|
+
hint: "0px — square corners"
|
|
1355
|
+
},
|
|
1356
|
+
subtle: {
|
|
1357
|
+
label: "Subtle",
|
|
1358
|
+
hint: "6px — barely rounded"
|
|
1359
|
+
},
|
|
1360
|
+
rounded: {
|
|
1361
|
+
label: "Rounded",
|
|
1362
|
+
hint: "8px — balanced (default)"
|
|
1363
|
+
},
|
|
1364
|
+
pill: {
|
|
1365
|
+
label: "Pill",
|
|
1366
|
+
hint: "12px — soft, bubbly"
|
|
1367
|
+
}
|
|
1368
|
+
},
|
|
1369
|
+
shadow: {
|
|
1370
|
+
flat: {
|
|
1371
|
+
label: "Flat",
|
|
1372
|
+
hint: "No shadows — clean, modern"
|
|
1373
|
+
},
|
|
1374
|
+
subtle: {
|
|
1375
|
+
label: "Subtle",
|
|
1376
|
+
hint: "Soft low-opacity shadows (default)"
|
|
1377
|
+
},
|
|
1378
|
+
elevated: {
|
|
1379
|
+
label: "Elevated",
|
|
1380
|
+
hint: "Prominent layered shadows"
|
|
1381
|
+
}
|
|
1382
|
+
},
|
|
1383
|
+
motion: {
|
|
1384
|
+
snappy: {
|
|
1385
|
+
label: "Snappy",
|
|
1386
|
+
hint: "Fast, spring-like (150ms)"
|
|
1387
|
+
},
|
|
1388
|
+
smooth: {
|
|
1389
|
+
label: "Smooth",
|
|
1390
|
+
hint: "Balanced ease-out (200ms, default)"
|
|
1391
|
+
},
|
|
1392
|
+
minimal: {
|
|
1393
|
+
label: "Minimal",
|
|
1394
|
+
hint: "Barely-there, linear (100ms)"
|
|
1395
|
+
}
|
|
1396
|
+
},
|
|
1397
|
+
density: {
|
|
1398
|
+
compact: {
|
|
1399
|
+
label: "Compact",
|
|
1400
|
+
hint: "Tight padding, smaller components"
|
|
1401
|
+
},
|
|
1402
|
+
default: {
|
|
1403
|
+
label: "Default",
|
|
1404
|
+
hint: "Balanced spacing"
|
|
1405
|
+
},
|
|
1406
|
+
spacious: {
|
|
1407
|
+
label: "Spacious",
|
|
1408
|
+
hint: "Generous padding, larger components"
|
|
1409
|
+
}
|
|
1410
|
+
},
|
|
1411
|
+
defaultTheme: {
|
|
1412
|
+
system: {
|
|
1413
|
+
label: "System",
|
|
1414
|
+
hint: "Follow OS preference (recommended)"
|
|
1415
|
+
},
|
|
1416
|
+
light: {
|
|
1417
|
+
label: "Light",
|
|
1418
|
+
hint: "Always start in light mode"
|
|
1419
|
+
},
|
|
1420
|
+
dark: {
|
|
1421
|
+
label: "Dark",
|
|
1422
|
+
hint: "Always start in dark mode"
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
};
|
|
1426
|
+
//#endregion
|
|
1427
|
+
export { DEFAULT_DARK_SELECTOR, DESTRUCTIVE_SCALE_HEX, GREY_SCALES, SHADE_STEPS, auditTheme, brandColorsFromConfig, buildThemeCss, contrastLevelLabel, contrastRatio, contrastVerdict, defaultFontWeights, densityPresets, deriveDarkPalette, deriveLightPalette, generateBrandScales, generateColorScale, generateDestructiveScaleCSS, generatePaletteCSS, generateScaleCSS, getAnimationPresets, getDestructiveColorScale, hexToHSL, hexToOklch, hslToString, isThemeHex, motionPresets, oklchToHslString, presetHints, radiusPresets, rateContrast, relativeLuminance, shadowPresets, spacingScale, themeFontIds, typeScale, zIndexTokens };
|
|
1307
1428
|
|
|
1308
1429
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/oklch.ts","../src/colors.ts","../src/radius.ts","../src/shadows.ts","../src/motion.ts","../src/density.ts","../src/typography.ts","../src/spacing.ts","../src/z-index.ts","../src/animation-presets.ts","../src/theme.ts","../src/contrast.ts"],"sourcesContent":["/**\n * OKLCH color space math — zero dependencies.\n * hex → sRGB → linear sRGB → OKLab (matrix) → OKLCH (polar)\n * Reverse: OKLCH → OKLab → linear sRGB → sRGB → HSL string\n * Gamut clamping via binary search on chroma (12 iterations).\n */\n\nexport interface OKLCH {\n L: number; // lightness 0–1\n C: number; // chroma ≥ 0\n H: number; // hue 0–360\n}\n\n// --- sRGB ↔ linear sRGB ---\n\nfunction srgbToLinear(c: number): number {\n return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n}\n\nfunction linearToSrgb(c: number): number {\n return c <= 0.0031308 ? c * 12.92 : 1.055 * Math.pow(c, 1 / 2.4) - 0.055;\n}\n\n// --- Hex → sRGB ---\n\nfunction hexToSrgb(hex: string): [number, number, number] {\n hex = hex.replace(\"#\", \"\");\n return [\n parseInt(hex.substring(0, 2), 16) / 255,\n parseInt(hex.substring(2, 4), 16) / 255,\n parseInt(hex.substring(4, 6), 16) / 255,\n ];\n}\n\n// --- linear sRGB ↔ OKLab ---\n\nfunction linearSrgbToOklab(r: number, g: number, b: number): [number, number, number] {\n const l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;\n const m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;\n const s = 0.0883024619 * r + 0.2024326059 * g + 0.6892649272 * b;\n\n const lc = Math.cbrt(l);\n const mc = Math.cbrt(m);\n const sc = Math.cbrt(s);\n\n return [\n 0.2104542553 * lc + 0.7936177850 * mc - 0.0040720468 * sc,\n 1.9779984951 * lc - 2.4285922050 * mc + 0.4505937099 * sc,\n 0.0259040371 * lc + 0.7827717662 * mc - 0.8086757660 * sc,\n ];\n}\n\nfunction oklabToLinearSrgb(L: number, a: number, b: number): [number, number, number] {\n const lc = L + 0.3963377774 * a + 0.2158037573 * b;\n const mc = L - 0.1055613458 * a - 0.0638541728 * b;\n const sc = L - 0.0894841775 * a - 1.2914855480 * b;\n\n return [\n 4.0767416621 * lc * lc * lc - 3.3077115913 * mc * mc * mc + 0.2309699292 * sc * sc * sc,\n -1.2684380046 * lc * lc * lc + 2.6097574011 * mc * mc * mc - 0.3413193965 * sc * sc * sc,\n -0.0041960863 * lc * lc * lc - 0.7034186147 * mc * mc * mc + 1.7076147010 * sc * sc * sc,\n ];\n}\n\n// --- OKLab ↔ OKLCH ---\n\nfunction oklabToOklch(L: number, a: number, b: number): OKLCH {\n const C = Math.sqrt(a * a + b * b);\n let H = (Math.atan2(b, a) * 180) / Math.PI;\n if (H < 0) H += 360;\n return { L, C, H };\n}\n\nfunction oklchToOklab(L: number, C: number, H: number): [number, number, number] {\n const hRad = (H * Math.PI) / 180;\n return [L, C * Math.cos(hRad), C * Math.sin(hRad)];\n}\n\n// --- Gamut clamping ---\n\nfunction isInGamut(r: number, g: number, b: number): boolean {\n const eps = 1e-4;\n return r >= -eps && r <= 1 + eps && g >= -eps && g <= 1 + eps && b >= -eps && b <= 1 + eps;\n}\n\nfunction gamutClampChroma(L: number, C: number, H: number): number {\n if (C <= 0) return 0;\n\n const [, a, b] = oklchToOklab(L, C, H);\n const [r, g, bl] = oklabToLinearSrgb(L, a, b);\n\n if (isInGamut(r, g, bl)) return C;\n\n let lo = 0;\n let hi = C;\n\n for (let i = 0; i < 12; i++) {\n const mid = (lo + hi) / 2;\n const [, am, bm] = oklchToOklab(L, mid, H);\n const [rm, gm, bm2] = oklabToLinearSrgb(L, am, bm);\n\n if (isInGamut(rm, gm, bm2)) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n\n return lo;\n}\n\n// --- sRGB → HSL ---\n\nfunction srgbToHsl(r: number, g: number, b: number): [number, number, number] {\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n let h = 0;\n let s = 0;\n\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n break;\n case g:\n h = ((b - r) / d + 2) / 6;\n break;\n case b:\n h = ((r - g) / d + 4) / 6;\n break;\n }\n }\n\n return [Math.round(h * 360), Math.round(s * 100), Math.round(l * 100)];\n}\n\n// --- Public API ---\n\nexport function hexToOklch(hex: string): OKLCH {\n const [r, g, b] = hexToSrgb(hex);\n const [lr, lg, lb] = [srgbToLinear(r), srgbToLinear(g), srgbToLinear(b)];\n const [L, a, ob] = linearSrgbToOklab(lr, lg, lb);\n return oklabToOklch(L, a, ob);\n}\n\nexport function oklchToHslString(L: number, C: number, H: number): string {\n const clampedC = gamutClampChroma(L, C, H);\n const [, a, b] = oklchToOklab(L, clampedC, H);\n const [lr, lg, lb] = oklabToLinearSrgb(L, a, b);\n\n const r = Math.min(1, Math.max(0, linearToSrgb(lr)));\n const g = Math.min(1, Math.max(0, linearToSrgb(lg)));\n const bl = Math.min(1, Math.max(0, linearToSrgb(lb)));\n\n const [h, s, l] = srgbToHsl(r, g, bl);\n return `${h} ${s}% ${l}%`;\n}\n","/**\n * Color derivation engine.\n * Takes brand colors (hex) + a grey scale selection and derives\n * a full semantic palette for both light and dark modes,\n * plus 50–950 shade scales via OKLCH color space.\n */\n\nimport { hexToOklch, oklchToHslString } from \"./oklch\";\n\nexport interface HSL {\n h: number;\n s: number;\n l: number;\n}\n\nexport function hexToHSL(hex: string): HSL {\n hex = hex.replace(\"#\", \"\");\n const r = parseInt(hex.substring(0, 2), 16) / 255;\n const g = parseInt(hex.substring(2, 4), 16) / 255;\n const b = parseInt(hex.substring(4, 6), 16) / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n let h = 0;\n let s = 0;\n\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n break;\n case g:\n h = ((b - r) / d + 2) / 6;\n break;\n case b:\n h = ((r - g) / d + 4) / 6;\n break;\n }\n }\n\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n };\n}\n\nexport function hslToString(hsl: HSL): string {\n return `${hsl.h} ${hsl.s}% ${hsl.l}%`;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n// --- Grey scale palettes (Tailwind v4 values as HSL strings) ---\n\nexport type GreyScale = \"slate\" | \"gray\" | \"zinc\" | \"neutral\" | \"stone\";\n\ntype GreyShade = \"50\" | \"100\" | \"200\" | \"300\" | \"400\" | \"500\" | \"600\" | \"700\" | \"800\" | \"900\" | \"950\";\n\ntype GreyPalette = Record<GreyShade, string>;\n\nexport const GREY_SCALES: Record<GreyScale, GreyPalette> = {\n slate: {\n \"50\": \"210 40% 98%\",\n \"100\": \"210 40% 96%\",\n \"200\": \"214 32% 91%\",\n \"300\": \"213 27% 84%\",\n \"400\": \"215 20% 65%\",\n \"500\": \"215 16% 47%\",\n \"600\": \"215 19% 35%\",\n \"700\": \"215 25% 27%\",\n \"800\": \"217 33% 17%\",\n \"900\": \"222 47% 11%\",\n \"950\": \"229 84% 5%\",\n },\n gray: {\n \"50\": \"210 20% 98%\",\n \"100\": \"220 14% 96%\",\n \"200\": \"220 13% 91%\",\n \"300\": \"216 12% 84%\",\n \"400\": \"218 11% 65%\",\n \"500\": \"220 9% 46%\",\n \"600\": \"215 14% 34%\",\n \"700\": \"217 19% 27%\",\n \"800\": \"215 28% 17%\",\n \"900\": \"221 39% 11%\",\n \"950\": \"224 71% 4%\",\n },\n zinc: {\n \"50\": \"0 0% 98%\",\n \"100\": \"240 5% 96%\",\n \"200\": \"240 6% 90%\",\n \"300\": \"240 5% 84%\",\n \"400\": \"240 5% 65%\",\n \"500\": \"240 4% 46%\",\n \"600\": \"240 5% 34%\",\n \"700\": \"240 5% 26%\",\n \"800\": \"240 4% 16%\",\n \"900\": \"240 6% 10%\",\n \"950\": \"240 10% 4%\",\n },\n neutral: {\n \"50\": \"0 0% 98%\",\n \"100\": \"0 0% 96%\",\n \"200\": \"0 0% 90%\",\n \"300\": \"0 0% 83%\",\n \"400\": \"0 0% 64%\",\n \"500\": \"0 0% 45%\",\n \"600\": \"0 0% 32%\",\n \"700\": \"0 0% 25%\",\n \"800\": \"0 0% 15%\",\n \"900\": \"0 0% 9%\",\n \"950\": \"0 0% 4%\",\n },\n stone: {\n \"50\": \"60 9% 98%\",\n \"100\": \"60 5% 96%\",\n \"200\": \"20 6% 90%\",\n \"300\": \"24 6% 83%\",\n \"400\": \"24 5% 64%\",\n \"500\": \"25 5% 45%\",\n \"600\": \"33 5% 32%\",\n \"700\": \"30 6% 25%\",\n \"800\": \"12 6% 15%\",\n \"900\": \"24 10% 10%\",\n \"950\": \"20 14% 4%\",\n },\n};\n\n// --- Brand color types ---\n\nexport interface BrandColors {\n primary: string; // hex\n secondary: string; // hex\n accent?: string; // hex\n highlight?: string; // hex\n success: string; // hex\n grey?: GreyScale; // defaults to \"slate\"\n}\n\n// --- Shade scale types ---\n\nexport const SHADE_STEPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] as const;\nexport type ShadeStep = (typeof SHADE_STEPS)[number];\nexport type ColorScale = Record<ShadeStep, string>;\n\nexport interface BrandScales {\n primary: ColorScale;\n secondary: ColorScale;\n \"brand-accent\": ColorScale;\n highlight: ColorScale;\n success: ColorScale;\n}\n\n// --- Target OKLCH lightness per step ---\n\nconst TARGET_LIGHTNESS: Record<ShadeStep, number> = {\n 50: 0.97,\n 100: 0.93,\n 200: 0.87,\n 300: 0.79,\n 400: 0.70,\n 500: 0.59,\n 600: 0.49,\n 700: 0.39,\n 800: 0.30,\n 900: 0.21,\n 950: 0.14,\n};\n\n// --- Scale generation ---\n\n/**\n * Generate a full 50–950 color scale from a single hex value.\n * Uses OKLCH for perceptual uniformity. The input color is auto-anchored\n * to its closest shade step and reproduced pixel-perfect at that step.\n */\nexport function generateColorScale(hex: string): ColorScale {\n const { L: inputL, C: inputC, H } = hexToOklch(hex);\n\n // Sine-based chroma curve: peaks at mid-lightness, falls toward extremes\n const chromaCurve = (L: number): number => Math.sin(Math.PI * L);\n const inputCurveValue = chromaCurve(inputL);\n\n // Anchor ratio so that input chroma is preserved at input lightness\n const chromaRatio = inputCurveValue > 0.01 ? inputC / inputCurveValue : inputC;\n\n const scale = {} as ColorScale;\n\n for (const step of SHADE_STEPS) {\n const targetL = TARGET_LIGHTNESS[step];\n const targetC = inputCurveValue > 0.01\n ? chromaRatio * chromaCurve(targetL)\n : inputC * chromaCurve(targetL);\n\n scale[step] = oklchToHslString(targetL, targetC, H);\n }\n\n return scale;\n}\n\n/**\n * Generate shade scales for all brand colors.\n */\nexport function generateBrandScales(brand: BrandColors): BrandScales {\n const accentHex = brand.accent ?? brand.primary;\n const highlightHex = brand.highlight ?? brand.secondary;\n\n return {\n primary: generateColorScale(brand.primary),\n secondary: generateColorScale(brand.secondary),\n \"brand-accent\": generateColorScale(accentHex),\n highlight: generateColorScale(highlightHex),\n success: generateColorScale(brand.success),\n };\n}\n\n/**\n * Generate CSS custom property declarations for all brand scales.\n * Output is indented with 2 spaces, suitable for injection into :root {}.\n */\nexport function generateScaleCSS(scales: BrandScales): string {\n const lines: string[] = [];\n\n for (const [colorName, scale] of Object.entries(scales)) {\n for (const step of SHADE_STEPS) {\n lines.push(` --${colorName}-${step}: ${(scale as ColorScale)[step]};`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Canonical red for destructive UI (matches common “danger” hue). Used for the\n * destructive 50–950 scale so tinted surfaces (e.g. soft delete buttons) work\n * like success scales, independent of brand colors.\n */\nexport const DESTRUCTIVE_SCALE_HEX = \"#ef4444\";\n\nlet destructiveColorScaleCache: ColorScale | null = null;\n\nexport function getDestructiveColorScale(): ColorScale {\n if (!destructiveColorScaleCache) {\n destructiveColorScaleCache = generateColorScale(DESTRUCTIVE_SCALE_HEX);\n }\n return destructiveColorScaleCache;\n}\n\n/** CSS custom properties `--destructive-50` … `--destructive-950` for :root injection. */\nexport function generateDestructiveScaleCSS(): string {\n const scale = getDestructiveColorScale();\n return SHADE_STEPS.map((step) => ` --destructive-${step}: ${scale[step]};`).join(\"\\n\");\n}\n\n// --- Semantic palette ---\n\nexport interface SemanticPalette {\n background: string;\n foreground: string;\n card: string;\n \"card-foreground\": string;\n \"surface-tertiary\": string;\n popover: string;\n \"popover-foreground\": string;\n primary: string;\n \"primary-foreground\": string;\n secondary: string;\n \"secondary-foreground\": string;\n accent: string;\n \"accent-foreground\": string;\n \"brand-accent\": string;\n \"brand-accent-foreground\": string;\n highlight: string;\n \"highlight-foreground\": string;\n success: string;\n \"success-foreground\": string;\n muted: string;\n \"muted-foreground\": string;\n \"content-secondary\": string;\n destructive: string;\n \"destructive-foreground\": string;\n border: string;\n \"border-strong\": string;\n \"border-subtle\": string;\n input: string;\n ring: string;\n}\n\n// --- Foreground contrast ---\n\n/**\n * Near-white ink on a dark fill, near-black on a light one. A lightness\n * heuristic, not a measurement: `auditTheme` in `./contrast` is what says\n * whether the pairing actually reads.\n */\nfunction contrastForeground(color: HSL): string {\n return color.l > 55\n ? hslToString({ h: color.h, s: clamp(color.s - 20, 0, 100), l: 10 })\n : hslToString({ h: color.h, s: clamp(color.s - 25, 0, 100), l: 98 });\n}\n\n/**\n * A brand fill lightens in dark mode only below this lightness. The CLI\n * shipped 40 and this module shipped 50 until BIS-57; 40 is the value every\n * generated `bison-theme.css` in the field was built with, and Spinal\n * Simplicity's `globals.css` records why a fill at 43 must not lighten: its\n * derived ink flips to near-black, and the button's fixed `hover:bg-primary-700`\n * then reads at 1.74:1.\n */\nconst DARK_FILL_LIGHTEN_BELOW = 40;\n\n/**\n * The focus ring lightens below this lightness. A ring is a thin outline on\n * the page background and carries no ink, so it is free to lighten where a\n * fill is not: `#DB0082` at 43% is 4.1:1 on zinc-950, at 68% it is 7.1:1.\n */\nconst DARK_RING_LIGHTEN_BELOW = 50;\n\nfunction lightenForDark(color: HSL, below: number): HSL {\n if (color.l < below) {\n return { ...color, l: clamp(color.l + 25, 0, 100) };\n }\n return color;\n}\n\n// --- Palette derivation ---\n\n/**\n * The light semantic palette for a brand. This is the one derivation the\n * CLI (`bison-theme.css`), `BisonProvider` and a CMS theme all share.\n *\n * Decided in BIS-57, where the CLI and this module had drifted:\n * - `muted-foreground` is grey-600, not grey-500. grey-500 is 4.6:1 on the\n * page background, and the token carries card descriptions, hints, table\n * labels and footer lines; grey-600 is 7.4:1. Spinal Simplicity overrode\n * it by hand for its patient audience.\n * - `content-secondary` is grey-500, not grey-400. It is text: the\n * progress bar's percentage label and every chart axis tick use it, and\n * grey-400 is about 2.5:1 on the page background on every scale. grey-500\n * is 4.5:1 or better on both the page background and a card.\n */\nexport function deriveLightPalette(brand: BrandColors): SemanticPalette {\n const grey = GREY_SCALES[brand.grey ?? \"slate\"];\n const primary = hexToHSL(brand.primary);\n const secondary = hexToHSL(brand.secondary);\n const accent = brand.accent ? hexToHSL(brand.accent) : primary;\n const highlight = brand.highlight ? hexToHSL(brand.highlight) : secondary;\n const success = hexToHSL(brand.success);\n\n return {\n background: grey[\"50\"],\n foreground: grey[\"950\"],\n card: \"0 0% 100%\",\n \"card-foreground\": grey[\"950\"],\n \"surface-tertiary\": grey[\"100\"],\n popover: \"0 0% 100%\",\n \"popover-foreground\": grey[\"950\"],\n primary: hslToString(primary),\n \"primary-foreground\": contrastForeground(primary),\n secondary: hslToString(secondary),\n \"secondary-foreground\": contrastForeground(secondary),\n accent: grey[\"100\"],\n \"accent-foreground\": grey[\"950\"],\n \"brand-accent\": hslToString(accent),\n \"brand-accent-foreground\": contrastForeground(accent),\n highlight: hslToString(highlight),\n \"highlight-foreground\": contrastForeground(highlight),\n success: hslToString(success),\n \"success-foreground\": contrastForeground(success),\n muted: grey[\"100\"],\n \"muted-foreground\": grey[\"600\"],\n \"content-secondary\": grey[\"500\"],\n destructive: \"0 84% 60%\",\n \"destructive-foreground\": \"0 0% 98%\",\n border: grey[\"200\"],\n \"border-strong\": grey[\"300\"],\n \"border-subtle\": grey[\"100\"],\n input: grey[\"200\"],\n ring: hslToString(primary),\n };\n}\n\n/**\n * The dark semantic palette for a brand, derived from the same inputs as\n * the light one: no manual dark palette.\n *\n * Decided in BIS-57, where the CLI and this module had drifted:\n * - Brand fills lighten only below lightness 40 (`DARK_FILL_LIGHTEN_BELOW`);\n * the ring lightens below 50 (`DARK_RING_LIGHTEN_BELOW`). See both.\n * - `muted-foreground` is grey-300, not grey-400. grey-400 is 6.9:1 on\n * `card`, where most supporting copy sits; grey-300 clears 7:1 on both\n * surfaces.\n * - `content-secondary` is grey-400, not grey-500. grey-500 on `card` is\n * about 3.7:1, under AA; grey-400 is about 7:1.\n * - `destructive` is `0 62% 30%`, not `0 84% 65%`. `destructive-foreground`\n * (`0 0% 98%`) is 9.8:1 on the former and 3.2:1 on the latter, which\n * fails AA for the button label.\n */\nexport function deriveDarkPalette(brand: BrandColors): SemanticPalette {\n const grey = GREY_SCALES[brand.grey ?? \"slate\"];\n const primaryHsl = hexToHSL(brand.primary);\n const primary = lightenForDark(primaryHsl, DARK_FILL_LIGHTEN_BELOW);\n const secondary = lightenForDark(hexToHSL(brand.secondary), DARK_FILL_LIGHTEN_BELOW);\n const accent = lightenForDark(brand.accent ? hexToHSL(brand.accent) : primaryHsl, DARK_FILL_LIGHTEN_BELOW);\n const highlight = lightenForDark(\n brand.highlight ? hexToHSL(brand.highlight) : hexToHSL(brand.secondary),\n DARK_FILL_LIGHTEN_BELOW,\n );\n const success = lightenForDark(hexToHSL(brand.success), DARK_FILL_LIGHTEN_BELOW);\n const ring = lightenForDark(primaryHsl, DARK_RING_LIGHTEN_BELOW);\n\n return {\n background: grey[\"950\"],\n foreground: grey[\"50\"],\n card: grey[\"900\"],\n \"card-foreground\": grey[\"50\"],\n \"surface-tertiary\": grey[\"800\"],\n popover: grey[\"900\"],\n \"popover-foreground\": grey[\"50\"],\n primary: hslToString(primary),\n \"primary-foreground\": contrastForeground(primary),\n secondary: hslToString(secondary),\n \"secondary-foreground\": contrastForeground(secondary),\n accent: grey[\"800\"],\n \"accent-foreground\": grey[\"50\"],\n \"brand-accent\": hslToString(accent),\n \"brand-accent-foreground\": contrastForeground(accent),\n highlight: hslToString(highlight),\n \"highlight-foreground\": contrastForeground(highlight),\n success: hslToString(success),\n \"success-foreground\": contrastForeground(success),\n muted: grey[\"800\"],\n \"muted-foreground\": grey[\"300\"],\n \"content-secondary\": grey[\"400\"],\n destructive: \"0 62% 30%\",\n \"destructive-foreground\": \"0 0% 98%\",\n border: grey[\"800\"],\n \"border-strong\": grey[\"700\"],\n \"border-subtle\": grey[\"900\"],\n input: grey[\"800\"],\n ring: hslToString(ring),\n };\n}\n\nexport function generatePaletteCSS(brand: BrandColors, attribute: \"class\" | \"data-theme\" = \"class\"): string {\n const light = deriveLightPalette(brand);\n const dark = deriveDarkPalette(brand);\n const scales = generateBrandScales(brand);\n\n const toVars = (palette: SemanticPalette, indent: string) =>\n Object.entries(palette)\n .map(([key, value]) => `${indent}--${key}: ${value};`)\n .join(\"\\n\");\n\n const darkSelector = attribute === \"class\" ? \".dark\" : '[data-theme=\"dark\"]';\n\n return `:root {\\n${toVars(light, \" \")}\\n\\n${generateScaleCSS(scales)}\\n\\n${generateDestructiveScaleCSS()}\\n}\\n\\n${darkSelector} {\\n${toVars(dark, \" \")}\\n}\\n`;\n}\n","export const radiusPresets = {\n sharp: {\n \"--radius\": \"0rem\",\n \"--radius-sm\": \"0rem\",\n \"--radius-md\": \"0rem\",\n \"--radius-lg\": \"0rem\",\n \"--radius-xl\": \"0rem\",\n \"--radius-full\": \"0rem\",\n },\n subtle: {\n \"--radius\": \"0.375rem\",\n \"--radius-sm\": \"0.375rem\",\n \"--radius-md\": \"0.375rem\",\n \"--radius-lg\": \"0.5rem\",\n \"--radius-xl\": \"0.75rem\",\n \"--radius-full\": \"9999px\",\n },\n rounded: {\n \"--radius\": \"0.5rem\",\n \"--radius-sm\": \"0.5rem\",\n \"--radius-md\": \"0.5rem\",\n \"--radius-lg\": \"0.75rem\",\n \"--radius-xl\": \"1rem\",\n \"--radius-full\": \"9999px\",\n },\n pill: {\n \"--radius\": \"0.75rem\",\n \"--radius-sm\": \"0.75rem\",\n \"--radius-md\": \"0.75rem\",\n \"--radius-lg\": \"1rem\",\n \"--radius-xl\": \"1.5rem\",\n \"--radius-full\": \"9999px\",\n },\n} as const;\n\nexport type RadiusPreset = keyof typeof radiusPresets;\n","export const shadowPresets = {\n flat: {\n \"--shadow-sm\": \"none\",\n \"--shadow\": \"none\",\n \"--shadow-md\": \"none\",\n \"--shadow-lg\": \"none\",\n \"--shadow-xl\": \"none\",\n },\n subtle: {\n \"--shadow-sm\": \"0 1px 2px 0 rgb(0 0 0 / 0.03)\",\n \"--shadow\": \"0 1px 3px 0 rgb(0 0 0 / 0.05), 0 1px 2px -1px rgb(0 0 0 / 0.05)\",\n \"--shadow-md\": \"0 4px 6px -1px rgb(0 0 0 / 0.05), 0 2px 4px -2px rgb(0 0 0 / 0.05)\",\n \"--shadow-lg\": \"0 10px 15px -3px rgb(0 0 0 / 0.05), 0 4px 6px -4px rgb(0 0 0 / 0.05)\",\n \"--shadow-xl\": \"0 20px 25px -5px rgb(0 0 0 / 0.05), 0 8px 10px -6px rgb(0 0 0 / 0.05)\",\n },\n elevated: {\n \"--shadow-sm\": \"0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.1)\",\n \"--shadow\": \"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)\",\n \"--shadow-md\": \"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)\",\n \"--shadow-lg\": \"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)\",\n \"--shadow-xl\": \"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)\",\n },\n} as const;\n\nexport type ShadowPreset = keyof typeof shadowPresets;\n","export const motionPresets = {\n snappy: {\n \"--duration-fast\": \"100ms\",\n \"--duration-normal\": \"150ms\",\n \"--duration-slow\": \"250ms\",\n \"--ease-default\": \"cubic-bezier(0.22, 1, 0.36, 1)\",\n \"--ease-in\": \"cubic-bezier(0.55, 0, 1, 0.45)\",\n \"--ease-out\": \"cubic-bezier(0, 0.55, 0.45, 1)\",\n \"--ease-in-out\": \"cubic-bezier(0.65, 0, 0.35, 1)\",\n },\n smooth: {\n \"--duration-fast\": \"150ms\",\n \"--duration-normal\": \"200ms\",\n \"--duration-slow\": \"350ms\",\n \"--ease-default\": \"cubic-bezier(0.25, 0.1, 0.25, 1)\",\n \"--ease-in\": \"cubic-bezier(0.42, 0, 1, 1)\",\n \"--ease-out\": \"cubic-bezier(0, 0, 0.58, 1)\",\n \"--ease-in-out\": \"cubic-bezier(0.42, 0, 0.58, 1)\",\n },\n minimal: {\n \"--duration-fast\": \"75ms\",\n \"--duration-normal\": \"100ms\",\n \"--duration-slow\": \"200ms\",\n \"--ease-default\": \"linear\",\n \"--ease-in\": \"linear\",\n \"--ease-out\": \"linear\",\n \"--ease-in-out\": \"linear\",\n },\n} as const;\n\nexport type MotionPreset = keyof typeof motionPresets;\n","export const densityPresets = {\n compact: {\n \"--density-padding-xs\": \"0.125rem\",\n \"--density-padding-sm\": \"0.25rem\",\n \"--density-padding-md\": \"0.375rem\",\n \"--density-padding-lg\": \"0.5rem\",\n \"--density-padding-xl\": \"0.75rem\",\n \"--density-gap-sm\": \"0.25rem\",\n \"--density-gap-md\": \"0.5rem\",\n \"--density-gap-lg\": \"0.75rem\",\n \"--density-height-sm\": \"1.75rem\",\n \"--density-height-md\": \"2rem\",\n \"--density-height-lg\": \"2.5rem\",\n },\n default: {\n \"--density-padding-xs\": \"0.25rem\",\n \"--density-padding-sm\": \"0.5rem\",\n \"--density-padding-md\": \"0.75rem\",\n \"--density-padding-lg\": \"1rem\",\n \"--density-padding-xl\": \"1.5rem\",\n \"--density-gap-sm\": \"0.5rem\",\n \"--density-gap-md\": \"0.75rem\",\n \"--density-gap-lg\": \"1rem\",\n \"--density-height-sm\": \"2rem\",\n \"--density-height-md\": \"2.5rem\",\n \"--density-height-lg\": \"3rem\",\n },\n spacious: {\n \"--density-padding-xs\": \"0.5rem\",\n \"--density-padding-sm\": \"0.75rem\",\n \"--density-padding-md\": \"1rem\",\n \"--density-padding-lg\": \"1.5rem\",\n \"--density-padding-xl\": \"2rem\",\n \"--density-gap-sm\": \"0.75rem\",\n \"--density-gap-md\": \"1rem\",\n \"--density-gap-lg\": \"1.5rem\",\n \"--density-height-sm\": \"2.5rem\",\n \"--density-height-md\": \"3rem\",\n \"--density-height-lg\": \"3.5rem\",\n },\n} as const;\n\nexport type DensityPreset = keyof typeof densityPresets;\n","/** Locked type scale — consumers cannot override sizes, only font-family and weights. */\nexport const typeScale = {\n \"text-xs\": { fontSize: \"0.75rem\", lineHeight: \"1rem\" },\n \"text-sm\": { fontSize: \"0.875rem\", lineHeight: \"1.25rem\" },\n \"text-base\": { fontSize: \"1rem\", lineHeight: \"1.5rem\" },\n \"text-lg\": { fontSize: \"1.125rem\", lineHeight: \"1.75rem\" },\n \"text-xl\": { fontSize: \"1.25rem\", lineHeight: \"1.75rem\" },\n \"text-2xl\": { fontSize: \"1.5rem\", lineHeight: \"2rem\" },\n \"text-3xl\": { fontSize: \"1.875rem\", lineHeight: \"2.25rem\" },\n \"text-4xl\": { fontSize: \"2.25rem\", lineHeight: \"2.5rem\" },\n\n // Fluid headings using clamp()\n \"heading-sm\": {\n fontSize: \"clamp(1.125rem, 1rem + 0.5vw, 1.25rem)\",\n lineHeight: \"1.4\",\n letterSpacing: \"-0.01em\",\n },\n \"heading-md\": {\n fontSize: \"clamp(1.25rem, 1rem + 1vw, 1.875rem)\",\n lineHeight: \"1.3\",\n letterSpacing: \"-0.015em\",\n },\n \"heading-lg\": {\n fontSize: \"clamp(1.5rem, 1rem + 2vw, 2.25rem)\",\n lineHeight: \"1.2\",\n letterSpacing: \"-0.02em\",\n },\n \"heading-xl\": {\n fontSize: \"clamp(1.875rem, 1rem + 3vw, 3rem)\",\n lineHeight: \"1.1\",\n letterSpacing: \"-0.025em\",\n },\n \"heading-2xl\": {\n fontSize: \"clamp(2.25rem, 1rem + 4vw, 3.75rem)\",\n lineHeight: \"1.1\",\n letterSpacing: \"-0.03em\",\n },\n} as const;\n\nexport interface FontWeightMap {\n normal: number;\n medium: number;\n semibold: number;\n bold: number;\n extrabold?: number;\n}\n\nexport const defaultFontWeights: FontWeightMap = {\n normal: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n extrabold: 800,\n};\n","/** Locked spacing scale — 4px (0.25rem) base grid. Not consumer-overridable. */\nexport const spacingScale = {\n \"0\": \"0\",\n \"0.5\": \"0.125rem\",\n \"1\": \"0.25rem\",\n \"1.5\": \"0.375rem\",\n \"2\": \"0.5rem\",\n \"2.5\": \"0.625rem\",\n \"3\": \"0.75rem\",\n \"3.5\": \"0.875rem\",\n \"4\": \"1rem\",\n \"5\": \"1.25rem\",\n \"6\": \"1.5rem\",\n \"7\": \"1.75rem\",\n \"8\": \"2rem\",\n \"9\": \"2.25rem\",\n \"10\": \"2.5rem\",\n \"11\": \"2.75rem\",\n \"12\": \"3rem\",\n \"14\": \"3.5rem\",\n \"16\": \"4rem\",\n \"20\": \"5rem\",\n \"24\": \"6rem\",\n \"28\": \"7rem\",\n \"32\": \"8rem\",\n \"36\": \"9rem\",\n \"40\": \"10rem\",\n \"44\": \"11rem\",\n \"48\": \"12rem\",\n \"52\": \"13rem\",\n \"56\": \"14rem\",\n \"60\": \"15rem\",\n \"64\": \"16rem\",\n \"72\": \"18rem\",\n \"80\": \"20rem\",\n \"96\": \"24rem\",\n} as const;\n","/** Z-index tokens — overridable by consumers via CSS custom properties. */\nexport const zIndexTokens = {\n \"--z-dropdown\": \"50\",\n \"--z-sticky\": \"100\",\n \"--z-fixed\": \"200\",\n \"--z-modal-backdrop\": \"300\",\n \"--z-modal\": \"400\",\n \"--z-popover\": \"500\",\n \"--z-tooltip\": \"600\",\n \"--z-toast\": \"700\",\n} as const;\n\nexport type ZIndexToken = keyof typeof zIndexTokens;\n","/**\n * Framer Motion animation presets.\n *\n * Each preset is a Framer Motion `Variants` object with `hidden` and `visible`\n * states, plus optional `exit`. Durations and easings are resolved per motion\n * preset (snappy / smooth / minimal) at call time via `getAnimationPresets()`.\n */\n\nimport { motionPresets, type MotionPreset } from \"./motion\";\n\n// ---------------------------------------------------------------------------\n// Duration / easing helpers\n// ---------------------------------------------------------------------------\n\nfunction parseDuration(ms: string): number {\n return parseInt(ms, 10) / 1000;\n}\n\nfunction parseEasing(raw: string): number[] | string {\n if (raw === \"linear\") return \"linear\" as string;\n const match = raw.match(\n /cubic-bezier\\(\\s*([\\d.]+)\\s*,\\s*([\\d.-]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.-]+)\\s*\\)/\n );\n if (!match) return [0.25, 0.1, 0.25, 1];\n return [Number(match[1]), Number(match[2]), Number(match[3]), Number(match[4])];\n}\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface MotionVariant {\n hidden: Record<string, unknown>;\n visible: Record<string, unknown>;\n exit?: Record<string, unknown>;\n}\n\nexport interface StaggerContainerVariant {\n hidden: Record<string, unknown>;\n visible: Record<string, unknown>;\n}\n\nexport interface AnimationPresets {\n fadeIn: MotionVariant;\n fadeUp: MotionVariant;\n fadeDown: MotionVariant;\n scaleIn: MotionVariant;\n slideInLeft: MotionVariant;\n slideInRight: MotionVariant;\n cardLift: MotionVariant;\n staggerContainer: StaggerContainerVariant;\n staggerItem: MotionVariant;\n pageTransition: MotionVariant;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Returns Framer Motion variant presets tuned to the given motion preset.\n *\n * @example\n * ```tsx\n * import { getAnimationPresets } from \"@bison-lab/tokens\";\n * import { motion } from \"framer-motion\";\n *\n * const presets = getAnimationPresets(\"smooth\");\n *\n * <motion.div variants={presets.fadeUp} initial=\"hidden\" animate=\"visible\">\n * Hello\n * </motion.div>\n * ```\n */\nexport function getAnimationPresets(preset: MotionPreset = \"smooth\"): AnimationPresets {\n const tokens = motionPresets[preset];\n const normal = parseDuration(tokens[\"--duration-normal\"]);\n const slow = parseDuration(tokens[\"--duration-slow\"]);\n const ease = parseEasing(tokens[\"--ease-out\"]);\n\n const transition = { duration: normal, ease };\n const slowTransition = { duration: slow, ease };\n\n return {\n fadeIn: {\n hidden: { opacity: 0 },\n visible: { opacity: 1, transition },\n },\n\n fadeUp: {\n hidden: { opacity: 0, y: 10 },\n visible: { opacity: 1, y: 0, transition },\n },\n\n fadeDown: {\n hidden: { opacity: 0, y: -10 },\n visible: { opacity: 1, y: 0, transition },\n },\n\n scaleIn: {\n hidden: { opacity: 0, scale: 0.97 },\n visible: { opacity: 1, scale: 1, transition },\n },\n\n slideInLeft: {\n hidden: { opacity: 0, x: -16 },\n visible: { opacity: 1, x: 0, transition },\n },\n\n slideInRight: {\n hidden: { opacity: 0, x: 16 },\n visible: { opacity: 1, x: 0, transition },\n },\n\n cardLift: {\n hidden: { opacity: 0, y: 6, scale: 0.99 },\n visible: {\n opacity: 1,\n y: 0,\n scale: 1,\n transition: slowTransition,\n },\n exit: { opacity: 0, y: 4, scale: 0.99, transition },\n },\n\n staggerContainer: {\n hidden: {},\n visible: {\n transition: {\n staggerChildren: 0.07,\n delayChildren: 0.1,\n },\n },\n },\n\n staggerItem: {\n hidden: { opacity: 0, y: 8 },\n visible: { opacity: 1, y: 0, transition },\n },\n\n pageTransition: {\n hidden: { opacity: 0, y: 8 },\n visible: { opacity: 1, y: 0, transition: slowTransition },\n exit: { opacity: 0, y: -6, transition },\n },\n };\n}\n","/**\n * The theme a site configures, and the stylesheet built from it.\n *\n * `ThemeConfig` is the `bison.config.json` shape `@bison-lab/create-theme`\n * writes. `buildThemeCss` turns one into the complete theme stylesheet: the\n * CLI writes it to `bison-theme.css`, and a CMS theme (BIS-60) renders it at\n * request time from the same function, so the two can never disagree.\n */\n\nimport {\n deriveLightPalette,\n deriveDarkPalette,\n generateBrandScales,\n generateScaleCSS,\n generateDestructiveScaleCSS,\n type BrandColors,\n type GreyScale,\n type SemanticPalette,\n} from \"./colors\";\nimport { radiusPresets, type RadiusPreset } from \"./radius\";\nimport { shadowPresets, type ShadowPreset } from \"./shadows\";\nimport { motionPresets, type MotionPreset } from \"./motion\";\nimport { densityPresets, type DensityPreset } from \"./density\";\nimport { fontFaceCss, fontStack, isFontId, type FontId } from \"@bison-lab/fonts\";\n\nexport interface ThemeConfig {\n /** `#rrggbb` */\n brandPrimary: string;\n brandSecondary: string;\n brandAccent: string;\n brandHighlight: string;\n brandSuccess: string;\n greyScale: GreyScale;\n /**\n * The selector the dark block is written under, or `\"@media\"` for a\n * `prefers-color-scheme` query. Defaults to `[data-theme=\"dark\"]`, which\n * is what `ThemeProvider` sets and the Tailwind preset's `dark:` variant\n * reads.\n */\n darkSelector?: string;\n defaultTheme: \"light\" | \"dark\" | \"system\";\n radius: RadiusPreset;\n shadow: ShadowPreset;\n motion: MotionPreset;\n density: DensityPreset;\n /**\n * A catalogue id from `@bison-lab/fonts` (`\"inter\"`). A value that is not\n * one is a legacy family name from an older `bison.config.json` and is\n * quoted into the stack as-is; the CLI migrates it to its id on the next\n * run.\n */\n fontBody: string;\n /** A catalogue id, a legacy family name, or `null` to use `fontBody` for headings. */\n fontHeading: string | null;\n fontWeights: {\n normal: number;\n medium: number;\n semibold: number;\n bold: number;\n };\n}\n\nexport interface BuildThemeCssOptions {\n /**\n * Overrides `config.darkSelector`: `\"class\"` writes the dark block under\n * `.dark`, `\"data-theme\"` under `[data-theme=\"dark\"]`.\n */\n attribute?: \"class\" | \"data-theme\";\n /**\n * When set, the stylesheet opens with the `@font-face` rules for the\n * catalogue families the config names, served from this base URL. The\n * CLI passes `/fonts`; a site rendering the theme at request time may\n * prefer `fontFaceCss` in its own `<head>` and leave this unset.\n */\n fontsBaseUrl?: string;\n}\n\nexport const DEFAULT_DARK_SELECTOR = '[data-theme=\"dark\"]';\n\n/** Whether a value is the six-digit hex colour a theme field must hold. */\nexport function isThemeHex(value: unknown): value is string {\n return typeof value === \"string\" && /^#[0-9a-f]{6}$/i.test(value);\n}\n\ntype ThemeColorFields = Pick<\n ThemeConfig,\n \"brandPrimary\" | \"brandSecondary\" | \"brandAccent\" | \"brandHighlight\" | \"brandSuccess\" | \"greyScale\"\n>;\n\nconst BRAND_FIELDS = [\n \"brandPrimary\",\n \"brandSecondary\",\n \"brandAccent\",\n \"brandHighlight\",\n \"brandSuccess\",\n] as const satisfies readonly (keyof ThemeColorFields)[];\n\n/**\n * Refuses a config whose brand colours are not `#rrggbb`, naming the field.\n * `hexToHSL` reads fixed substrings, so a short or malformed hex would\n * otherwise become `NaN` in the palette without a word: `buildThemeCss`\n * would emit a variable the browser drops, and a five-digit hex would\n * measure a plausible, wrong contrast ratio.\n */\nfunction assertThemeColors(config: ThemeColorFields): void {\n for (const field of BRAND_FIELDS) {\n const value = config[field];\n if (!isThemeHex(value)) {\n throw new Error(`${field} must be a six-digit hex colour like #1e3a5f, got ${JSON.stringify(value)}`);\n }\n }\n}\n\n/** The `BrandColors` a config's five hexes and grey scale describe. Throws on a hex that is not `#rrggbb`. */\nexport function brandColorsFromConfig(config: ThemeColorFields): BrandColors {\n assertThemeColors(config);\n return {\n primary: config.brandPrimary,\n secondary: config.brandSecondary,\n accent: config.brandAccent,\n highlight: config.brandHighlight,\n success: config.brandSuccess,\n grey: config.greyScale,\n };\n}\n\nfunction resolveDarkSelector(config: ThemeConfig, options?: BuildThemeCssOptions): string {\n if (options?.attribute === \"class\") return \".dark\";\n if (options?.attribute === \"data-theme\") return DEFAULT_DARK_SELECTOR;\n return config.darkSelector?.trim() || DEFAULT_DARK_SELECTOR;\n}\n\nconst LEGACY_FONT_FALLBACK = \"ui-sans-serif, system-ui, sans-serif\";\n\n/** The `font-family` value for a config font: the catalogue stack for an id, the CLI's old quoting for a legacy name. */\nfunction fontFamilyValue(value: string): string {\n return isFontId(value) ? fontStack(value) : `'${value}', ${LEGACY_FONT_FALLBACK}`;\n}\n\n/** The catalogue ids a config names, body first, without repeats. A legacy family name is not one. */\nexport function themeFontIds(config: Pick<ThemeConfig, \"fontBody\" | \"fontHeading\">): FontId[] {\n const ids: FontId[] = [];\n for (const value of [config.fontBody, config.fontHeading ?? config.fontBody]) {\n if (isFontId(value) && !ids.includes(value)) ids.push(value);\n }\n return ids;\n}\n\nfunction paletteLines(palette: SemanticPalette, indent: string): string[] {\n return Object.entries(palette).map(([key, value]) => `${indent}--${key}: ${value};`);\n}\n\nfunction presetLines(vars: Record<string, string>): string[] {\n return Object.entries(vars).map(([key, value]) => ` ${key}: ${value};`);\n}\n\n/**\n * The complete theme stylesheet for a config: the light semantic palette,\n * the brand and destructive scales, the four preset variable blocks, the\n * typography variables, and the dark palette under the dark selector.\n *\n * The preset blocks mean a site needs only this file and `base.css`; the\n * preset files under `css/themes/` stay for consumers composing their own\n * theme, and importing both is harmless.\n *\n * Throws, naming the field, when a brand colour is not `#rrggbb`; a CMS\n * that stored a bad value fails loudly rather than shipping a stylesheet\n * with a `NaN` in it. A blank `darkSelector` means the default.\n *\n * `fontBody` / `fontHeading` are catalogue ids and become the catalogue's\n * stack; a legacy family name is quoted as the CLI always wrote it. The\n * `@font-face` rules themselves are written only when `fontsBaseUrl` is\n * given.\n */\nexport function buildThemeCss(config: ThemeConfig, options?: BuildThemeCssOptions): string {\n const brand = brandColorsFromConfig(config);\n const light = deriveLightPalette(brand);\n const dark = deriveDarkPalette(brand);\n const scales = generateBrandScales(brand);\n const darkSelector = resolveDarkSelector(config, options);\n const fontFaces = options?.fontsBaseUrl ? fontFaceCss(themeFontIds(config), options.fontsBaseUrl) : \"\";\n\n const darkBlock =\n darkSelector === \"@media\"\n ? [\n `@media (prefers-color-scheme: dark) {`,\n ` :root {`,\n ...paletteLines(dark, \" \"),\n ` }`,\n `}`,\n ]\n : [`${darkSelector} {`, ...paletteLines(dark, \" \"), `}`];\n\n const lines: string[] = [\n `/* Bison Lab Theme — generated by @bison-lab/tokens buildThemeCss. Do not hand-edit; regenerate from bison.config.json. */`,\n `/* Brand: ${config.brandPrimary} / ${config.brandSecondary} / ${config.brandAccent} / ${config.brandHighlight} / ${config.brandSuccess} */`,\n `/* Grey: ${config.greyScale} */`,\n `/* Presets: radius ${config.radius} · shadow ${config.shadow} · motion ${config.motion} · density ${config.density} */`,\n ``,\n ...(fontFaces ? [fontFaces, ``] : []),\n `:root {`,\n ...paletteLines(light, \" \"),\n ``,\n ` /* Brand color scales (50–950) */`,\n generateScaleCSS(scales),\n ``,\n ` /* Destructive scale (50–950) — soft danger surfaces */`,\n generateDestructiveScaleCSS(),\n ``,\n ` /* Radius preset: ${config.radius} */`,\n ...presetLines(radiusPresets[config.radius]),\n ``,\n ` /* Shadow preset: ${config.shadow} */`,\n ...presetLines(shadowPresets[config.shadow]),\n ``,\n ` /* Motion preset: ${config.motion} */`,\n ...presetLines(motionPresets[config.motion]),\n ``,\n ` /* Density preset: ${config.density} */`,\n ...presetLines(densityPresets[config.density]),\n ``,\n ` /* Typography */`,\n ` --font-body: ${fontFamilyValue(config.fontBody)};`,\n ` --font-heading: ${fontFamilyValue(config.fontHeading ?? config.fontBody)};`,\n ` --font-weight-normal: ${config.fontWeights.normal};`,\n ` --font-weight-medium: ${config.fontWeights.medium};`,\n ` --font-weight-semibold: ${config.fontWeights.semibold};`,\n ` --font-weight-bold: ${config.fontWeights.bold};`,\n ` --font-weight-extrabold: 800;`,\n `}`,\n ``,\n ...darkBlock,\n ``,\n ];\n\n return lines.join(\"\\n\");\n}\n","/**\n * WCAG contrast, measured on the palette a theme derives.\n *\n * Pure functions with no DOM, so the Theme admin (BIS-60) can run them in\n * the browser as the editor types. `auditTheme` returns data only; the\n * `ContrastStrip` that draws it is BIS-59.\n */\n\nimport { deriveLightPalette, deriveDarkPalette, type SemanticPalette } from \"./colors\";\nimport { brandColorsFromConfig, type ThemeConfig } from \"./theme\";\n\n/** `#rrggbb`, or the token form the palettes use: `\"h s% l%\"`. */\nexport type ColorInput = string;\n\nexport type ContrastLevel = \"fail\" | \"aa-large\" | \"aa\" | \"aaa\";\n\n/**\n * What the pairing carries. `text` and `fill-with-text` are held to the\n * body text target; `large-text` to 4.5 under a 7:1 target, else 3;\n * `non-text` (a focus ring, a border) to WCAG 1.4.11's single 3:1 tier.\n */\nexport type ContrastRole = \"text\" | \"large-text\" | \"fill-with-text\" | \"non-text\";\n\nexport interface ContrastRating {\n aa: boolean;\n aaLarge: boolean;\n aaa: boolean;\n level: ContrastLevel;\n}\n\nexport interface ContrastSample {\n ratio: number;\n /** The WCAG text rating of `ratio`, whatever the role. */\n level: ContrastLevel;\n /** The measured colours, in the token form, so a renderer can draw them. */\n foreground: string;\n background: string;\n}\n\nexport interface ContrastCheck {\n /** Stable: `<foreground-token>-on-<background-token>`. */\n id: string;\n /** What the pairing affects, as advice: \"Secondary as eyebrow text on the page background\". */\n label: string;\n role: ContrastRole;\n light: ContrastSample;\n dark: ContrastSample;\n /** The threshold this check was judged against, after the role's rule. */\n target: number;\n /** Both modes at or above `target`. */\n meetsTarget: boolean;\n}\n\nexport type ContrastThemeInput = Pick<\n ThemeConfig,\n \"brandPrimary\" | \"brandSecondary\" | \"brandAccent\" | \"brandHighlight\" | \"brandSuccess\" | \"greyScale\"\n>;\n\nexport interface AuditThemeOptions {\n /** The body text target. 4.5 is AA; a site with an older audience passes 7. */\n target?: number;\n}\n\n// --- Colour parsing ---\n\ntype Rgb = [number, number, number];\n\nfunction hslToRgb(h: number, s: number, l: number): Rgb {\n const chroma = (1 - Math.abs(2 * l - 1)) * s;\n const hue = (((h % 360) + 360) % 360) / 60;\n const x = chroma * (1 - Math.abs((hue % 2) - 1));\n const m = l - chroma / 2;\n let rgb: Rgb;\n if (hue < 1) rgb = [chroma, x, 0];\n else if (hue < 2) rgb = [x, chroma, 0];\n else if (hue < 3) rgb = [0, chroma, x];\n else if (hue < 4) rgb = [0, x, chroma];\n else if (hue < 5) rgb = [x, 0, chroma];\n else rgb = [chroma, 0, x];\n return [rgb[0] + m, rgb[1] + m, rgb[2] + m];\n}\n\nfunction parseColor(input: ColorInput): Rgb {\n const hex = /^#([0-9a-f]{6})$/i.exec(input.trim());\n if (hex) {\n const value = parseInt(hex[1], 16);\n return [(value >> 16) & 255, (value >> 8) & 255, value & 255].map((channel) => channel / 255) as Rgb;\n }\n const triplet = /^(-?[\\d.]+)\\s+([\\d.]+)%\\s+([\\d.]+)%$/.exec(input.trim());\n if (triplet) {\n return hslToRgb(Number(triplet[1]), Number(triplet[2]) / 100, Number(triplet[3]) / 100);\n }\n throw new Error(`Not a colour this module reads: \"${input}\". Pass #rrggbb or \"h s% l%\".`);\n}\n\n// --- WCAG 2.x ---\n\nfunction linearChannel(channel: number): number {\n return channel <= 0.04045 ? channel / 12.92 : Math.pow((channel + 0.055) / 1.055, 2.4);\n}\n\n/** WCAG relative luminance, 0 for black to 1 for white. */\nexport function relativeLuminance(color: ColorInput): number {\n const [r, g, b] = parseColor(color);\n return 0.2126 * linearChannel(r) + 0.7152 * linearChannel(g) + 0.0722 * linearChannel(b);\n}\n\n/** WCAG contrast ratio between two colours, 1 to 21, to two decimal places. Order does not matter. */\nexport function contrastRatio(a: ColorInput, b: ColorInput): number {\n const la = relativeLuminance(a);\n const lb = relativeLuminance(b);\n const ratio = (Math.max(la, lb) + 0.05) / (Math.min(la, lb) + 0.05);\n return Math.round(ratio * 100) / 100;\n}\n\n/** The WCAG text ratings a ratio earns: 3:1 large text, 4.5:1 AA, 7:1 AAA. */\nexport function rateContrast(ratio: number): ContrastRating {\n const aaLarge = ratio >= 3;\n const aa = ratio >= 4.5;\n const aaa = ratio >= 7;\n return { aa, aaLarge, aaa, level: aaa ? \"aaa\" : aa ? \"aa\" : aaLarge ? \"aa-large\" : \"fail\" };\n}\n\n// --- The audit ---\n\ntype PaletteToken = keyof SemanticPalette;\n\ninterface Pairing {\n foreground: PaletteToken;\n background: PaletteToken;\n role: ContrastRole;\n label: string;\n}\n\n/** Every pairing in the system that carries text, plus the focus ring. */\nconst PAIRINGS: readonly Pairing[] = [\n { foreground: \"primary-foreground\", background: \"primary\", role: \"fill-with-text\", label: \"Primary button label on the primary fill\" },\n { foreground: \"secondary-foreground\", background: \"secondary\", role: \"fill-with-text\", label: \"Secondary button label on the secondary fill\" },\n { foreground: \"brand-accent-foreground\", background: \"brand-accent\", role: \"fill-with-text\", label: \"Copy on a brand-accent band\" },\n { foreground: \"highlight-foreground\", background: \"highlight\", role: \"fill-with-text\", label: \"Copy on a highlight fill\" },\n { foreground: \"success-foreground\", background: \"success\", role: \"fill-with-text\", label: \"Success badge label on its fill\" },\n { foreground: \"destructive-foreground\", background: \"destructive\", role: \"fill-with-text\", label: \"Destructive button label on its fill\" },\n { foreground: \"accent-foreground\", background: \"accent\", role: \"fill-with-text\", label: \"Hovered and selected item text on the accent surface\" },\n { foreground: \"muted-foreground\", background: \"muted\", role: \"fill-with-text\", label: \"Hint text on a muted surface\" },\n { foreground: \"card-foreground\", background: \"card\", role: \"fill-with-text\", label: \"Card body text on the card surface\" },\n { foreground: \"popover-foreground\", background: \"popover\", role: \"fill-with-text\", label: \"Menu and popover text on the popover surface\" },\n { foreground: \"foreground\", background: \"background\", role: \"text\", label: \"Body text on the page background\" },\n { foreground: \"foreground\", background: \"card\", role: \"text\", label: \"Body text on a card\" },\n { foreground: \"muted-foreground\", background: \"background\", role: \"text\", label: \"Supporting text on the page background\" },\n { foreground: \"muted-foreground\", background: \"card\", role: \"text\", label: \"Supporting text on a card\" },\n { foreground: \"content-secondary\", background: \"background\", role: \"text\", label: \"Chart axis labels and tertiary text on the page background\" },\n { foreground: \"content-secondary\", background: \"card\", role: \"text\", label: \"Chart axis labels and tertiary text on a card\" },\n { foreground: \"primary\", background: \"background\", role: \"text\", label: \"Primary as link text on the page background\" },\n { foreground: \"secondary\", background: \"background\", role: \"text\", label: \"Secondary as eyebrow text on the page background\" },\n { foreground: \"ring\", background: \"background\", role: \"non-text\", label: \"Focus ring on the page background\" },\n];\n\nfunction roleTarget(role: ContrastRole, target: number): number {\n switch (role) {\n case \"non-text\":\n return 3;\n case \"large-text\":\n return target >= 7 ? 4.5 : 3;\n default:\n return target;\n }\n}\n\nfunction sample(palette: SemanticPalette, pairing: Pairing): ContrastSample {\n const foreground = palette[pairing.foreground];\n const background = palette[pairing.background];\n const ratio = contrastRatio(foreground, background);\n return { ratio, level: rateContrast(ratio).level, foreground, background };\n}\n\n/**\n * Measures every text-carrying pairing the palette derives for these\n * colours, in light and dark. Advice, not enforcement: nothing here refuses\n * a theme on its ratios. The checks are data; BIS-59's `ContrastStrip` draws\n * them.\n *\n * Throws, naming the field, when a brand colour is not `#rrggbb`, the same\n * contract as `buildThemeCss`. An admin field validates its own value\n * before calling this, so a half-typed hex never reaches it.\n */\nexport function auditTheme(config: ContrastThemeInput, options: AuditThemeOptions = {}): ContrastCheck[] {\n const target = options.target ?? 4.5;\n const brand = brandColorsFromConfig(config);\n const light = deriveLightPalette(brand);\n const dark = deriveDarkPalette(brand);\n\n return PAIRINGS.map((pairing) => {\n const lightSample = sample(light, pairing);\n const darkSample = sample(dark, pairing);\n const threshold = roleTarget(pairing.role, target);\n return {\n id: `${pairing.foreground}-on-${pairing.background}`,\n label: pairing.label,\n role: pairing.role,\n light: lightSample,\n dark: darkSample,\n target: threshold,\n meetsTarget: lightSample.ratio >= threshold && darkSample.ratio >= threshold,\n };\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/oklch.ts","../src/colors.ts","../src/radius.ts","../src/shadows.ts","../src/motion.ts","../src/density.ts","../src/typography.ts","../src/spacing.ts","../src/z-index.ts","../src/animation-presets.ts","../src/theme.ts","../src/contrast.ts","../src/preset-hints.ts"],"sourcesContent":["/**\n * OKLCH color space math — zero dependencies.\n * hex → sRGB → linear sRGB → OKLab (matrix) → OKLCH (polar)\n * Reverse: OKLCH → OKLab → linear sRGB → sRGB → HSL string\n * Gamut clamping via binary search on chroma (12 iterations).\n */\n\nexport interface OKLCH {\n L: number; // lightness 0–1\n C: number; // chroma ≥ 0\n H: number; // hue 0–360\n}\n\n// --- sRGB ↔ linear sRGB ---\n\nfunction srgbToLinear(c: number): number {\n return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n}\n\nfunction linearToSrgb(c: number): number {\n return c <= 0.0031308 ? c * 12.92 : 1.055 * Math.pow(c, 1 / 2.4) - 0.055;\n}\n\n// --- Hex → sRGB ---\n\nfunction hexToSrgb(hex: string): [number, number, number] {\n hex = hex.replace(\"#\", \"\");\n return [\n parseInt(hex.substring(0, 2), 16) / 255,\n parseInt(hex.substring(2, 4), 16) / 255,\n parseInt(hex.substring(4, 6), 16) / 255,\n ];\n}\n\n// --- linear sRGB ↔ OKLab ---\n\nfunction linearSrgbToOklab(r: number, g: number, b: number): [number, number, number] {\n const l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;\n const m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;\n const s = 0.0883024619 * r + 0.2024326059 * g + 0.6892649272 * b;\n\n const lc = Math.cbrt(l);\n const mc = Math.cbrt(m);\n const sc = Math.cbrt(s);\n\n return [\n 0.2104542553 * lc + 0.7936177850 * mc - 0.0040720468 * sc,\n 1.9779984951 * lc - 2.4285922050 * mc + 0.4505937099 * sc,\n 0.0259040371 * lc + 0.7827717662 * mc - 0.8086757660 * sc,\n ];\n}\n\nfunction oklabToLinearSrgb(L: number, a: number, b: number): [number, number, number] {\n const lc = L + 0.3963377774 * a + 0.2158037573 * b;\n const mc = L - 0.1055613458 * a - 0.0638541728 * b;\n const sc = L - 0.0894841775 * a - 1.2914855480 * b;\n\n return [\n 4.0767416621 * lc * lc * lc - 3.3077115913 * mc * mc * mc + 0.2309699292 * sc * sc * sc,\n -1.2684380046 * lc * lc * lc + 2.6097574011 * mc * mc * mc - 0.3413193965 * sc * sc * sc,\n -0.0041960863 * lc * lc * lc - 0.7034186147 * mc * mc * mc + 1.7076147010 * sc * sc * sc,\n ];\n}\n\n// --- OKLab ↔ OKLCH ---\n\nfunction oklabToOklch(L: number, a: number, b: number): OKLCH {\n const C = Math.sqrt(a * a + b * b);\n let H = (Math.atan2(b, a) * 180) / Math.PI;\n if (H < 0) H += 360;\n return { L, C, H };\n}\n\nfunction oklchToOklab(L: number, C: number, H: number): [number, number, number] {\n const hRad = (H * Math.PI) / 180;\n return [L, C * Math.cos(hRad), C * Math.sin(hRad)];\n}\n\n// --- Gamut clamping ---\n\nfunction isInGamut(r: number, g: number, b: number): boolean {\n const eps = 1e-4;\n return r >= -eps && r <= 1 + eps && g >= -eps && g <= 1 + eps && b >= -eps && b <= 1 + eps;\n}\n\nfunction gamutClampChroma(L: number, C: number, H: number): number {\n if (C <= 0) return 0;\n\n const [, a, b] = oklchToOklab(L, C, H);\n const [r, g, bl] = oklabToLinearSrgb(L, a, b);\n\n if (isInGamut(r, g, bl)) return C;\n\n let lo = 0;\n let hi = C;\n\n for (let i = 0; i < 12; i++) {\n const mid = (lo + hi) / 2;\n const [, am, bm] = oklchToOklab(L, mid, H);\n const [rm, gm, bm2] = oklabToLinearSrgb(L, am, bm);\n\n if (isInGamut(rm, gm, bm2)) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n\n return lo;\n}\n\n// --- sRGB → HSL ---\n\nfunction srgbToHsl(r: number, g: number, b: number): [number, number, number] {\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n let h = 0;\n let s = 0;\n\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n break;\n case g:\n h = ((b - r) / d + 2) / 6;\n break;\n case b:\n h = ((r - g) / d + 4) / 6;\n break;\n }\n }\n\n return [Math.round(h * 360), Math.round(s * 100), Math.round(l * 100)];\n}\n\n// --- Public API ---\n\nexport function hexToOklch(hex: string): OKLCH {\n const [r, g, b] = hexToSrgb(hex);\n const [lr, lg, lb] = [srgbToLinear(r), srgbToLinear(g), srgbToLinear(b)];\n const [L, a, ob] = linearSrgbToOklab(lr, lg, lb);\n return oklabToOklch(L, a, ob);\n}\n\nexport function oklchToHslString(L: number, C: number, H: number): string {\n const clampedC = gamutClampChroma(L, C, H);\n const [, a, b] = oklchToOklab(L, clampedC, H);\n const [lr, lg, lb] = oklabToLinearSrgb(L, a, b);\n\n const r = Math.min(1, Math.max(0, linearToSrgb(lr)));\n const g = Math.min(1, Math.max(0, linearToSrgb(lg)));\n const bl = Math.min(1, Math.max(0, linearToSrgb(lb)));\n\n const [h, s, l] = srgbToHsl(r, g, bl);\n return `${h} ${s}% ${l}%`;\n}\n","/**\n * Color derivation engine.\n * Takes brand colors (hex) + a grey scale selection and derives\n * a full semantic palette for both light and dark modes,\n * plus 50–950 shade scales via OKLCH color space.\n */\n\nimport { hexToOklch, oklchToHslString } from \"./oklch\";\n\nexport interface HSL {\n h: number;\n s: number;\n l: number;\n}\n\nexport function hexToHSL(hex: string): HSL {\n hex = hex.replace(\"#\", \"\");\n const r = parseInt(hex.substring(0, 2), 16) / 255;\n const g = parseInt(hex.substring(2, 4), 16) / 255;\n const b = parseInt(hex.substring(4, 6), 16) / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n let h = 0;\n let s = 0;\n\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n break;\n case g:\n h = ((b - r) / d + 2) / 6;\n break;\n case b:\n h = ((r - g) / d + 4) / 6;\n break;\n }\n }\n\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n };\n}\n\nexport function hslToString(hsl: HSL): string {\n return `${hsl.h} ${hsl.s}% ${hsl.l}%`;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n// --- Grey scale palettes (Tailwind v4 values as HSL strings) ---\n\nexport type GreyScale = \"slate\" | \"gray\" | \"zinc\" | \"neutral\" | \"stone\";\n\ntype GreyShade = \"50\" | \"100\" | \"200\" | \"300\" | \"400\" | \"500\" | \"600\" | \"700\" | \"800\" | \"900\" | \"950\";\n\ntype GreyPalette = Record<GreyShade, string>;\n\nexport const GREY_SCALES: Record<GreyScale, GreyPalette> = {\n slate: {\n \"50\": \"210 40% 98%\",\n \"100\": \"210 40% 96%\",\n \"200\": \"214 32% 91%\",\n \"300\": \"213 27% 84%\",\n \"400\": \"215 20% 65%\",\n \"500\": \"215 16% 47%\",\n \"600\": \"215 19% 35%\",\n \"700\": \"215 25% 27%\",\n \"800\": \"217 33% 17%\",\n \"900\": \"222 47% 11%\",\n \"950\": \"229 84% 5%\",\n },\n gray: {\n \"50\": \"210 20% 98%\",\n \"100\": \"220 14% 96%\",\n \"200\": \"220 13% 91%\",\n \"300\": \"216 12% 84%\",\n \"400\": \"218 11% 65%\",\n \"500\": \"220 9% 46%\",\n \"600\": \"215 14% 34%\",\n \"700\": \"217 19% 27%\",\n \"800\": \"215 28% 17%\",\n \"900\": \"221 39% 11%\",\n \"950\": \"224 71% 4%\",\n },\n zinc: {\n \"50\": \"0 0% 98%\",\n \"100\": \"240 5% 96%\",\n \"200\": \"240 6% 90%\",\n \"300\": \"240 5% 84%\",\n \"400\": \"240 5% 65%\",\n \"500\": \"240 4% 46%\",\n \"600\": \"240 5% 34%\",\n \"700\": \"240 5% 26%\",\n \"800\": \"240 4% 16%\",\n \"900\": \"240 6% 10%\",\n \"950\": \"240 10% 4%\",\n },\n neutral: {\n \"50\": \"0 0% 98%\",\n \"100\": \"0 0% 96%\",\n \"200\": \"0 0% 90%\",\n \"300\": \"0 0% 83%\",\n \"400\": \"0 0% 64%\",\n \"500\": \"0 0% 45%\",\n \"600\": \"0 0% 32%\",\n \"700\": \"0 0% 25%\",\n \"800\": \"0 0% 15%\",\n \"900\": \"0 0% 9%\",\n \"950\": \"0 0% 4%\",\n },\n stone: {\n \"50\": \"60 9% 98%\",\n \"100\": \"60 5% 96%\",\n \"200\": \"20 6% 90%\",\n \"300\": \"24 6% 83%\",\n \"400\": \"24 5% 64%\",\n \"500\": \"25 5% 45%\",\n \"600\": \"33 5% 32%\",\n \"700\": \"30 6% 25%\",\n \"800\": \"12 6% 15%\",\n \"900\": \"24 10% 10%\",\n \"950\": \"20 14% 4%\",\n },\n};\n\n// --- Brand color types ---\n\nexport interface BrandColors {\n primary: string; // hex\n secondary: string; // hex\n accent?: string; // hex\n highlight?: string; // hex\n success: string; // hex\n grey?: GreyScale; // defaults to \"slate\"\n}\n\n// --- Shade scale types ---\n\nexport const SHADE_STEPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] as const;\nexport type ShadeStep = (typeof SHADE_STEPS)[number];\nexport type ColorScale = Record<ShadeStep, string>;\n\nexport interface BrandScales {\n primary: ColorScale;\n secondary: ColorScale;\n \"brand-accent\": ColorScale;\n highlight: ColorScale;\n success: ColorScale;\n}\n\n// --- Target OKLCH lightness per step ---\n\nconst TARGET_LIGHTNESS: Record<ShadeStep, number> = {\n 50: 0.97,\n 100: 0.93,\n 200: 0.87,\n 300: 0.79,\n 400: 0.70,\n 500: 0.59,\n 600: 0.49,\n 700: 0.39,\n 800: 0.30,\n 900: 0.21,\n 950: 0.14,\n};\n\n// --- Scale generation ---\n\n/**\n * Generate a full 50–950 color scale from a single hex value.\n * Uses OKLCH for perceptual uniformity. The input color is auto-anchored\n * to its closest shade step and reproduced pixel-perfect at that step.\n */\nexport function generateColorScale(hex: string): ColorScale {\n const { L: inputL, C: inputC, H } = hexToOklch(hex);\n\n // Sine-based chroma curve: peaks at mid-lightness, falls toward extremes\n const chromaCurve = (L: number): number => Math.sin(Math.PI * L);\n const inputCurveValue = chromaCurve(inputL);\n\n // Anchor ratio so that input chroma is preserved at input lightness\n const chromaRatio = inputCurveValue > 0.01 ? inputC / inputCurveValue : inputC;\n\n const scale = {} as ColorScale;\n\n for (const step of SHADE_STEPS) {\n const targetL = TARGET_LIGHTNESS[step];\n const targetC = inputCurveValue > 0.01\n ? chromaRatio * chromaCurve(targetL)\n : inputC * chromaCurve(targetL);\n\n scale[step] = oklchToHslString(targetL, targetC, H);\n }\n\n return scale;\n}\n\n/**\n * Generate shade scales for all brand colors.\n */\nexport function generateBrandScales(brand: BrandColors): BrandScales {\n const accentHex = brand.accent ?? brand.primary;\n const highlightHex = brand.highlight ?? brand.secondary;\n\n return {\n primary: generateColorScale(brand.primary),\n secondary: generateColorScale(brand.secondary),\n \"brand-accent\": generateColorScale(accentHex),\n highlight: generateColorScale(highlightHex),\n success: generateColorScale(brand.success),\n };\n}\n\n/**\n * Generate CSS custom property declarations for all brand scales.\n * Output is indented with 2 spaces, suitable for injection into :root {}.\n */\nexport function generateScaleCSS(scales: BrandScales): string {\n const lines: string[] = [];\n\n for (const [colorName, scale] of Object.entries(scales)) {\n for (const step of SHADE_STEPS) {\n lines.push(` --${colorName}-${step}: ${(scale as ColorScale)[step]};`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Canonical red for destructive UI (matches common “danger” hue). Used for the\n * destructive 50–950 scale so tinted surfaces (e.g. soft delete buttons) work\n * like success scales, independent of brand colors.\n */\nexport const DESTRUCTIVE_SCALE_HEX = \"#ef4444\";\n\nlet destructiveColorScaleCache: ColorScale | null = null;\n\nexport function getDestructiveColorScale(): ColorScale {\n if (!destructiveColorScaleCache) {\n destructiveColorScaleCache = generateColorScale(DESTRUCTIVE_SCALE_HEX);\n }\n return destructiveColorScaleCache;\n}\n\n/** CSS custom properties `--destructive-50` … `--destructive-950` for :root injection. */\nexport function generateDestructiveScaleCSS(): string {\n const scale = getDestructiveColorScale();\n return SHADE_STEPS.map((step) => ` --destructive-${step}: ${scale[step]};`).join(\"\\n\");\n}\n\n// --- Semantic palette ---\n\nexport interface SemanticPalette {\n background: string;\n foreground: string;\n card: string;\n \"card-foreground\": string;\n \"surface-tertiary\": string;\n popover: string;\n \"popover-foreground\": string;\n primary: string;\n \"primary-foreground\": string;\n secondary: string;\n \"secondary-foreground\": string;\n accent: string;\n \"accent-foreground\": string;\n \"brand-accent\": string;\n \"brand-accent-foreground\": string;\n highlight: string;\n \"highlight-foreground\": string;\n success: string;\n \"success-foreground\": string;\n muted: string;\n \"muted-foreground\": string;\n \"content-secondary\": string;\n destructive: string;\n \"destructive-foreground\": string;\n border: string;\n \"border-strong\": string;\n \"border-subtle\": string;\n input: string;\n ring: string;\n}\n\n// --- Foreground contrast ---\n\n/**\n * Near-white ink on a dark fill, near-black on a light one. A lightness\n * heuristic, not a measurement: `auditTheme` in `./contrast` is what says\n * whether the pairing actually reads.\n */\nfunction contrastForeground(color: HSL): string {\n return color.l > 55\n ? hslToString({ h: color.h, s: clamp(color.s - 20, 0, 100), l: 10 })\n : hslToString({ h: color.h, s: clamp(color.s - 25, 0, 100), l: 98 });\n}\n\n/**\n * A brand fill lightens in dark mode only below this lightness. The CLI\n * shipped 40 and this module shipped 50 until BIS-57; 40 is the value every\n * generated `bison-theme.css` in the field was built with, and Spinal\n * Simplicity's `globals.css` records why a fill at 43 must not lighten: its\n * derived ink flips to near-black, and the button's fixed `hover:bg-primary-700`\n * then reads at 1.74:1.\n */\nconst DARK_FILL_LIGHTEN_BELOW = 40;\n\n/**\n * The focus ring lightens below this lightness. A ring is a thin outline on\n * the page background and carries no ink, so it is free to lighten where a\n * fill is not: `#DB0082` at 43% is 4.1:1 on zinc-950, at 68% it is 7.1:1.\n */\nconst DARK_RING_LIGHTEN_BELOW = 50;\n\nfunction lightenForDark(color: HSL, below: number): HSL {\n if (color.l < below) {\n return { ...color, l: clamp(color.l + 25, 0, 100) };\n }\n return color;\n}\n\n// --- Palette derivation ---\n\n/**\n * The light semantic palette for a brand. This is the one derivation the\n * CLI (`bison-theme.css`), `BisonProvider` and a CMS theme all share.\n *\n * Decided in BIS-57, where the CLI and this module had drifted:\n * - `muted-foreground` is grey-600, not grey-500. grey-500 is 4.6:1 on the\n * page background, and the token carries card descriptions, hints, table\n * labels and footer lines; grey-600 is 7.4:1. Spinal Simplicity overrode\n * it by hand for its patient audience.\n * - `content-secondary` is grey-500, not grey-400. It is text: the\n * progress bar's percentage label and every chart axis tick use it, and\n * grey-400 is about 2.5:1 on the page background on every scale. grey-500\n * is 4.5:1 or better on both the page background and a card.\n */\nexport function deriveLightPalette(brand: BrandColors): SemanticPalette {\n const grey = GREY_SCALES[brand.grey ?? \"slate\"];\n const primary = hexToHSL(brand.primary);\n const secondary = hexToHSL(brand.secondary);\n const accent = brand.accent ? hexToHSL(brand.accent) : primary;\n const highlight = brand.highlight ? hexToHSL(brand.highlight) : secondary;\n const success = hexToHSL(brand.success);\n\n return {\n background: grey[\"50\"],\n foreground: grey[\"950\"],\n card: \"0 0% 100%\",\n \"card-foreground\": grey[\"950\"],\n \"surface-tertiary\": grey[\"100\"],\n popover: \"0 0% 100%\",\n \"popover-foreground\": grey[\"950\"],\n primary: hslToString(primary),\n \"primary-foreground\": contrastForeground(primary),\n secondary: hslToString(secondary),\n \"secondary-foreground\": contrastForeground(secondary),\n accent: grey[\"100\"],\n \"accent-foreground\": grey[\"950\"],\n \"brand-accent\": hslToString(accent),\n \"brand-accent-foreground\": contrastForeground(accent),\n highlight: hslToString(highlight),\n \"highlight-foreground\": contrastForeground(highlight),\n success: hslToString(success),\n \"success-foreground\": contrastForeground(success),\n muted: grey[\"100\"],\n \"muted-foreground\": grey[\"600\"],\n \"content-secondary\": grey[\"500\"],\n destructive: \"0 84% 60%\",\n \"destructive-foreground\": \"0 0% 98%\",\n border: grey[\"200\"],\n \"border-strong\": grey[\"300\"],\n \"border-subtle\": grey[\"100\"],\n input: grey[\"200\"],\n ring: hslToString(primary),\n };\n}\n\n/**\n * The dark semantic palette for a brand, derived from the same inputs as\n * the light one: no manual dark palette.\n *\n * Decided in BIS-57, where the CLI and this module had drifted:\n * - Brand fills lighten only below lightness 40 (`DARK_FILL_LIGHTEN_BELOW`);\n * the ring lightens below 50 (`DARK_RING_LIGHTEN_BELOW`). See both.\n * - `muted-foreground` is grey-300, not grey-400. grey-400 is 6.9:1 on\n * `card`, where most supporting copy sits; grey-300 clears 7:1 on both\n * surfaces.\n * - `content-secondary` is grey-400, not grey-500. grey-500 on `card` is\n * about 3.7:1, under AA; grey-400 is about 7:1.\n * - `destructive` is `0 62% 30%`, not `0 84% 65%`. `destructive-foreground`\n * (`0 0% 98%`) is 9.8:1 on the former and 3.2:1 on the latter, which\n * fails AA for the button label.\n */\nexport function deriveDarkPalette(brand: BrandColors): SemanticPalette {\n const grey = GREY_SCALES[brand.grey ?? \"slate\"];\n const primaryHsl = hexToHSL(brand.primary);\n const primary = lightenForDark(primaryHsl, DARK_FILL_LIGHTEN_BELOW);\n const secondary = lightenForDark(hexToHSL(brand.secondary), DARK_FILL_LIGHTEN_BELOW);\n const accent = lightenForDark(brand.accent ? hexToHSL(brand.accent) : primaryHsl, DARK_FILL_LIGHTEN_BELOW);\n const highlight = lightenForDark(\n brand.highlight ? hexToHSL(brand.highlight) : hexToHSL(brand.secondary),\n DARK_FILL_LIGHTEN_BELOW,\n );\n const success = lightenForDark(hexToHSL(brand.success), DARK_FILL_LIGHTEN_BELOW);\n const ring = lightenForDark(primaryHsl, DARK_RING_LIGHTEN_BELOW);\n\n return {\n background: grey[\"950\"],\n foreground: grey[\"50\"],\n card: grey[\"900\"],\n \"card-foreground\": grey[\"50\"],\n \"surface-tertiary\": grey[\"800\"],\n popover: grey[\"900\"],\n \"popover-foreground\": grey[\"50\"],\n primary: hslToString(primary),\n \"primary-foreground\": contrastForeground(primary),\n secondary: hslToString(secondary),\n \"secondary-foreground\": contrastForeground(secondary),\n accent: grey[\"800\"],\n \"accent-foreground\": grey[\"50\"],\n \"brand-accent\": hslToString(accent),\n \"brand-accent-foreground\": contrastForeground(accent),\n highlight: hslToString(highlight),\n \"highlight-foreground\": contrastForeground(highlight),\n success: hslToString(success),\n \"success-foreground\": contrastForeground(success),\n muted: grey[\"800\"],\n \"muted-foreground\": grey[\"300\"],\n \"content-secondary\": grey[\"400\"],\n destructive: \"0 62% 30%\",\n \"destructive-foreground\": \"0 0% 98%\",\n border: grey[\"800\"],\n \"border-strong\": grey[\"700\"],\n \"border-subtle\": grey[\"900\"],\n input: grey[\"800\"],\n ring: hslToString(ring),\n };\n}\n\nexport function generatePaletteCSS(brand: BrandColors, attribute: \"class\" | \"data-theme\" = \"class\"): string {\n const light = deriveLightPalette(brand);\n const dark = deriveDarkPalette(brand);\n const scales = generateBrandScales(brand);\n\n const toVars = (palette: SemanticPalette, indent: string) =>\n Object.entries(palette)\n .map(([key, value]) => `${indent}--${key}: ${value};`)\n .join(\"\\n\");\n\n const darkSelector = attribute === \"class\" ? \".dark\" : '[data-theme=\"dark\"]';\n\n return `:root {\\n${toVars(light, \" \")}\\n\\n${generateScaleCSS(scales)}\\n\\n${generateDestructiveScaleCSS()}\\n}\\n\\n${darkSelector} {\\n${toVars(dark, \" \")}\\n}\\n`;\n}\n","export const radiusPresets = {\n sharp: {\n \"--radius\": \"0rem\",\n \"--radius-sm\": \"0rem\",\n \"--radius-md\": \"0rem\",\n \"--radius-lg\": \"0rem\",\n \"--radius-xl\": \"0rem\",\n \"--radius-full\": \"0rem\",\n },\n subtle: {\n \"--radius\": \"0.375rem\",\n \"--radius-sm\": \"0.375rem\",\n \"--radius-md\": \"0.375rem\",\n \"--radius-lg\": \"0.5rem\",\n \"--radius-xl\": \"0.75rem\",\n \"--radius-full\": \"9999px\",\n },\n rounded: {\n \"--radius\": \"0.5rem\",\n \"--radius-sm\": \"0.5rem\",\n \"--radius-md\": \"0.5rem\",\n \"--radius-lg\": \"0.75rem\",\n \"--radius-xl\": \"1rem\",\n \"--radius-full\": \"9999px\",\n },\n pill: {\n \"--radius\": \"0.75rem\",\n \"--radius-sm\": \"0.75rem\",\n \"--radius-md\": \"0.75rem\",\n \"--radius-lg\": \"1rem\",\n \"--radius-xl\": \"1.5rem\",\n \"--radius-full\": \"9999px\",\n },\n} as const;\n\nexport type RadiusPreset = keyof typeof radiusPresets;\n","export const shadowPresets = {\n flat: {\n \"--shadow-sm\": \"none\",\n \"--shadow\": \"none\",\n \"--shadow-md\": \"none\",\n \"--shadow-lg\": \"none\",\n \"--shadow-xl\": \"none\",\n },\n subtle: {\n \"--shadow-sm\": \"0 1px 2px 0 rgb(0 0 0 / 0.03)\",\n \"--shadow\": \"0 1px 3px 0 rgb(0 0 0 / 0.05), 0 1px 2px -1px rgb(0 0 0 / 0.05)\",\n \"--shadow-md\": \"0 4px 6px -1px rgb(0 0 0 / 0.05), 0 2px 4px -2px rgb(0 0 0 / 0.05)\",\n \"--shadow-lg\": \"0 10px 15px -3px rgb(0 0 0 / 0.05), 0 4px 6px -4px rgb(0 0 0 / 0.05)\",\n \"--shadow-xl\": \"0 20px 25px -5px rgb(0 0 0 / 0.05), 0 8px 10px -6px rgb(0 0 0 / 0.05)\",\n },\n elevated: {\n \"--shadow-sm\": \"0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.1)\",\n \"--shadow\": \"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)\",\n \"--shadow-md\": \"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)\",\n \"--shadow-lg\": \"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)\",\n \"--shadow-xl\": \"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)\",\n },\n} as const;\n\nexport type ShadowPreset = keyof typeof shadowPresets;\n","export const motionPresets = {\n snappy: {\n \"--duration-fast\": \"100ms\",\n \"--duration-normal\": \"150ms\",\n \"--duration-slow\": \"250ms\",\n \"--ease-default\": \"cubic-bezier(0.22, 1, 0.36, 1)\",\n \"--ease-in\": \"cubic-bezier(0.55, 0, 1, 0.45)\",\n \"--ease-out\": \"cubic-bezier(0, 0.55, 0.45, 1)\",\n \"--ease-in-out\": \"cubic-bezier(0.65, 0, 0.35, 1)\",\n },\n smooth: {\n \"--duration-fast\": \"150ms\",\n \"--duration-normal\": \"200ms\",\n \"--duration-slow\": \"350ms\",\n \"--ease-default\": \"cubic-bezier(0.25, 0.1, 0.25, 1)\",\n \"--ease-in\": \"cubic-bezier(0.42, 0, 1, 1)\",\n \"--ease-out\": \"cubic-bezier(0, 0, 0.58, 1)\",\n \"--ease-in-out\": \"cubic-bezier(0.42, 0, 0.58, 1)\",\n },\n minimal: {\n \"--duration-fast\": \"75ms\",\n \"--duration-normal\": \"100ms\",\n \"--duration-slow\": \"200ms\",\n \"--ease-default\": \"linear\",\n \"--ease-in\": \"linear\",\n \"--ease-out\": \"linear\",\n \"--ease-in-out\": \"linear\",\n },\n} as const;\n\nexport type MotionPreset = keyof typeof motionPresets;\n","export const densityPresets = {\n compact: {\n \"--density-padding-xs\": \"0.125rem\",\n \"--density-padding-sm\": \"0.25rem\",\n \"--density-padding-md\": \"0.375rem\",\n \"--density-padding-lg\": \"0.5rem\",\n \"--density-padding-xl\": \"0.75rem\",\n \"--density-gap-sm\": \"0.25rem\",\n \"--density-gap-md\": \"0.5rem\",\n \"--density-gap-lg\": \"0.75rem\",\n \"--density-height-sm\": \"1.75rem\",\n \"--density-height-md\": \"2rem\",\n \"--density-height-lg\": \"2.5rem\",\n },\n default: {\n \"--density-padding-xs\": \"0.25rem\",\n \"--density-padding-sm\": \"0.5rem\",\n \"--density-padding-md\": \"0.75rem\",\n \"--density-padding-lg\": \"1rem\",\n \"--density-padding-xl\": \"1.5rem\",\n \"--density-gap-sm\": \"0.5rem\",\n \"--density-gap-md\": \"0.75rem\",\n \"--density-gap-lg\": \"1rem\",\n \"--density-height-sm\": \"2rem\",\n \"--density-height-md\": \"2.5rem\",\n \"--density-height-lg\": \"3rem\",\n },\n spacious: {\n \"--density-padding-xs\": \"0.5rem\",\n \"--density-padding-sm\": \"0.75rem\",\n \"--density-padding-md\": \"1rem\",\n \"--density-padding-lg\": \"1.5rem\",\n \"--density-padding-xl\": \"2rem\",\n \"--density-gap-sm\": \"0.75rem\",\n \"--density-gap-md\": \"1rem\",\n \"--density-gap-lg\": \"1.5rem\",\n \"--density-height-sm\": \"2.5rem\",\n \"--density-height-md\": \"3rem\",\n \"--density-height-lg\": \"3.5rem\",\n },\n} as const;\n\nexport type DensityPreset = keyof typeof densityPresets;\n","/** Locked type scale — consumers cannot override sizes, only font-family and weights. */\nexport const typeScale = {\n \"text-xs\": { fontSize: \"0.75rem\", lineHeight: \"1rem\" },\n \"text-sm\": { fontSize: \"0.875rem\", lineHeight: \"1.25rem\" },\n \"text-base\": { fontSize: \"1rem\", lineHeight: \"1.5rem\" },\n \"text-lg\": { fontSize: \"1.125rem\", lineHeight: \"1.75rem\" },\n \"text-xl\": { fontSize: \"1.25rem\", lineHeight: \"1.75rem\" },\n \"text-2xl\": { fontSize: \"1.5rem\", lineHeight: \"2rem\" },\n \"text-3xl\": { fontSize: \"1.875rem\", lineHeight: \"2.25rem\" },\n \"text-4xl\": { fontSize: \"2.25rem\", lineHeight: \"2.5rem\" },\n\n // Fluid headings using clamp()\n \"heading-sm\": {\n fontSize: \"clamp(1.125rem, 1rem + 0.5vw, 1.25rem)\",\n lineHeight: \"1.4\",\n letterSpacing: \"-0.01em\",\n },\n \"heading-md\": {\n fontSize: \"clamp(1.25rem, 1rem + 1vw, 1.875rem)\",\n lineHeight: \"1.3\",\n letterSpacing: \"-0.015em\",\n },\n \"heading-lg\": {\n fontSize: \"clamp(1.5rem, 1rem + 2vw, 2.25rem)\",\n lineHeight: \"1.2\",\n letterSpacing: \"-0.02em\",\n },\n \"heading-xl\": {\n fontSize: \"clamp(1.875rem, 1rem + 3vw, 3rem)\",\n lineHeight: \"1.1\",\n letterSpacing: \"-0.025em\",\n },\n \"heading-2xl\": {\n fontSize: \"clamp(2.25rem, 1rem + 4vw, 3.75rem)\",\n lineHeight: \"1.1\",\n letterSpacing: \"-0.03em\",\n },\n} as const;\n\nexport interface FontWeightMap {\n normal: number;\n medium: number;\n semibold: number;\n bold: number;\n extrabold?: number;\n}\n\nexport const defaultFontWeights: FontWeightMap = {\n normal: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n extrabold: 800,\n};\n","/** Locked spacing scale — 4px (0.25rem) base grid. Not consumer-overridable. */\nexport const spacingScale = {\n \"0\": \"0\",\n \"0.5\": \"0.125rem\",\n \"1\": \"0.25rem\",\n \"1.5\": \"0.375rem\",\n \"2\": \"0.5rem\",\n \"2.5\": \"0.625rem\",\n \"3\": \"0.75rem\",\n \"3.5\": \"0.875rem\",\n \"4\": \"1rem\",\n \"5\": \"1.25rem\",\n \"6\": \"1.5rem\",\n \"7\": \"1.75rem\",\n \"8\": \"2rem\",\n \"9\": \"2.25rem\",\n \"10\": \"2.5rem\",\n \"11\": \"2.75rem\",\n \"12\": \"3rem\",\n \"14\": \"3.5rem\",\n \"16\": \"4rem\",\n \"20\": \"5rem\",\n \"24\": \"6rem\",\n \"28\": \"7rem\",\n \"32\": \"8rem\",\n \"36\": \"9rem\",\n \"40\": \"10rem\",\n \"44\": \"11rem\",\n \"48\": \"12rem\",\n \"52\": \"13rem\",\n \"56\": \"14rem\",\n \"60\": \"15rem\",\n \"64\": \"16rem\",\n \"72\": \"18rem\",\n \"80\": \"20rem\",\n \"96\": \"24rem\",\n} as const;\n","/** Z-index tokens — overridable by consumers via CSS custom properties. */\nexport const zIndexTokens = {\n \"--z-dropdown\": \"50\",\n \"--z-sticky\": \"100\",\n \"--z-fixed\": \"200\",\n \"--z-modal-backdrop\": \"300\",\n \"--z-modal\": \"400\",\n \"--z-popover\": \"500\",\n \"--z-tooltip\": \"600\",\n \"--z-toast\": \"700\",\n} as const;\n\nexport type ZIndexToken = keyof typeof zIndexTokens;\n","/**\n * Framer Motion animation presets.\n *\n * Each preset is a Framer Motion `Variants` object with `hidden` and `visible`\n * states, plus optional `exit`. Durations and easings are resolved per motion\n * preset (snappy / smooth / minimal) at call time via `getAnimationPresets()`.\n */\n\nimport { motionPresets, type MotionPreset } from \"./motion\";\n\n// ---------------------------------------------------------------------------\n// Duration / easing helpers\n// ---------------------------------------------------------------------------\n\nfunction parseDuration(ms: string): number {\n return parseInt(ms, 10) / 1000;\n}\n\nfunction parseEasing(raw: string): number[] | string {\n if (raw === \"linear\") return \"linear\" as string;\n const match = raw.match(\n /cubic-bezier\\(\\s*([\\d.]+)\\s*,\\s*([\\d.-]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.-]+)\\s*\\)/\n );\n if (!match) return [0.25, 0.1, 0.25, 1];\n return [Number(match[1]), Number(match[2]), Number(match[3]), Number(match[4])];\n}\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface MotionVariant {\n hidden: Record<string, unknown>;\n visible: Record<string, unknown>;\n exit?: Record<string, unknown>;\n}\n\nexport interface StaggerContainerVariant {\n hidden: Record<string, unknown>;\n visible: Record<string, unknown>;\n}\n\nexport interface AnimationPresets {\n fadeIn: MotionVariant;\n fadeUp: MotionVariant;\n fadeDown: MotionVariant;\n scaleIn: MotionVariant;\n slideInLeft: MotionVariant;\n slideInRight: MotionVariant;\n cardLift: MotionVariant;\n staggerContainer: StaggerContainerVariant;\n staggerItem: MotionVariant;\n pageTransition: MotionVariant;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Returns Framer Motion variant presets tuned to the given motion preset.\n *\n * @example\n * ```tsx\n * import { getAnimationPresets } from \"@bison-lab/tokens\";\n * import { motion } from \"framer-motion\";\n *\n * const presets = getAnimationPresets(\"smooth\");\n *\n * <motion.div variants={presets.fadeUp} initial=\"hidden\" animate=\"visible\">\n * Hello\n * </motion.div>\n * ```\n */\nexport function getAnimationPresets(preset: MotionPreset = \"smooth\"): AnimationPresets {\n const tokens = motionPresets[preset];\n const normal = parseDuration(tokens[\"--duration-normal\"]);\n const slow = parseDuration(tokens[\"--duration-slow\"]);\n const ease = parseEasing(tokens[\"--ease-out\"]);\n\n const transition = { duration: normal, ease };\n const slowTransition = { duration: slow, ease };\n\n return {\n fadeIn: {\n hidden: { opacity: 0 },\n visible: { opacity: 1, transition },\n },\n\n fadeUp: {\n hidden: { opacity: 0, y: 10 },\n visible: { opacity: 1, y: 0, transition },\n },\n\n fadeDown: {\n hidden: { opacity: 0, y: -10 },\n visible: { opacity: 1, y: 0, transition },\n },\n\n scaleIn: {\n hidden: { opacity: 0, scale: 0.97 },\n visible: { opacity: 1, scale: 1, transition },\n },\n\n slideInLeft: {\n hidden: { opacity: 0, x: -16 },\n visible: { opacity: 1, x: 0, transition },\n },\n\n slideInRight: {\n hidden: { opacity: 0, x: 16 },\n visible: { opacity: 1, x: 0, transition },\n },\n\n cardLift: {\n hidden: { opacity: 0, y: 6, scale: 0.99 },\n visible: {\n opacity: 1,\n y: 0,\n scale: 1,\n transition: slowTransition,\n },\n exit: { opacity: 0, y: 4, scale: 0.99, transition },\n },\n\n staggerContainer: {\n hidden: {},\n visible: {\n transition: {\n staggerChildren: 0.07,\n delayChildren: 0.1,\n },\n },\n },\n\n staggerItem: {\n hidden: { opacity: 0, y: 8 },\n visible: { opacity: 1, y: 0, transition },\n },\n\n pageTransition: {\n hidden: { opacity: 0, y: 8 },\n visible: { opacity: 1, y: 0, transition: slowTransition },\n exit: { opacity: 0, y: -6, transition },\n },\n };\n}\n","/**\n * The theme a site configures, and the stylesheet built from it.\n *\n * `ThemeConfig` is the `bison.config.json` shape `@bison-lab/create-theme`\n * writes. `buildThemeCss` turns one into the complete theme stylesheet: the\n * CLI writes it to `bison-theme.css`, and a CMS theme (BIS-60) renders it at\n * request time from the same function, so the two can never disagree.\n */\n\nimport {\n deriveLightPalette,\n deriveDarkPalette,\n generateBrandScales,\n generateScaleCSS,\n generateDestructiveScaleCSS,\n type BrandColors,\n type GreyScale,\n type SemanticPalette,\n} from \"./colors\";\nimport { radiusPresets, type RadiusPreset } from \"./radius\";\nimport { shadowPresets, type ShadowPreset } from \"./shadows\";\nimport { motionPresets, type MotionPreset } from \"./motion\";\nimport { densityPresets, type DensityPreset } from \"./density\";\nimport { fontFaceCss, fontStack, isFontId, type FontId } from \"@bison-lab/fonts\";\n\nexport interface ThemeConfig {\n /** `#rrggbb` */\n brandPrimary: string;\n brandSecondary: string;\n brandAccent: string;\n brandHighlight: string;\n brandSuccess: string;\n greyScale: GreyScale;\n /**\n * The selector the dark block is written under, or `\"@media\"` for a\n * `prefers-color-scheme` query. Defaults to `[data-theme=\"dark\"]`, which\n * is what `ThemeProvider` sets and the Tailwind preset's `dark:` variant\n * reads.\n */\n darkSelector?: string;\n defaultTheme: \"light\" | \"dark\" | \"system\";\n radius: RadiusPreset;\n shadow: ShadowPreset;\n motion: MotionPreset;\n density: DensityPreset;\n /**\n * A catalogue id from `@bison-lab/fonts` (`\"inter\"`). A value that is not\n * one is a legacy family name from an older `bison.config.json` and is\n * quoted into the stack as-is; the CLI migrates it to its id on the next\n * run.\n */\n fontBody: string;\n /** A catalogue id, a legacy family name, or `null` to use `fontBody` for headings. */\n fontHeading: string | null;\n fontWeights: {\n normal: number;\n medium: number;\n semibold: number;\n bold: number;\n };\n}\n\nexport interface BuildThemeCssOptions {\n /**\n * Overrides `config.darkSelector`: `\"class\"` writes the dark block under\n * `.dark`, `\"data-theme\"` under `[data-theme=\"dark\"]`.\n */\n attribute?: \"class\" | \"data-theme\";\n /**\n * When set, the stylesheet opens with the `@font-face` rules for the\n * catalogue families the config names, served from this base URL. The\n * CLI passes `/fonts`; a site rendering the theme at request time may\n * prefer `fontFaceCss` in its own `<head>` and leave this unset.\n */\n fontsBaseUrl?: string;\n}\n\nexport const DEFAULT_DARK_SELECTOR = '[data-theme=\"dark\"]';\n\n/** Whether a value is the six-digit hex colour a theme field must hold. */\nexport function isThemeHex(value: unknown): value is string {\n return typeof value === \"string\" && /^#[0-9a-f]{6}$/i.test(value);\n}\n\ntype ThemeColorFields = Pick<\n ThemeConfig,\n \"brandPrimary\" | \"brandSecondary\" | \"brandAccent\" | \"brandHighlight\" | \"brandSuccess\" | \"greyScale\"\n>;\n\nconst BRAND_FIELDS = [\n \"brandPrimary\",\n \"brandSecondary\",\n \"brandAccent\",\n \"brandHighlight\",\n \"brandSuccess\",\n] as const satisfies readonly (keyof ThemeColorFields)[];\n\n/**\n * Refuses a config whose brand colours are not `#rrggbb`, naming the field.\n * `hexToHSL` reads fixed substrings, so a short or malformed hex would\n * otherwise become `NaN` in the palette without a word: `buildThemeCss`\n * would emit a variable the browser drops, and a five-digit hex would\n * measure a plausible, wrong contrast ratio.\n */\nfunction assertThemeColors(config: ThemeColorFields): void {\n for (const field of BRAND_FIELDS) {\n const value = config[field];\n if (!isThemeHex(value)) {\n throw new Error(`${field} must be a six-digit hex colour like #1e3a5f, got ${JSON.stringify(value)}`);\n }\n }\n}\n\n/** The `BrandColors` a config's five hexes and grey scale describe. Throws on a hex that is not `#rrggbb`. */\nexport function brandColorsFromConfig(config: ThemeColorFields): BrandColors {\n assertThemeColors(config);\n return {\n primary: config.brandPrimary,\n secondary: config.brandSecondary,\n accent: config.brandAccent,\n highlight: config.brandHighlight,\n success: config.brandSuccess,\n grey: config.greyScale,\n };\n}\n\nfunction resolveDarkSelector(config: ThemeConfig, options?: BuildThemeCssOptions): string {\n if (options?.attribute === \"class\") return \".dark\";\n if (options?.attribute === \"data-theme\") return DEFAULT_DARK_SELECTOR;\n return config.darkSelector?.trim() || DEFAULT_DARK_SELECTOR;\n}\n\nconst LEGACY_FONT_FALLBACK = \"ui-sans-serif, system-ui, sans-serif\";\n\n/** The `font-family` value for a config font: the catalogue stack for an id, the CLI's old quoting for a legacy name. */\nfunction fontFamilyValue(value: string): string {\n return isFontId(value) ? fontStack(value) : `'${value}', ${LEGACY_FONT_FALLBACK}`;\n}\n\n/** The catalogue ids a config names, body first, without repeats. A legacy family name is not one. */\nexport function themeFontIds(config: Pick<ThemeConfig, \"fontBody\" | \"fontHeading\">): FontId[] {\n const ids: FontId[] = [];\n for (const value of [config.fontBody, config.fontHeading ?? config.fontBody]) {\n if (isFontId(value) && !ids.includes(value)) ids.push(value);\n }\n return ids;\n}\n\nfunction paletteLines(palette: SemanticPalette, indent: string): string[] {\n return Object.entries(palette).map(([key, value]) => `${indent}--${key}: ${value};`);\n}\n\nfunction presetLines(vars: Record<string, string>): string[] {\n return Object.entries(vars).map(([key, value]) => ` ${key}: ${value};`);\n}\n\n/**\n * The complete theme stylesheet for a config: the light semantic palette,\n * the brand and destructive scales, the four preset variable blocks, the\n * typography variables, and the dark palette under the dark selector.\n *\n * The preset blocks mean a site needs only this file and `base.css`; the\n * preset files under `css/themes/` stay for consumers composing their own\n * theme, and importing both is harmless.\n *\n * Throws, naming the field, when a brand colour is not `#rrggbb`; a CMS\n * that stored a bad value fails loudly rather than shipping a stylesheet\n * with a `NaN` in it. A blank `darkSelector` means the default.\n *\n * `fontBody` / `fontHeading` are catalogue ids and become the catalogue's\n * stack; a legacy family name is quoted as the CLI always wrote it. The\n * `@font-face` rules themselves are written only when `fontsBaseUrl` is\n * given.\n */\nexport function buildThemeCss(config: ThemeConfig, options?: BuildThemeCssOptions): string {\n const brand = brandColorsFromConfig(config);\n const light = deriveLightPalette(brand);\n const dark = deriveDarkPalette(brand);\n const scales = generateBrandScales(brand);\n const darkSelector = resolveDarkSelector(config, options);\n const fontFaces = options?.fontsBaseUrl ? fontFaceCss(themeFontIds(config), options.fontsBaseUrl) : \"\";\n\n const darkBlock =\n darkSelector === \"@media\"\n ? [\n `@media (prefers-color-scheme: dark) {`,\n ` :root {`,\n ...paletteLines(dark, \" \"),\n ` }`,\n `}`,\n ]\n : [`${darkSelector} {`, ...paletteLines(dark, \" \"), `}`];\n\n const lines: string[] = [\n `/* Bison Lab Theme — generated by @bison-lab/tokens buildThemeCss. Do not hand-edit; regenerate from bison.config.json. */`,\n `/* Brand: ${config.brandPrimary} / ${config.brandSecondary} / ${config.brandAccent} / ${config.brandHighlight} / ${config.brandSuccess} */`,\n `/* Grey: ${config.greyScale} */`,\n `/* Presets: radius ${config.radius} · shadow ${config.shadow} · motion ${config.motion} · density ${config.density} */`,\n ``,\n ...(fontFaces ? [fontFaces, ``] : []),\n `:root {`,\n ...paletteLines(light, \" \"),\n ``,\n ` /* Brand color scales (50–950) */`,\n generateScaleCSS(scales),\n ``,\n ` /* Destructive scale (50–950) — soft danger surfaces */`,\n generateDestructiveScaleCSS(),\n ``,\n ` /* Radius preset: ${config.radius} */`,\n ...presetLines(radiusPresets[config.radius]),\n ``,\n ` /* Shadow preset: ${config.shadow} */`,\n ...presetLines(shadowPresets[config.shadow]),\n ``,\n ` /* Motion preset: ${config.motion} */`,\n ...presetLines(motionPresets[config.motion]),\n ``,\n ` /* Density preset: ${config.density} */`,\n ...presetLines(densityPresets[config.density]),\n ``,\n ` /* Typography */`,\n ` --font-body: ${fontFamilyValue(config.fontBody)};`,\n ` --font-heading: ${fontFamilyValue(config.fontHeading ?? config.fontBody)};`,\n ` --font-weight-normal: ${config.fontWeights.normal};`,\n ` --font-weight-medium: ${config.fontWeights.medium};`,\n ` --font-weight-semibold: ${config.fontWeights.semibold};`,\n ` --font-weight-bold: ${config.fontWeights.bold};`,\n ` --font-weight-extrabold: 800;`,\n `}`,\n ``,\n ...darkBlock,\n ``,\n ];\n\n return lines.join(\"\\n\");\n}\n","/**\n * WCAG contrast, measured on the palette a theme derives.\n *\n * Pure functions with no DOM, so the Theme admin (BIS-60) can run them in\n * the browser as the editor types. `auditTheme` returns data only; the\n * `ContrastStrip` that draws it is BIS-59.\n */\n\nimport { deriveLightPalette, deriveDarkPalette, type SemanticPalette } from \"./colors\";\nimport { brandColorsFromConfig, type ThemeConfig } from \"./theme\";\n\n/** `#rrggbb`, or the token form the palettes use: `\"h s% l%\"`. */\nexport type ColorInput = string;\n\nexport type ContrastLevel = \"fail\" | \"aa-large\" | \"aa\" | \"aaa\";\n\n/**\n * What the pairing carries. `text` and `fill-with-text` are held to the\n * body text target; `large-text` to 4.5 under a 7:1 target, else 3;\n * `non-text` (a focus ring, a border) to WCAG 1.4.11's single 3:1 tier.\n */\nexport type ContrastRole = \"text\" | \"large-text\" | \"fill-with-text\" | \"non-text\";\n\nexport interface ContrastRating {\n aa: boolean;\n aaLarge: boolean;\n aaa: boolean;\n level: ContrastLevel;\n}\n\nexport interface ContrastSample {\n ratio: number;\n /** The WCAG text rating of `ratio`, whatever the role. */\n level: ContrastLevel;\n /** The measured colours, in the token form, so a renderer can draw them. */\n foreground: string;\n background: string;\n}\n\nexport interface ContrastCheck {\n /** Stable: `<foreground-token>-on-<background-token>`. */\n id: string;\n /** What the pairing affects, as advice: \"Secondary as eyebrow text on the page background\". */\n label: string;\n role: ContrastRole;\n light: ContrastSample;\n dark: ContrastSample;\n /** The threshold this check was judged against, after the role's rule. */\n target: number;\n /** Both modes at or above `target`. */\n meetsTarget: boolean;\n}\n\nexport type ContrastThemeInput = Pick<\n ThemeConfig,\n \"brandPrimary\" | \"brandSecondary\" | \"brandAccent\" | \"brandHighlight\" | \"brandSuccess\" | \"greyScale\"\n>;\n\nexport interface AuditThemeOptions {\n /** The body text target. 4.5 is AA; a site with an older audience passes 7. */\n target?: number;\n}\n\n// --- Colour parsing ---\n\ntype Rgb = [number, number, number];\n\nfunction hslToRgb(h: number, s: number, l: number): Rgb {\n const chroma = (1 - Math.abs(2 * l - 1)) * s;\n const hue = (((h % 360) + 360) % 360) / 60;\n const x = chroma * (1 - Math.abs((hue % 2) - 1));\n const m = l - chroma / 2;\n let rgb: Rgb;\n if (hue < 1) rgb = [chroma, x, 0];\n else if (hue < 2) rgb = [x, chroma, 0];\n else if (hue < 3) rgb = [0, chroma, x];\n else if (hue < 4) rgb = [0, x, chroma];\n else if (hue < 5) rgb = [x, 0, chroma];\n else rgb = [chroma, 0, x];\n return [rgb[0] + m, rgb[1] + m, rgb[2] + m];\n}\n\nfunction parseColor(input: ColorInput): Rgb {\n const hex = /^#([0-9a-f]{6})$/i.exec(input.trim());\n if (hex) {\n const value = parseInt(hex[1], 16);\n return [(value >> 16) & 255, (value >> 8) & 255, value & 255].map((channel) => channel / 255) as Rgb;\n }\n const triplet = /^(-?[\\d.]+)\\s+([\\d.]+)%\\s+([\\d.]+)%$/.exec(input.trim());\n if (triplet) {\n return hslToRgb(Number(triplet[1]), Number(triplet[2]) / 100, Number(triplet[3]) / 100);\n }\n throw new Error(`Not a colour this module reads: \"${input}\". Pass #rrggbb or \"h s% l%\".`);\n}\n\n// --- WCAG 2.x ---\n\nfunction linearChannel(channel: number): number {\n return channel <= 0.04045 ? channel / 12.92 : Math.pow((channel + 0.055) / 1.055, 2.4);\n}\n\n/** WCAG relative luminance, 0 for black to 1 for white. */\nexport function relativeLuminance(color: ColorInput): number {\n const [r, g, b] = parseColor(color);\n return 0.2126 * linearChannel(r) + 0.7152 * linearChannel(g) + 0.0722 * linearChannel(b);\n}\n\n/** WCAG contrast ratio between two colours, 1 to 21, to two decimal places. Order does not matter. */\nexport function contrastRatio(a: ColorInput, b: ColorInput): number {\n const la = relativeLuminance(a);\n const lb = relativeLuminance(b);\n const ratio = (Math.max(la, lb) + 0.05) / (Math.min(la, lb) + 0.05);\n return Math.round(ratio * 100) / 100;\n}\n\n/** The WCAG text ratings a ratio earns: 3:1 large text, 4.5:1 AA, 7:1 AAA. */\nexport function rateContrast(ratio: number): ContrastRating {\n const aaLarge = ratio >= 3;\n const aa = ratio >= 4.5;\n const aaa = ratio >= 7;\n return { aa, aaLarge, aaa, level: aaa ? \"aaa\" : aa ? \"aa\" : aaLarge ? \"aa-large\" : \"fail\" };\n}\n\nconst LEVEL_LABEL: Record<ContrastLevel, string> = {\n aaa: \"AAA\",\n aa: \"AA\",\n \"aa-large\": \"AA large\",\n fail: \"Fails\",\n};\n\n/** The level word both `ContrastStrip` and the Theme admin field show. */\nexport function contrastLevelLabel(level: ContrastLevel): string {\n return LEVEL_LABEL[level];\n}\n\nexport interface ContrastVerdict {\n meets: boolean;\n text: string;\n}\n\n/**\n * Whether `sample` clears `target`, and the sentence both renderers print\n * (`\"meets 4.5:1\"` / `\"below 7:1\"`).\n */\nexport function contrastVerdict(\n sample: Pick<ContrastSample, \"ratio\">,\n target: number,\n): ContrastVerdict {\n const meets = sample.ratio >= target;\n return { meets, text: `${meets ? \"meets\" : \"below\"} ${target}:1` };\n}\n\n// --- The audit ---\n\ntype PaletteToken = keyof SemanticPalette;\n\ninterface Pairing {\n foreground: PaletteToken;\n background: PaletteToken;\n role: ContrastRole;\n label: string;\n}\n\n/** Every pairing in the system that carries text, plus the focus ring. */\nconst PAIRINGS: readonly Pairing[] = [\n { foreground: \"primary-foreground\", background: \"primary\", role: \"fill-with-text\", label: \"Primary button label on the primary fill\" },\n { foreground: \"secondary-foreground\", background: \"secondary\", role: \"fill-with-text\", label: \"Secondary button label on the secondary fill\" },\n { foreground: \"brand-accent-foreground\", background: \"brand-accent\", role: \"fill-with-text\", label: \"Copy on a brand-accent band\" },\n { foreground: \"highlight-foreground\", background: \"highlight\", role: \"fill-with-text\", label: \"Copy on a highlight fill\" },\n { foreground: \"success-foreground\", background: \"success\", role: \"fill-with-text\", label: \"Success badge label on its fill\" },\n { foreground: \"destructive-foreground\", background: \"destructive\", role: \"fill-with-text\", label: \"Destructive button label on its fill\" },\n { foreground: \"accent-foreground\", background: \"accent\", role: \"fill-with-text\", label: \"Hovered and selected item text on the accent surface\" },\n { foreground: \"muted-foreground\", background: \"muted\", role: \"fill-with-text\", label: \"Hint text on a muted surface\" },\n { foreground: \"card-foreground\", background: \"card\", role: \"fill-with-text\", label: \"Card body text on the card surface\" },\n { foreground: \"popover-foreground\", background: \"popover\", role: \"fill-with-text\", label: \"Menu and popover text on the popover surface\" },\n { foreground: \"foreground\", background: \"background\", role: \"text\", label: \"Body text on the page background\" },\n { foreground: \"foreground\", background: \"card\", role: \"text\", label: \"Body text on a card\" },\n { foreground: \"muted-foreground\", background: \"background\", role: \"text\", label: \"Supporting text on the page background\" },\n { foreground: \"muted-foreground\", background: \"card\", role: \"text\", label: \"Supporting text on a card\" },\n { foreground: \"content-secondary\", background: \"background\", role: \"text\", label: \"Chart axis labels and tertiary text on the page background\" },\n { foreground: \"content-secondary\", background: \"card\", role: \"text\", label: \"Chart axis labels and tertiary text on a card\" },\n { foreground: \"primary\", background: \"background\", role: \"text\", label: \"Primary as link text on the page background\" },\n { foreground: \"secondary\", background: \"background\", role: \"text\", label: \"Secondary as eyebrow text on the page background\" },\n { foreground: \"ring\", background: \"background\", role: \"non-text\", label: \"Focus ring on the page background\" },\n];\n\nfunction roleTarget(role: ContrastRole, target: number): number {\n switch (role) {\n case \"non-text\":\n return 3;\n case \"large-text\":\n return target >= 7 ? 4.5 : 3;\n default:\n return target;\n }\n}\n\nfunction sample(palette: SemanticPalette, pairing: Pairing): ContrastSample {\n const foreground = palette[pairing.foreground];\n const background = palette[pairing.background];\n const ratio = contrastRatio(foreground, background);\n return { ratio, level: rateContrast(ratio).level, foreground, background };\n}\n\n/**\n * Measures every text-carrying pairing the palette derives for these\n * colours, in light and dark. Advice, not enforcement: nothing here refuses\n * a theme on its ratios. The checks are data; BIS-59's `ContrastStrip` draws\n * them.\n *\n * Throws, naming the field, when a brand colour is not `#rrggbb`, the same\n * contract as `buildThemeCss`. An admin field validates its own value\n * before calling this, so a half-typed hex never reaches it.\n */\nexport function auditTheme(config: ContrastThemeInput, options: AuditThemeOptions = {}): ContrastCheck[] {\n const target = options.target ?? 4.5;\n const brand = brandColorsFromConfig(config);\n const light = deriveLightPalette(brand);\n const dark = deriveDarkPalette(brand);\n\n return PAIRINGS.map((pairing) => {\n const lightSample = sample(light, pairing);\n const darkSample = sample(dark, pairing);\n const threshold = roleTarget(pairing.role, target);\n return {\n id: `${pairing.foreground}-on-${pairing.background}`,\n label: pairing.label,\n role: pairing.role,\n light: lightSample,\n dark: darkSample,\n target: threshold,\n meetsTarget: lightSample.ratio >= threshold && darkSample.ratio >= threshold,\n };\n });\n}\n","/**\n * The label and hint the CLI and the Theme Global show for each preset\n * value. One record, so the two cannot drift.\n */\n\nexport interface PresetHint {\n label: string;\n hint: string;\n}\n\nexport const presetHints = {\n greyScale: {\n slate: { label: \"Slate\", hint: \"Cool blue-grey — modern, tech-forward\" },\n gray: { label: \"Gray\", hint: \"Balanced blue-grey — neutral default\" },\n zinc: { label: \"Zinc\", hint: \"Cool desaturated — minimal, sharp\" },\n neutral: { label: \"Neutral\", hint: \"Pure grey — zero hue bias\" },\n stone: { label: \"Stone\", hint: \"Warm earthy grey — organic, approachable\" },\n },\n radius: {\n sharp: { label: \"Sharp\", hint: \"0px — square corners\" },\n subtle: { label: \"Subtle\", hint: \"6px — barely rounded\" },\n rounded: { label: \"Rounded\", hint: \"8px — balanced (default)\" },\n pill: { label: \"Pill\", hint: \"12px — soft, bubbly\" },\n },\n shadow: {\n flat: { label: \"Flat\", hint: \"No shadows — clean, modern\" },\n subtle: { label: \"Subtle\", hint: \"Soft low-opacity shadows (default)\" },\n elevated: { label: \"Elevated\", hint: \"Prominent layered shadows\" },\n },\n motion: {\n snappy: { label: \"Snappy\", hint: \"Fast, spring-like (150ms)\" },\n smooth: { label: \"Smooth\", hint: \"Balanced ease-out (200ms, default)\" },\n minimal: { label: \"Minimal\", hint: \"Barely-there, linear (100ms)\" },\n },\n density: {\n compact: { label: \"Compact\", hint: \"Tight padding, smaller components\" },\n default: { label: \"Default\", hint: \"Balanced spacing\" },\n spacious: { label: \"Spacious\", hint: \"Generous padding, larger components\" },\n },\n defaultTheme: {\n system: { label: \"System\", hint: \"Follow OS preference (recommended)\" },\n light: { label: \"Light\", hint: \"Always start in light mode\" },\n dark: { label: \"Dark\", hint: \"Always start in dark mode\" },\n },\n} as const satisfies Record<string, Record<string, PresetHint>>;\n\nexport type PresetHintFamily = keyof typeof presetHints;\n"],"mappings":";;AAeA,SAAS,aAAa,GAAmB;AACvC,QAAO,KAAK,SAAU,IAAI,QAAQ,KAAK,KAAK,IAAI,QAAS,OAAO,IAAI;;AAGtE,SAAS,aAAa,GAAmB;AACvC,QAAO,KAAK,WAAY,IAAI,QAAQ,QAAQ,KAAK,IAAI,GAAG,IAAI,IAAI,GAAG;;AAKrE,SAAS,UAAU,KAAuC;AACxD,OAAM,IAAI,QAAQ,KAAK,GAAG;AAC1B,QAAO;EACL,SAAS,IAAI,UAAU,GAAG,EAAE,EAAE,GAAG,GAAG;EACpC,SAAS,IAAI,UAAU,GAAG,EAAE,EAAE,GAAG,GAAG;EACpC,SAAS,IAAI,UAAU,GAAG,EAAE,EAAE,GAAG,GAAG;EACrC;;AAKH,SAAS,kBAAkB,GAAW,GAAW,GAAqC;CACpF,MAAM,IAAI,cAAe,IAAI,cAAe,IAAI,cAAe;CAC/D,MAAM,IAAI,cAAe,IAAI,cAAe,IAAI,cAAe;CAC/D,MAAM,IAAI,cAAe,IAAI,cAAe,IAAI,cAAe;CAE/D,MAAM,KAAK,KAAK,KAAK,EAAE;CACvB,MAAM,KAAK,KAAK,KAAK,EAAE;CACvB,MAAM,KAAK,KAAK,KAAK,EAAE;AAEvB,QAAO;EACL,cAAe,KAAK,aAAe,KAAK,cAAe;EACvD,eAAe,KAAK,cAAe,KAAK,cAAe;EACvD,cAAe,KAAK,cAAe,KAAK,aAAe;EACxD;;AAGH,SAAS,kBAAkB,GAAW,GAAW,GAAqC;CACpF,MAAM,KAAK,IAAI,cAAe,IAAI,cAAe;CACjD,MAAM,KAAK,IAAI,cAAe,IAAI,cAAe;CACjD,MAAM,KAAK,IAAI,cAAe,IAAI,cAAe;AAEjD,QAAO;EACJ,eAAe,KAAK,KAAK,KAAK,eAAe,KAAK,KAAK,KAAK,cAAe,KAAK,KAAK;EACtF,gBAAgB,KAAK,KAAK,KAAK,eAAe,KAAK,KAAK,KAAK,cAAe,KAAK,KAAK;EACtF,eAAgB,KAAK,KAAK,KAAK,cAAe,KAAK,KAAK,KAAK,cAAe,KAAK,KAAK;EACvF;;AAKH,SAAS,aAAa,GAAW,GAAW,GAAkB;CAC5D,MAAM,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,EAAE;CAClC,IAAI,IAAK,KAAK,MAAM,GAAG,EAAE,GAAG,MAAO,KAAK;AACxC,KAAI,IAAI,EAAG,MAAK;AAChB,QAAO;EAAE;EAAG;EAAG;EAAG;;AAGpB,SAAS,aAAa,GAAW,GAAW,GAAqC;CAC/E,MAAM,OAAQ,IAAI,KAAK,KAAM;AAC7B,QAAO;EAAC;EAAG,IAAI,KAAK,IAAI,KAAK;EAAE,IAAI,KAAK,IAAI,KAAK;EAAC;;AAKpD,SAAS,UAAU,GAAW,GAAW,GAAoB;CAC3D,MAAM,MAAM;AACZ,QAAO,KAAK,CAAC,OAAO,KAAK,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,IAAI;;AAGzF,SAAS,iBAAiB,GAAW,GAAW,GAAmB;AACjE,KAAI,KAAK,EAAG,QAAO;CAEnB,MAAM,GAAG,GAAG,KAAK,aAAa,GAAG,GAAG,EAAE;CACtC,MAAM,CAAC,GAAG,GAAG,MAAM,kBAAkB,GAAG,GAAG,EAAE;AAE7C,KAAI,UAAU,GAAG,GAAG,GAAG,CAAE,QAAO;CAEhC,IAAI,KAAK;CACT,IAAI,KAAK;AAET,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;EAC3B,MAAM,OAAO,KAAK,MAAM;EACxB,MAAM,GAAG,IAAI,MAAM,aAAa,GAAG,KAAK,EAAE;EAC1C,MAAM,CAAC,IAAI,IAAI,OAAO,kBAAkB,GAAG,IAAI,GAAG;AAElD,MAAI,UAAU,IAAI,IAAI,IAAI,CACxB,MAAK;MAEL,MAAK;;AAIT,QAAO;;AAKT,SAAS,UAAU,GAAW,GAAW,GAAqC;CAC5E,MAAM,MAAM,KAAK,IAAI,GAAG,GAAG,EAAE;CAC7B,MAAM,MAAM,KAAK,IAAI,GAAG,GAAG,EAAE;CAC7B,MAAM,KAAK,MAAM,OAAO;CACxB,IAAI,IAAI;CACR,IAAI,IAAI;AAER,KAAI,QAAQ,KAAK;EACf,MAAM,IAAI,MAAM;AAChB,MAAI,IAAI,KAAM,KAAK,IAAI,MAAM,OAAO,KAAK,MAAM;AAC/C,UAAQ,KAAR;GACE,KAAK;AACH,UAAM,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,MAAM;AACtC;GACF,KAAK;AACH,UAAM,IAAI,KAAK,IAAI,KAAK;AACxB;GACF,KAAK;AACH,UAAM,IAAI,KAAK,IAAI,KAAK;AACxB;;;AAIN,QAAO;EAAC,KAAK,MAAM,IAAI,IAAI;EAAE,KAAK,MAAM,IAAI,IAAI;EAAE,KAAK,MAAM,IAAI,IAAI;EAAC;;AAKxE,SAAgB,WAAW,KAAoB;CAC7C,MAAM,CAAC,GAAG,GAAG,KAAK,UAAU,IAAI;CAChC,MAAM,CAAC,IAAI,IAAI,MAAM;EAAC,aAAa,EAAE;EAAE,aAAa,EAAE;EAAE,aAAa,EAAE;EAAC;CACxE,MAAM,CAAC,GAAG,GAAG,MAAM,kBAAkB,IAAI,IAAI,GAAG;AAChD,QAAO,aAAa,GAAG,GAAG,GAAG;;AAG/B,SAAgB,iBAAiB,GAAW,GAAW,GAAmB;CAExE,MAAM,GAAG,GAAG,KAAK,aAAa,GADb,iBAAiB,GAAG,GAAG,EAAE,EACC,EAAE;CAC7C,MAAM,CAAC,IAAI,IAAI,MAAM,kBAAkB,GAAG,GAAG,EAAE;CAM/C,MAAM,CAAC,GAAG,GAAG,KAAK,UAJR,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,aAAa,GAAG,CAAC,CAAC,EAC1C,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,aAAa,GAAG,CAAC,CAAC,EACzC,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,aAAa,GAAG,CAAC,CAAC,CAEhB;AACrC,QAAO,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE;;;;;;;;;;AC/IzB,SAAgB,SAAS,KAAkB;AACzC,OAAM,IAAI,QAAQ,KAAK,GAAG;CAC1B,MAAM,IAAI,SAAS,IAAI,UAAU,GAAG,EAAE,EAAE,GAAG,GAAG;CAC9C,MAAM,IAAI,SAAS,IAAI,UAAU,GAAG,EAAE,EAAE,GAAG,GAAG;CAC9C,MAAM,IAAI,SAAS,IAAI,UAAU,GAAG,EAAE,EAAE,GAAG,GAAG;CAE9C,MAAM,MAAM,KAAK,IAAI,GAAG,GAAG,EAAE;CAC7B,MAAM,MAAM,KAAK,IAAI,GAAG,GAAG,EAAE;CAC7B,MAAM,KAAK,MAAM,OAAO;CACxB,IAAI,IAAI;CACR,IAAI,IAAI;AAER,KAAI,QAAQ,KAAK;EACf,MAAM,IAAI,MAAM;AAChB,MAAI,IAAI,KAAM,KAAK,IAAI,MAAM,OAAO,KAAK,MAAM;AAC/C,UAAQ,KAAR;GACE,KAAK;AACH,UAAM,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,MAAM;AACtC;GACF,KAAK;AACH,UAAM,IAAI,KAAK,IAAI,KAAK;AACxB;GACF,KAAK;AACH,UAAM,IAAI,KAAK,IAAI,KAAK;AACxB;;;AAIN,QAAO;EACL,GAAG,KAAK,MAAM,IAAI,IAAI;EACtB,GAAG,KAAK,MAAM,IAAI,IAAI;EACtB,GAAG,KAAK,MAAM,IAAI,IAAI;EACvB;;AAGH,SAAgB,YAAY,KAAkB;AAC5C,QAAO,GAAG,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,IAAI,EAAE;;AAGrC,SAAS,MAAM,OAAe,KAAa,KAAqB;AAC9D,QAAO,KAAK,IAAI,KAAK,IAAI,OAAO,IAAI,EAAE,IAAI;;AAW5C,MAAa,cAA8C;CACzD,OAAO;EACL,MAAM;EACN,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACR;CACD,MAAM;EACJ,MAAM;EACN,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACR;CACD,MAAM;EACJ,MAAM;EACN,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACR;CACD,SAAS;EACP,MAAM;EACN,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACR;CACD,OAAO;EACL,MAAM;EACN,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACP,OAAO;EACR;CACF;AAeD,MAAa,cAAc;CAAC;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;AAcjF,MAAM,mBAA8C;CAClD,IAAI;CACJ,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACN;;;;;;AASD,SAAgB,mBAAmB,KAAyB;CAC1D,MAAM,EAAE,GAAG,QAAQ,GAAG,QAAQ,MAAM,WAAW,IAAI;CAGnD,MAAM,eAAe,MAAsB,KAAK,IAAI,KAAK,KAAK,EAAE;CAChE,MAAM,kBAAkB,YAAY,OAAO;CAG3C,MAAM,cAAc,kBAAkB,MAAO,SAAS,kBAAkB;CAExE,MAAM,QAAQ,EAAE;AAEhB,MAAK,MAAM,QAAQ,aAAa;EAC9B,MAAM,UAAU,iBAAiB;AAKjC,QAAM,QAAQ,iBAAiB,SAJf,kBAAkB,MAC9B,cAAc,YAAY,QAAQ,GAClC,SAAS,YAAY,QAAQ,EAEgB,EAAE;;AAGrD,QAAO;;;;;AAMT,SAAgB,oBAAoB,OAAiC;CACnE,MAAM,YAAY,MAAM,UAAU,MAAM;CACxC,MAAM,eAAe,MAAM,aAAa,MAAM;AAE9C,QAAO;EACL,SAAS,mBAAmB,MAAM,QAAQ;EAC1C,WAAW,mBAAmB,MAAM,UAAU;EAC9C,gBAAgB,mBAAmB,UAAU;EAC7C,WAAW,mBAAmB,aAAa;EAC3C,SAAS,mBAAmB,MAAM,QAAQ;EAC3C;;;;;;AAOH,SAAgB,iBAAiB,QAA6B;CAC5D,MAAM,QAAkB,EAAE;AAE1B,MAAK,MAAM,CAAC,WAAW,UAAU,OAAO,QAAQ,OAAO,CACrD,MAAK,MAAM,QAAQ,YACjB,OAAM,KAAK,OAAO,UAAU,GAAG,KAAK,IAAK,MAAqB,MAAM,GAAG;AAI3E,QAAO,MAAM,KAAK,KAAK;;;;;;;AAQzB,MAAa,wBAAwB;AAErC,IAAI,6BAAgD;AAEpD,SAAgB,2BAAuC;AACrD,KAAI,CAAC,2BACH,8BAA6B,mBAAmB,sBAAsB;AAExE,QAAO;;;AAIT,SAAgB,8BAAsC;CACpD,MAAM,QAAQ,0BAA0B;AACxC,QAAO,YAAY,KAAK,SAAS,mBAAmB,KAAK,IAAI,MAAM,MAAM,GAAG,CAAC,KAAK,KAAK;;;;;;;AA4CzF,SAAS,mBAAmB,OAAoB;AAC9C,QAAO,MAAM,IAAI,KACb,YAAY;EAAE,GAAG,MAAM;EAAG,GAAG,MAAM,MAAM,IAAI,IAAI,GAAG,IAAI;EAAE,GAAG;EAAI,CAAC,GAClE,YAAY;EAAE,GAAG,MAAM;EAAG,GAAG,MAAM,MAAM,IAAI,IAAI,GAAG,IAAI;EAAE,GAAG;EAAI,CAAC;;;;;;;;;;AAWxE,MAAM,0BAA0B;;;;;;AAOhC,MAAM,0BAA0B;AAEhC,SAAS,eAAe,OAAY,OAAoB;AACtD,KAAI,MAAM,IAAI,MACZ,QAAO;EAAE,GAAG;EAAO,GAAG,MAAM,MAAM,IAAI,IAAI,GAAG,IAAI;EAAE;AAErD,QAAO;;;;;;;;;;;;;;;;AAmBT,SAAgB,mBAAmB,OAAqC;CACtE,MAAM,OAAO,YAAY,MAAM,QAAQ;CACvC,MAAM,UAAU,SAAS,MAAM,QAAQ;CACvC,MAAM,YAAY,SAAS,MAAM,UAAU;CAC3C,MAAM,SAAS,MAAM,SAAS,SAAS,MAAM,OAAO,GAAG;CACvD,MAAM,YAAY,MAAM,YAAY,SAAS,MAAM,UAAU,GAAG;CAChE,MAAM,UAAU,SAAS,MAAM,QAAQ;AAEvC,QAAO;EACL,YAAY,KAAK;EACjB,YAAY,KAAK;EACjB,MAAM;EACN,mBAAmB,KAAK;EACxB,oBAAoB,KAAK;EACzB,SAAS;EACT,sBAAsB,KAAK;EAC3B,SAAS,YAAY,QAAQ;EAC7B,sBAAsB,mBAAmB,QAAQ;EACjD,WAAW,YAAY,UAAU;EACjC,wBAAwB,mBAAmB,UAAU;EACrD,QAAQ,KAAK;EACb,qBAAqB,KAAK;EAC1B,gBAAgB,YAAY,OAAO;EACnC,2BAA2B,mBAAmB,OAAO;EACrD,WAAW,YAAY,UAAU;EACjC,wBAAwB,mBAAmB,UAAU;EACrD,SAAS,YAAY,QAAQ;EAC7B,sBAAsB,mBAAmB,QAAQ;EACjD,OAAO,KAAK;EACZ,oBAAoB,KAAK;EACzB,qBAAqB,KAAK;EAC1B,aAAa;EACb,0BAA0B;EAC1B,QAAQ,KAAK;EACb,iBAAiB,KAAK;EACtB,iBAAiB,KAAK;EACtB,OAAO,KAAK;EACZ,MAAM,YAAY,QAAQ;EAC3B;;;;;;;;;;;;;;;;;;AAmBH,SAAgB,kBAAkB,OAAqC;CACrE,MAAM,OAAO,YAAY,MAAM,QAAQ;CACvC,MAAM,aAAa,SAAS,MAAM,QAAQ;CAC1C,MAAM,UAAU,eAAe,YAAY,wBAAwB;CACnE,MAAM,YAAY,eAAe,SAAS,MAAM,UAAU,EAAE,wBAAwB;CACpF,MAAM,SAAS,eAAe,MAAM,SAAS,SAAS,MAAM,OAAO,GAAG,YAAY,wBAAwB;CAC1G,MAAM,YAAY,eAChB,MAAM,YAAY,SAAS,MAAM,UAAU,GAAG,SAAS,MAAM,UAAU,EACvE,wBACD;CACD,MAAM,UAAU,eAAe,SAAS,MAAM,QAAQ,EAAE,wBAAwB;CAChF,MAAM,OAAO,eAAe,YAAY,wBAAwB;AAEhE,QAAO;EACL,YAAY,KAAK;EACjB,YAAY,KAAK;EACjB,MAAM,KAAK;EACX,mBAAmB,KAAK;EACxB,oBAAoB,KAAK;EACzB,SAAS,KAAK;EACd,sBAAsB,KAAK;EAC3B,SAAS,YAAY,QAAQ;EAC7B,sBAAsB,mBAAmB,QAAQ;EACjD,WAAW,YAAY,UAAU;EACjC,wBAAwB,mBAAmB,UAAU;EACrD,QAAQ,KAAK;EACb,qBAAqB,KAAK;EAC1B,gBAAgB,YAAY,OAAO;EACnC,2BAA2B,mBAAmB,OAAO;EACrD,WAAW,YAAY,UAAU;EACjC,wBAAwB,mBAAmB,UAAU;EACrD,SAAS,YAAY,QAAQ;EAC7B,sBAAsB,mBAAmB,QAAQ;EACjD,OAAO,KAAK;EACZ,oBAAoB,KAAK;EACzB,qBAAqB,KAAK;EAC1B,aAAa;EACb,0BAA0B;EAC1B,QAAQ,KAAK;EACb,iBAAiB,KAAK;EACtB,iBAAiB,KAAK;EACtB,OAAO,KAAK;EACZ,MAAM,YAAY,KAAK;EACxB;;AAGH,SAAgB,mBAAmB,OAAoB,YAAoC,SAAiB;CAC1G,MAAM,QAAQ,mBAAmB,MAAM;CACvC,MAAM,OAAO,kBAAkB,MAAM;CACrC,MAAM,SAAS,oBAAoB,MAAM;CAEzC,MAAM,UAAU,SAA0B,WACxC,OAAO,QAAQ,QAAQ,CACpB,KAAK,CAAC,KAAK,WAAW,GAAG,OAAO,IAAI,IAAI,IAAI,MAAM,GAAG,CACrD,KAAK,KAAK;CAEf,MAAM,eAAe,cAAc,UAAU,UAAU;AAEvD,QAAO,YAAY,OAAO,OAAO,KAAK,CAAC,MAAM,iBAAiB,OAAO,CAAC,MAAM,6BAA6B,CAAC,SAAS,aAAa,MAAM,OAAO,MAAM,KAAK,CAAC;;;;AC9c3J,MAAa,gBAAgB;CAC3B,OAAO;EACL,YAAY;EACZ,eAAe;EACf,eAAe;EACf,eAAe;EACf,eAAe;EACf,iBAAiB;EAClB;CACD,QAAQ;EACN,YAAY;EACZ,eAAe;EACf,eAAe;EACf,eAAe;EACf,eAAe;EACf,iBAAiB;EAClB;CACD,SAAS;EACP,YAAY;EACZ,eAAe;EACf,eAAe;EACf,eAAe;EACf,eAAe;EACf,iBAAiB;EAClB;CACD,MAAM;EACJ,YAAY;EACZ,eAAe;EACf,eAAe;EACf,eAAe;EACf,eAAe;EACf,iBAAiB;EAClB;CACF;;;ACjCD,MAAa,gBAAgB;CAC3B,MAAM;EACJ,eAAe;EACf,YAAY;EACZ,eAAe;EACf,eAAe;EACf,eAAe;EAChB;CACD,QAAQ;EACN,eAAe;EACf,YAAY;EACZ,eAAe;EACf,eAAe;EACf,eAAe;EAChB;CACD,UAAU;EACR,eAAe;EACf,YAAY;EACZ,eAAe;EACf,eAAe;EACf,eAAe;EAChB;CACF;;;ACtBD,MAAa,gBAAgB;CAC3B,QAAQ;EACN,mBAAmB;EACnB,qBAAqB;EACrB,mBAAmB;EACnB,kBAAkB;EAClB,aAAa;EACb,cAAc;EACd,iBAAiB;EAClB;CACD,QAAQ;EACN,mBAAmB;EACnB,qBAAqB;EACrB,mBAAmB;EACnB,kBAAkB;EAClB,aAAa;EACb,cAAc;EACd,iBAAiB;EAClB;CACD,SAAS;EACP,mBAAmB;EACnB,qBAAqB;EACrB,mBAAmB;EACnB,kBAAkB;EAClB,aAAa;EACb,cAAc;EACd,iBAAiB;EAClB;CACF;;;AC5BD,MAAa,iBAAiB;CAC5B,SAAS;EACP,wBAAwB;EACxB,wBAAwB;EACxB,wBAAwB;EACxB,wBAAwB;EACxB,wBAAwB;EACxB,oBAAoB;EACpB,oBAAoB;EACpB,oBAAoB;EACpB,uBAAuB;EACvB,uBAAuB;EACvB,uBAAuB;EACxB;CACD,SAAS;EACP,wBAAwB;EACxB,wBAAwB;EACxB,wBAAwB;EACxB,wBAAwB;EACxB,wBAAwB;EACxB,oBAAoB;EACpB,oBAAoB;EACpB,oBAAoB;EACpB,uBAAuB;EACvB,uBAAuB;EACvB,uBAAuB;EACxB;CACD,UAAU;EACR,wBAAwB;EACxB,wBAAwB;EACxB,wBAAwB;EACxB,wBAAwB;EACxB,wBAAwB;EACxB,oBAAoB;EACpB,oBAAoB;EACpB,oBAAoB;EACpB,uBAAuB;EACvB,uBAAuB;EACvB,uBAAuB;EACxB;CACF;;;;ACvCD,MAAa,YAAY;CACvB,WAAW;EAAE,UAAU;EAAW,YAAY;EAAQ;CACtD,WAAW;EAAE,UAAU;EAAY,YAAY;EAAW;CAC1D,aAAa;EAAE,UAAU;EAAQ,YAAY;EAAU;CACvD,WAAW;EAAE,UAAU;EAAY,YAAY;EAAW;CAC1D,WAAW;EAAE,UAAU;EAAW,YAAY;EAAW;CACzD,YAAY;EAAE,UAAU;EAAU,YAAY;EAAQ;CACtD,YAAY;EAAE,UAAU;EAAY,YAAY;EAAW;CAC3D,YAAY;EAAE,UAAU;EAAW,YAAY;EAAU;CAGzD,cAAc;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EAChB;CACD,cAAc;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EAChB;CACD,cAAc;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EAChB;CACD,cAAc;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EAChB;CACD,eAAe;EACb,UAAU;EACV,YAAY;EACZ,eAAe;EAChB;CACF;AAUD,MAAa,qBAAoC;CAC/C,QAAQ;CACR,QAAQ;CACR,UAAU;CACV,MAAM;CACN,WAAW;CACZ;;;;ACpDD,MAAa,eAAe;CAC1B,KAAK;CACL,OAAO;CACP,KAAK;CACL,OAAO;CACP,KAAK;CACL,OAAO;CACP,KAAK;CACL,OAAO;CACP,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACP;;;;ACnCD,MAAa,eAAe;CAC1B,gBAAgB;CAChB,cAAc;CACd,aAAa;CACb,sBAAsB;CACtB,aAAa;CACb,eAAe;CACf,eAAe;CACf,aAAa;CACd;;;;;;;;;;ACID,SAAS,cAAc,IAAoB;AACzC,QAAO,SAAS,IAAI,GAAG,GAAG;;AAG5B,SAAS,YAAY,KAAgC;AACnD,KAAI,QAAQ,SAAU,QAAO;CAC7B,MAAM,QAAQ,IAAI,MAChB,gFACD;AACD,KAAI,CAAC,MAAO,QAAO;EAAC;EAAM;EAAK;EAAM;EAAE;AACvC,QAAO;EAAC,OAAO,MAAM,GAAG;EAAE,OAAO,MAAM,GAAG;EAAE,OAAO,MAAM,GAAG;EAAE,OAAO,MAAM,GAAG;EAAC;;;;;;;;;;;;;;;;;AAkDjF,SAAgB,oBAAoB,SAAuB,UAA4B;CACrF,MAAM,SAAS,cAAc;CAC7B,MAAM,SAAS,cAAc,OAAO,qBAAqB;CACzD,MAAM,OAAO,cAAc,OAAO,mBAAmB;CACrD,MAAM,OAAO,YAAY,OAAO,cAAc;CAE9C,MAAM,aAAa;EAAE,UAAU;EAAQ;EAAM;CAC7C,MAAM,iBAAiB;EAAE,UAAU;EAAM;EAAM;AAE/C,QAAO;EACL,QAAQ;GACN,QAAQ,EAAE,SAAS,GAAG;GACtB,SAAS;IAAE,SAAS;IAAG;IAAY;GACpC;EAED,QAAQ;GACN,QAAQ;IAAE,SAAS;IAAG,GAAG;IAAI;GAC7B,SAAS;IAAE,SAAS;IAAG,GAAG;IAAG;IAAY;GAC1C;EAED,UAAU;GACR,QAAQ;IAAE,SAAS;IAAG,GAAG;IAAK;GAC9B,SAAS;IAAE,SAAS;IAAG,GAAG;IAAG;IAAY;GAC1C;EAED,SAAS;GACP,QAAQ;IAAE,SAAS;IAAG,OAAO;IAAM;GACnC,SAAS;IAAE,SAAS;IAAG,OAAO;IAAG;IAAY;GAC9C;EAED,aAAa;GACX,QAAQ;IAAE,SAAS;IAAG,GAAG;IAAK;GAC9B,SAAS;IAAE,SAAS;IAAG,GAAG;IAAG;IAAY;GAC1C;EAED,cAAc;GACZ,QAAQ;IAAE,SAAS;IAAG,GAAG;IAAI;GAC7B,SAAS;IAAE,SAAS;IAAG,GAAG;IAAG;IAAY;GAC1C;EAED,UAAU;GACR,QAAQ;IAAE,SAAS;IAAG,GAAG;IAAG,OAAO;IAAM;GACzC,SAAS;IACP,SAAS;IACT,GAAG;IACH,OAAO;IACP,YAAY;IACb;GACD,MAAM;IAAE,SAAS;IAAG,GAAG;IAAG,OAAO;IAAM;IAAY;GACpD;EAED,kBAAkB;GAChB,QAAQ,EAAE;GACV,SAAS,EACP,YAAY;IACV,iBAAiB;IACjB,eAAe;IAChB,EACF;GACF;EAED,aAAa;GACX,QAAQ;IAAE,SAAS;IAAG,GAAG;IAAG;GAC5B,SAAS;IAAE,SAAS;IAAG,GAAG;IAAG;IAAY;GAC1C;EAED,gBAAgB;GACd,QAAQ;IAAE,SAAS;IAAG,GAAG;IAAG;GAC5B,SAAS;IAAE,SAAS;IAAG,GAAG;IAAG,YAAY;IAAgB;GACzD,MAAM;IAAE,SAAS;IAAG,GAAG;IAAI;IAAY;GACxC;EACF;;;;;;;;;;;;ACpEH,MAAa,wBAAwB;;AAGrC,SAAgB,WAAW,OAAiC;AAC1D,QAAO,OAAO,UAAU,YAAY,kBAAkB,KAAK,MAAM;;AAQnE,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACD;;;;;;;;AASD,SAAS,kBAAkB,QAAgC;AACzD,MAAK,MAAM,SAAS,cAAc;EAChC,MAAM,QAAQ,OAAO;AACrB,MAAI,CAAC,WAAW,MAAM,CACpB,OAAM,IAAI,MAAM,GAAG,MAAM,oDAAoD,KAAK,UAAU,MAAM,GAAG;;;;AAM3G,SAAgB,sBAAsB,QAAuC;AAC3E,mBAAkB,OAAO;AACzB,QAAO;EACL,SAAS,OAAO;EAChB,WAAW,OAAO;EAClB,QAAQ,OAAO;EACf,WAAW,OAAO;EAClB,SAAS,OAAO;EAChB,MAAM,OAAO;EACd;;AAGH,SAAS,oBAAoB,QAAqB,SAAwC;AACxF,KAAI,SAAS,cAAc,QAAS,QAAO;AAC3C,KAAI,SAAS,cAAc,aAAc,QAAO;AAChD,QAAO,OAAO,cAAc,MAAM,IAAA;;AAGpC,MAAM,uBAAuB;;AAG7B,SAAS,gBAAgB,OAAuB;AAC9C,QAAO,SAAS,MAAM,GAAG,UAAU,MAAM,GAAG,IAAI,MAAM,KAAK;;;AAI7D,SAAgB,aAAa,QAAiE;CAC5F,MAAM,MAAgB,EAAE;AACxB,MAAK,MAAM,SAAS,CAAC,OAAO,UAAU,OAAO,eAAe,OAAO,SAAS,CAC1E,KAAI,SAAS,MAAM,IAAI,CAAC,IAAI,SAAS,MAAM,CAAE,KAAI,KAAK,MAAM;AAE9D,QAAO;;AAGT,SAAS,aAAa,SAA0B,QAA0B;AACxE,QAAO,OAAO,QAAQ,QAAQ,CAAC,KAAK,CAAC,KAAK,WAAW,GAAG,OAAO,IAAI,IAAI,IAAI,MAAM,GAAG;;AAGtF,SAAS,YAAY,MAAwC;AAC3D,QAAO,OAAO,QAAQ,KAAK,CAAC,KAAK,CAAC,KAAK,WAAW,KAAK,IAAI,IAAI,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;AAqB1E,SAAgB,cAAc,QAAqB,SAAwC;CACzF,MAAM,QAAQ,sBAAsB,OAAO;CAC3C,MAAM,QAAQ,mBAAmB,MAAM;CACvC,MAAM,OAAO,kBAAkB,MAAM;CACrC,MAAM,SAAS,oBAAoB,MAAM;CACzC,MAAM,eAAe,oBAAoB,QAAQ,QAAQ;CACzD,MAAM,YAAY,SAAS,eAAe,YAAY,aAAa,OAAO,EAAE,QAAQ,aAAa,GAAG;CAEpG,MAAM,YACJ,iBAAiB,WACb;EACE;EACA;EACA,GAAG,aAAa,MAAM,OAAO;EAC7B;EACA;EACD,GACD;EAAC,GAAG,aAAa;EAAK,GAAG,aAAa,MAAM,KAAK;EAAE;EAAI;AA4C7D,QA1CwB;EACtB;EACA,aAAa,OAAO,aAAa,KAAK,OAAO,eAAe,KAAK,OAAO,YAAY,KAAK,OAAO,eAAe,KAAK,OAAO,aAAa;EACxI,YAAY,OAAO,UAAU;EAC7B,sBAAsB,OAAO,OAAO,YAAY,OAAO,OAAO,YAAY,OAAO,OAAO,aAAa,OAAO,QAAQ;EACpH;EACA,GAAI,YAAY,CAAC,WAAW,GAAG,GAAG,EAAE;EACpC;EACA,GAAG,aAAa,OAAO,KAAK;EAC5B;EACA;EACA,iBAAiB,OAAO;EACxB;EACA;EACA,6BAA6B;EAC7B;EACA,uBAAuB,OAAO,OAAO;EACrC,GAAG,YAAY,cAAc,OAAO,QAAQ;EAC5C;EACA,uBAAuB,OAAO,OAAO;EACrC,GAAG,YAAY,cAAc,OAAO,QAAQ;EAC5C;EACA,uBAAuB,OAAO,OAAO;EACrC,GAAG,YAAY,cAAc,OAAO,QAAQ;EAC5C;EACA,wBAAwB,OAAO,QAAQ;EACvC,GAAG,YAAY,eAAe,OAAO,SAAS;EAC9C;EACA;EACA,kBAAkB,gBAAgB,OAAO,SAAS,CAAC;EACnD,qBAAqB,gBAAgB,OAAO,eAAe,OAAO,SAAS,CAAC;EAC5E,2BAA2B,OAAO,YAAY,OAAO;EACrD,2BAA2B,OAAO,YAAY,OAAO;EACrD,6BAA6B,OAAO,YAAY,SAAS;EACzD,yBAAyB,OAAO,YAAY,KAAK;EACjD;EACA;EACA;EACA,GAAG;EACH;EACD,CAEY,KAAK,KAAK;;;;;;;;;;;ACxKzB,SAAS,SAAS,GAAW,GAAW,GAAgB;CACtD,MAAM,UAAU,IAAI,KAAK,IAAI,IAAI,IAAI,EAAE,IAAI;CAC3C,MAAM,OAAS,IAAI,MAAO,OAAO,MAAO;CACxC,MAAM,IAAI,UAAU,IAAI,KAAK,IAAK,MAAM,IAAK,EAAE;CAC/C,MAAM,IAAI,IAAI,SAAS;CACvB,IAAI;AACJ,KAAI,MAAM,EAAG,OAAM;EAAC;EAAQ;EAAG;EAAE;UACxB,MAAM,EAAG,OAAM;EAAC;EAAG;EAAQ;EAAE;UAC7B,MAAM,EAAG,OAAM;EAAC;EAAG;EAAQ;EAAE;UAC7B,MAAM,EAAG,OAAM;EAAC;EAAG;EAAG;EAAO;UAC7B,MAAM,EAAG,OAAM;EAAC;EAAG;EAAG;EAAO;KACjC,OAAM;EAAC;EAAQ;EAAG;EAAE;AACzB,QAAO;EAAC,IAAI,KAAK;EAAG,IAAI,KAAK;EAAG,IAAI,KAAK;EAAE;;AAG7C,SAAS,WAAW,OAAwB;CAC1C,MAAM,MAAM,oBAAoB,KAAK,MAAM,MAAM,CAAC;AAClD,KAAI,KAAK;EACP,MAAM,QAAQ,SAAS,IAAI,IAAI,GAAG;AAClC,SAAO;GAAE,SAAS,KAAM;GAAM,SAAS,IAAK;GAAK,QAAQ;GAAI,CAAC,KAAK,YAAY,UAAU,IAAI;;CAE/F,MAAM,UAAU,uCAAuC,KAAK,MAAM,MAAM,CAAC;AACzE,KAAI,QACF,QAAO,SAAS,OAAO,QAAQ,GAAG,EAAE,OAAO,QAAQ,GAAG,GAAG,KAAK,OAAO,QAAQ,GAAG,GAAG,IAAI;AAEzF,OAAM,IAAI,MAAM,oCAAoC,MAAM,+BAA+B;;AAK3F,SAAS,cAAc,SAAyB;AAC9C,QAAO,WAAW,SAAU,UAAU,QAAQ,KAAK,KAAK,UAAU,QAAS,OAAO,IAAI;;;AAIxF,SAAgB,kBAAkB,OAA2B;CAC3D,MAAM,CAAC,GAAG,GAAG,KAAK,WAAW,MAAM;AACnC,QAAO,QAAS,cAAc,EAAE,GAAG,QAAS,cAAc,EAAE,GAAG,QAAS,cAAc,EAAE;;;AAI1F,SAAgB,cAAc,GAAe,GAAuB;CAClE,MAAM,KAAK,kBAAkB,EAAE;CAC/B,MAAM,KAAK,kBAAkB,EAAE;CAC/B,MAAM,SAAS,KAAK,IAAI,IAAI,GAAG,GAAG,QAAS,KAAK,IAAI,IAAI,GAAG,GAAG;AAC9D,QAAO,KAAK,MAAM,QAAQ,IAAI,GAAG;;;AAInC,SAAgB,aAAa,OAA+B;CAC1D,MAAM,UAAU,SAAS;CACzB,MAAM,KAAK,SAAS;CACpB,MAAM,MAAM,SAAS;AACrB,QAAO;EAAE;EAAI;EAAS;EAAK,OAAO,MAAM,QAAQ,KAAK,OAAO,UAAU,aAAa;EAAQ;;AAG7F,MAAM,cAA6C;CACjD,KAAK;CACL,IAAI;CACJ,YAAY;CACZ,MAAM;CACP;;AAGD,SAAgB,mBAAmB,OAA8B;AAC/D,QAAO,YAAY;;;;;;AAYrB,SAAgB,gBACd,QACA,QACiB;CACjB,MAAM,QAAQ,OAAO,SAAS;AAC9B,QAAO;EAAE;EAAO,MAAM,GAAG,QAAQ,UAAU,QAAQ,GAAG,OAAO;EAAK;;;AAepE,MAAM,WAA+B;CACnC;EAAE,YAAY;EAAsB,YAAY;EAAW,MAAM;EAAkB,OAAO;EAA4C;CACtI;EAAE,YAAY;EAAwB,YAAY;EAAa,MAAM;EAAkB,OAAO;EAAgD;CAC9I;EAAE,YAAY;EAA2B,YAAY;EAAgB,MAAM;EAAkB,OAAO;EAA+B;CACnI;EAAE,YAAY;EAAwB,YAAY;EAAa,MAAM;EAAkB,OAAO;EAA4B;CAC1H;EAAE,YAAY;EAAsB,YAAY;EAAW,MAAM;EAAkB,OAAO;EAAmC;CAC7H;EAAE,YAAY;EAA0B,YAAY;EAAe,MAAM;EAAkB,OAAO;EAAwC;CAC1I;EAAE,YAAY;EAAqB,YAAY;EAAU,MAAM;EAAkB,OAAO;EAAwD;CAChJ;EAAE,YAAY;EAAoB,YAAY;EAAS,MAAM;EAAkB,OAAO;EAAgC;CACtH;EAAE,YAAY;EAAmB,YAAY;EAAQ,MAAM;EAAkB,OAAO;EAAsC;CAC1H;EAAE,YAAY;EAAsB,YAAY;EAAW,MAAM;EAAkB,OAAO;EAAgD;CAC1I;EAAE,YAAY;EAAc,YAAY;EAAc,MAAM;EAAQ,OAAO;EAAoC;CAC/G;EAAE,YAAY;EAAc,YAAY;EAAQ,MAAM;EAAQ,OAAO;EAAuB;CAC5F;EAAE,YAAY;EAAoB,YAAY;EAAc,MAAM;EAAQ,OAAO;EAA0C;CAC3H;EAAE,YAAY;EAAoB,YAAY;EAAQ,MAAM;EAAQ,OAAO;EAA6B;CACxG;EAAE,YAAY;EAAqB,YAAY;EAAc,MAAM;EAAQ,OAAO;EAA8D;CAChJ;EAAE,YAAY;EAAqB,YAAY;EAAQ,MAAM;EAAQ,OAAO;EAAiD;CAC7H;EAAE,YAAY;EAAW,YAAY;EAAc,MAAM;EAAQ,OAAO;EAA+C;CACvH;EAAE,YAAY;EAAa,YAAY;EAAc,MAAM;EAAQ,OAAO;EAAoD;CAC9H;EAAE,YAAY;EAAQ,YAAY;EAAc,MAAM;EAAY,OAAO;EAAqC;CAC/G;AAED,SAAS,WAAW,MAAoB,QAAwB;AAC9D,SAAQ,MAAR;EACE,KAAK,WACH,QAAO;EACT,KAAK,aACH,QAAO,UAAU,IAAI,MAAM;EAC7B,QACE,QAAO;;;AAIb,SAAS,OAAO,SAA0B,SAAkC;CAC1E,MAAM,aAAa,QAAQ,QAAQ;CACnC,MAAM,aAAa,QAAQ,QAAQ;CACnC,MAAM,QAAQ,cAAc,YAAY,WAAW;AACnD,QAAO;EAAE;EAAO,OAAO,aAAa,MAAM,CAAC;EAAO;EAAY;EAAY;;;;;;;;;;;;AAa5E,SAAgB,WAAW,QAA4B,UAA6B,EAAE,EAAmB;CACvG,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,QAAQ,sBAAsB,OAAO;CAC3C,MAAM,QAAQ,mBAAmB,MAAM;CACvC,MAAM,OAAO,kBAAkB,MAAM;AAErC,QAAO,SAAS,KAAK,YAAY;EAC/B,MAAM,cAAc,OAAO,OAAO,QAAQ;EAC1C,MAAM,aAAa,OAAO,MAAM,QAAQ;EACxC,MAAM,YAAY,WAAW,QAAQ,MAAM,OAAO;AAClD,SAAO;GACL,IAAI,GAAG,QAAQ,WAAW,MAAM,QAAQ;GACxC,OAAO,QAAQ;GACf,MAAM,QAAQ;GACd,OAAO;GACP,MAAM;GACN,QAAQ;GACR,aAAa,YAAY,SAAS,aAAa,WAAW,SAAS;GACpE;GACD;;;;AC/NJ,MAAa,cAAc;CACzB,WAAW;EACT,OAAO;GAAE,OAAO;GAAS,MAAM;GAAyC;EACxE,MAAM;GAAE,OAAO;GAAQ,MAAM;GAAwC;EACrE,MAAM;GAAE,OAAO;GAAQ,MAAM;GAAqC;EAClE,SAAS;GAAE,OAAO;GAAW,MAAM;GAA6B;EAChE,OAAO;GAAE,OAAO;GAAS,MAAM;GAA4C;EAC5E;CACD,QAAQ;EACN,OAAO;GAAE,OAAO;GAAS,MAAM;GAAwB;EACvD,QAAQ;GAAE,OAAO;GAAU,MAAM;GAAwB;EACzD,SAAS;GAAE,OAAO;GAAW,MAAM;GAA4B;EAC/D,MAAM;GAAE,OAAO;GAAQ,MAAM;GAAuB;EACrD;CACD,QAAQ;EACN,MAAM;GAAE,OAAO;GAAQ,MAAM;GAA8B;EAC3D,QAAQ;GAAE,OAAO;GAAU,MAAM;GAAsC;EACvE,UAAU;GAAE,OAAO;GAAY,MAAM;GAA6B;EACnE;CACD,QAAQ;EACN,QAAQ;GAAE,OAAO;GAAU,MAAM;GAA6B;EAC9D,QAAQ;GAAE,OAAO;GAAU,MAAM;GAAsC;EACvE,SAAS;GAAE,OAAO;GAAW,MAAM;GAAgC;EACpE;CACD,SAAS;EACP,SAAS;GAAE,OAAO;GAAW,MAAM;GAAqC;EACxE,SAAS;GAAE,OAAO;GAAW,MAAM;GAAoB;EACvD,UAAU;GAAE,OAAO;GAAY,MAAM;GAAuC;EAC7E;CACD,cAAc;EACZ,QAAQ;GAAE,OAAO;GAAU,MAAM;GAAsC;EACvE,OAAO;GAAE,OAAO;GAAS,MAAM;GAA8B;EAC7D,MAAM;GAAE,OAAO;GAAQ,MAAM;GAA6B;EAC3D;CACF"}
|
package/package.json
CHANGED