okchroma 0.1.0 → 0.1.2
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-lib/index.cjs +88 -16
- package/dist-lib/index.mjs +88 -16
- package/dist-lib/types/engine/cssRender.d.ts +16 -0
- package/dist-lib/types/engine/tokenNames.d.ts +25 -0
- package/dist-lib/types/index.d.ts +3 -2
- package/package.json +3 -2
- package/tokens/semantic.css +204 -0
package/dist-lib/index.cjs
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
CSS_FAMILY: () => CSS_FAMILY,
|
|
23
24
|
DEFAULT_LINK_HEX: () => DEFAULT_LINK_HEX,
|
|
24
25
|
EXT_KEY: () => EXT_KEY,
|
|
25
26
|
INK_0: () => INK_0,
|
|
@@ -29,7 +30,9 @@ __export(index_exports, {
|
|
|
29
30
|
PAPER_100: () => PAPER_100,
|
|
30
31
|
RESOLVER_ID: () => RESOLVER_ID,
|
|
31
32
|
SCALE_STOP_COUNT: () => SCALE_STOP_COUNT,
|
|
33
|
+
SCRIM_ALPHA: () => SCRIM_ALPHA,
|
|
32
34
|
SECONDARY_DISTINCT_DELTA_E: () => SECONDARY_DISTINCT_DELTA_E,
|
|
35
|
+
SHADOW_ALPHAS: () => SHADOW_ALPHAS,
|
|
33
36
|
SIGNALS: () => SIGNALS2,
|
|
34
37
|
SIGNAL_EMIT_NAME: () => SIGNAL_EMIT_NAME,
|
|
35
38
|
SIGNAL_SCALES: () => SIGNAL_SCALES,
|
|
@@ -41,16 +44,21 @@ __export(index_exports, {
|
|
|
41
44
|
STAMP_STATE_LEAVES: () => STAMP_STATE_LEAVES,
|
|
42
45
|
SUBTLE_PASTEL_K: () => SUBTLE_PASTEL_K,
|
|
43
46
|
SUBTLE_TINT_MULT: () => SUBTLE_TINT_MULT,
|
|
47
|
+
SURFACE_PLANE_LAW: () => SURFACE_PLANE_LAW,
|
|
48
|
+
SYSTEM_LEAF: () => SYSTEM_LEAF,
|
|
44
49
|
brandCss: () => brandCss,
|
|
45
50
|
checkAllCollisions: () => checkAllCollisions,
|
|
46
51
|
checkCollision: () => checkCollision,
|
|
47
52
|
checkHueCollision: () => checkHueCollision,
|
|
48
53
|
classifyArchetype: () => classifyArchetype,
|
|
54
|
+
ctaBorderRung: () => ctaBorderRung,
|
|
55
|
+
ctaNeedsBorder: () => ctaNeedsBorder,
|
|
49
56
|
emitDtcgRamp: () => emitDtcgRamp,
|
|
50
57
|
generateNeutralScale: () => generateNeutralScale,
|
|
51
58
|
generateScale: () => generateScale,
|
|
52
59
|
generateSubtleSecondary: () => generateSubtleSecondary,
|
|
53
60
|
neutralCss: () => neutralCss,
|
|
61
|
+
pageStopFor: () => pageStopFor,
|
|
54
62
|
parseToken: () => parseToken,
|
|
55
63
|
resolveBrand: () => resolveBrand,
|
|
56
64
|
resolveDtcgRamp: () => resolveDtcgRamp,
|
|
@@ -90,9 +98,11 @@ function stateStepL(restL, _mode, k) {
|
|
|
90
98
|
return k * STATE_HOVER_K;
|
|
91
99
|
}
|
|
92
100
|
var OVERRIDE_LIGHT_BELOW = ARCHETYPES.find((a) => a.name === "rich").min;
|
|
101
|
+
var OVERRIDE_DARK_ABOVE = ARCHETYPES.find((a) => a.name === "light").min;
|
|
93
102
|
function stateFillL(restL, mode, k) {
|
|
94
103
|
const natural = mode === "dark" ? 1 : -1;
|
|
95
|
-
const
|
|
104
|
+
const overridden = mode === "light" ? restL < OVERRIDE_LIGHT_BELOW : restL > OVERRIDE_DARK_ABOVE;
|
|
105
|
+
const preferred = overridden ? -natural : natural;
|
|
96
106
|
const fits = (d) => {
|
|
97
107
|
const p = restL + d * stateStepL(restL, mode, 2);
|
|
98
108
|
return p >= STATE_L_MIN && p <= STATE_L_MAX;
|
|
@@ -2619,7 +2629,7 @@ function generateNeutralScale(brandH, level = "default", contrastProfile) {
|
|
|
2619
2629
|
scale.ctaHoverDark = nState(10, "dark", scale.ctaDark, 1);
|
|
2620
2630
|
scale.ctaPressedDark = nState(11, "dark", scale.ctaDark, 2);
|
|
2621
2631
|
const onEnforce = contrastProfile !== "apca";
|
|
2622
|
-
const onFloor =
|
|
2632
|
+
const onFloor = 4.5;
|
|
2623
2633
|
scale.onFillTextIsWhite = onTextIsWhite(apcaY(scale.cta.r, scale.cta.g, scale.cta.b), scale.cta.L, scale.cta.C, scale.cta.H, onEnforce, onFloor);
|
|
2624
2634
|
scale.onFillTextIsWhiteDark = onTextIsWhite(apcaY(scale.ctaDark.r, scale.ctaDark.g, scale.ctaDark.b), scale.ctaDark.L, scale.ctaDark.C, scale.ctaDark.H, onEnforce, onFloor);
|
|
2625
2635
|
return scale;
|
|
@@ -2650,7 +2660,7 @@ function generateSubtleSecondary(hex, opts) {
|
|
|
2650
2660
|
scale.ctaHoverDark = st(10, "dark", scale.ctaDark, 1);
|
|
2651
2661
|
scale.ctaPressedDark = st(11, "dark", scale.ctaDark, 2);
|
|
2652
2662
|
const onEnforce = opts?.contrastProfile !== "apca";
|
|
2653
|
-
const onFloor =
|
|
2663
|
+
const onFloor = 4.5;
|
|
2654
2664
|
scale.onFillTextIsWhite = onTextIsWhite(apcaY(scale.cta.r, scale.cta.g, scale.cta.b), scale.cta.L, scale.cta.C, scale.cta.H, onEnforce, onFloor);
|
|
2655
2665
|
scale.onFillTextIsWhiteDark = onTextIsWhite(apcaY(scale.ctaDark.r, scale.ctaDark.g, scale.ctaDark.b), scale.ctaDark.L, scale.ctaDark.C, scale.ctaDark.H, onEnforce, onFloor);
|
|
2656
2666
|
return scale;
|
|
@@ -2695,7 +2705,7 @@ var COLOR_WORD = {
|
|
|
2695
2705
|
[FAMILY.info]: " (blue)"
|
|
2696
2706
|
};
|
|
2697
2707
|
var PAPER = { req: "backgrounds, inverted text", theming: (f) => TINT[f], collides: true };
|
|
2698
|
-
var WASH = { req: "subtle
|
|
2708
|
+
var WASH = { req: "subtle interactive states, decorative borders, illos, signal hierarchy", theming: (f) => TINT[f], collides: true };
|
|
2699
2709
|
var solved = (f) => `${TINT[f]}; re-solved to clear its floor`;
|
|
2700
2710
|
var OVERLAY = {
|
|
2701
2711
|
req: "translucent backgrounds that hold their reading on any paper",
|
|
@@ -2713,12 +2723,15 @@ var SCALE = {
|
|
|
2713
2723
|
"wash-89": WASH,
|
|
2714
2724
|
"wash-85": WASH,
|
|
2715
2725
|
"wash-80": WASH,
|
|
2726
|
+
// ("icons" KEPT through the 2026-08-28 on-flood strip (owner): an "icon" query
|
|
2727
|
+
// landing on the mark rows is worth its ic-ON-s noise — the one surviving body carrier)
|
|
2716
2728
|
"mark-74": { req: "focus rings, icons, large text", contrast: AA_LARGE, theming: solved, collides: true },
|
|
2717
2729
|
"lead-53": { req: "regular text, inverted backgrounds", contrast: AA_BODY, theming: solved, collides: true },
|
|
2718
2730
|
"ink-42": { req: "regular text, inverted backgrounds", contrast: AA_BODY, theming: solved, collides: true },
|
|
2719
2731
|
// ("high-emphasis" reworded 2026-08-12: the surface planes took low/high as label
|
|
2720
|
-
// words, and a body carrying either floods that token's picker search — the C50 law
|
|
2721
|
-
"
|
|
2732
|
+
// words, and a body carrying either floods that token's picker search — the C50 law;
|
|
2733
|
+
// "strong-emphasis" reworded 2026-08-28: str-ON-g fed the "on" flood)
|
|
2734
|
+
"ink-30": { req: "heavy-emphasis text, inverted backgrounds", contrast: AAA_BODY, theming: solved, collides: true },
|
|
2722
2735
|
// the stamp family (cta words → solid 2026-08-18, solid → stamp 2026-08-27). "CTA" stays in
|
|
2723
2736
|
// these bodies on purpose: it stopped being a token label, so it floods nothing,
|
|
2724
2737
|
// and a designer's "cta" query still lands on these rows.
|
|
@@ -2729,17 +2742,17 @@ var SCALE = {
|
|
|
2729
2742
|
// ("fill" reworded out 2026-08-18: fill became a label word and is foreign here)
|
|
2730
2743
|
"stamp/on": { req: "text over the CTA color", contrast: `${AA_BODY} over its CTA`, theming: (f) => `whichever pole passes; quiet CTAs take the soft pole${COLOR_WORD[f]}` }
|
|
2731
2744
|
};
|
|
2732
|
-
var ABS = { req: "
|
|
2733
|
-
var OFFSET = { req: "min APCA visibility", theming: "offsets
|
|
2745
|
+
var ABS = { req: "extreme poles for CTAs, aliased global endpoints" };
|
|
2746
|
+
var OFFSET = { req: "min APCA visibility", theming: "offsets CTAs in themes where they sit close to the page" };
|
|
2734
2747
|
var SHADOW = { req: "drop shadows" };
|
|
2735
2748
|
var PLANE = (req) => ({ req, theming: "aliased to the gray ramp" });
|
|
2736
2749
|
var LINK = (state, contrast) => ({
|
|
2737
2750
|
req: "links" + state,
|
|
2738
2751
|
contrast,
|
|
2739
|
-
theming: "rides the theme\u2019s
|
|
2752
|
+
theming: "rides the theme\u2019s link color; custom seed re-solves; overridable per theme"
|
|
2740
2753
|
});
|
|
2741
2754
|
var LINK_INVERSE = (state, contrast) => ({
|
|
2742
|
-
req: "links
|
|
2755
|
+
req: "links over inverted backgrounds" + state,
|
|
2743
2756
|
contrast,
|
|
2744
2757
|
theming: "same seed as the link, re-solved for inverted backgrounds; overridable per theme"
|
|
2745
2758
|
});
|
|
@@ -2750,19 +2763,23 @@ var SYSTEM = {
|
|
|
2750
2763
|
// the anchor is engine-resolved and rides the neutral in BOTH plugins now —
|
|
2751
2764
|
// NEUTRAL_ONLY above. Old files' static rows orphan unwritten.)
|
|
2752
2765
|
"system/abs-primary": { req: "identity seed reference", theming: "the theme\u2019s own input, as given" },
|
|
2753
|
-
"
|
|
2766
|
+
// ("companion" reworded 2026-08-28: compani-ON fed the "on" flood)
|
|
2767
|
+
"system/abs-alt": { req: "identity seed reference", theming: "the theme\u2019s paired input, as given" },
|
|
2754
2768
|
"system/alpha/transparent": { req: "aliased off-states" },
|
|
2755
2769
|
// ("dimming" reworded 2026-08-18: the surface planes took dim as a label word)
|
|
2756
2770
|
"system/alpha/abs-black-060": { req: "veils the page behind modals" },
|
|
2757
|
-
// ("fills" reworded 2026-08-18: fill became a label word and is foreign here
|
|
2758
|
-
"
|
|
2771
|
+
// ("fills" reworded 2026-08-18: fill became a label word and is foreign here;
|
|
2772
|
+
// "on-color" reworded 2026-08-28: the bare on fed the "on" flood)
|
|
2773
|
+
"system/alpha/ink": { req: "soft text pole for quiet CTAs" },
|
|
2759
2774
|
"system/alpha/006": OFFSET,
|
|
2760
2775
|
"system/alpha/008": OFFSET,
|
|
2761
2776
|
"system/alpha/016": OFFSET,
|
|
2762
2777
|
"system/alpha/shadow-04": SHADOW,
|
|
2763
2778
|
"system/alpha/shadow-08": SHADOW,
|
|
2764
2779
|
"system/alpha/shadow-12": SHADOW,
|
|
2765
|
-
"
|
|
2780
|
+
// ("elevation" dropped 2026-08-28: elevati-ON fed the "on" flood; the sibling
|
|
2781
|
+
// planes never carried the word)
|
|
2782
|
+
"system/surface/dim": PLANE("recessed plane"),
|
|
2766
2783
|
"system/surface/low": PLANE("resting page plane"),
|
|
2767
2784
|
"system/surface/mid": PLANE("raised plane \u2014 cards, menus"),
|
|
2768
2785
|
// ("overlays" reworded 2026-08-13: paper-overlay took the word as a label — the C50 law)
|
|
@@ -3393,6 +3410,33 @@ var STAMP_LEAF = {
|
|
|
3393
3410
|
EDGE: STAMP_STATE_LEAVES[STAMP_EDGE],
|
|
3394
3411
|
ON: STAMP_STATE_LEAVES[STAMP_ON]
|
|
3395
3412
|
};
|
|
3413
|
+
var SYSTEM_LEAF = {
|
|
3414
|
+
ABS_BLACK: "system/abs-black",
|
|
3415
|
+
ABS_WHITE: "system/abs-white",
|
|
3416
|
+
SURFACE: {
|
|
3417
|
+
DIM: "system/surface/dim",
|
|
3418
|
+
LOW: "system/surface/low",
|
|
3419
|
+
MID: "system/surface/mid",
|
|
3420
|
+
HIGH: "system/surface/high"
|
|
3421
|
+
},
|
|
3422
|
+
ALPHA: {
|
|
3423
|
+
TRANSPARENT: "system/alpha/transparent",
|
|
3424
|
+
SCRIM: "system/alpha/abs-black-060",
|
|
3425
|
+
INK: "system/alpha/ink",
|
|
3426
|
+
OFFSET_006: "system/alpha/006",
|
|
3427
|
+
OFFSET_008: "system/alpha/008",
|
|
3428
|
+
OFFSET_016: "system/alpha/016",
|
|
3429
|
+
SHADOW_04: "system/alpha/shadow-04",
|
|
3430
|
+
SHADOW_08: "system/alpha/shadow-08",
|
|
3431
|
+
SHADOW_12: "system/alpha/shadow-12"
|
|
3432
|
+
}
|
|
3433
|
+
};
|
|
3434
|
+
var SURFACE_PLANE_LAW = {
|
|
3435
|
+
[SYSTEM_LEAF.SURFACE.DIM]: { light: SHARED_NAMES[3], dark: PAPER_100 },
|
|
3436
|
+
[SYSTEM_LEAF.SURFACE.LOW]: { light: SHARED_NAMES[2], dark: SHARED_NAMES[1] },
|
|
3437
|
+
[SYSTEM_LEAF.SURFACE.MID]: { light: SHARED_NAMES[1], dark: SHARED_NAMES[2] },
|
|
3438
|
+
[SYSTEM_LEAF.SURFACE.HIGH]: { light: PAPER_100, dark: SHARED_NAMES[3] }
|
|
3439
|
+
};
|
|
3396
3440
|
var TOKEN_ORDER = [
|
|
3397
3441
|
...Object.values(SHARED_NAMES),
|
|
3398
3442
|
STAMP_FILL,
|
|
@@ -3438,6 +3482,12 @@ var OFFSET_ALPHAS = { 6: 0.06, 8: 0.08, 16: 0.16 };
|
|
|
3438
3482
|
var ctaBorderRung = (prefix) => prefix === CSS_NEUTRAL ? 8 : prefix === CSS_SECONDARY ? 6 : 16;
|
|
3439
3483
|
var offsetLeafName = (rung) => String(rung).padStart(3, "0");
|
|
3440
3484
|
var offsetVarName = (rung) => `--alpha-${offsetLeafName(rung)}`;
|
|
3485
|
+
var SHADOW_ALPHAS = {
|
|
3486
|
+
4: { light: 0.04, dark: 0.32 },
|
|
3487
|
+
8: { light: 0.08, dark: 0.48 },
|
|
3488
|
+
12: { light: 0.12, dark: 0.64 }
|
|
3489
|
+
};
|
|
3490
|
+
var SCRIM_ALPHA = 0.6;
|
|
3441
3491
|
var TRANSPARENT_VAR = "--alpha-transparent";
|
|
3442
3492
|
var offsetRgba = (rung, mode) => mode === "light" ? `rgba(0, 0, 0, ${OFFSET_ALPHAS[rung]})` : `rgba(255, 255, 255, ${OFFSET_ALPHAS[rung]})`;
|
|
3443
3493
|
var alphaRootVars = (mode) => [
|
|
@@ -3627,7 +3677,7 @@ function brandCss(slug, displayName, r, secondary, noteSuffix = "", neutralLevel
|
|
|
3627
3677
|
};
|
|
3628
3678
|
const softOnCta = (mode) => {
|
|
3629
3679
|
if (!secondary || secondaryStyle === "outline") return [];
|
|
3630
|
-
if (
|
|
3680
|
+
if (!softOnCtaPasses(secondary, mode)) return [];
|
|
3631
3681
|
const white = mode === "light" ? secondary.onFillTextIsWhite : secondary.onFillTextIsWhiteDark;
|
|
3632
3682
|
return [` --${CSS_SECONDARY}-stamp-on: rgba(${white ? "255, 255, 255" : "0, 0, 0"}, ${SOFT_ON_CTA_ALPHA[mode]});`];
|
|
3633
3683
|
};
|
|
@@ -3820,7 +3870,7 @@ function themeToFigma(r, input) {
|
|
|
3820
3870
|
});
|
|
3821
3871
|
};
|
|
3822
3872
|
softOnCta(neutralGroup, mode === "light" ? nScale.onFillTextIsWhite : nScale.onFillTextIsWhiteDark);
|
|
3823
|
-
if (input.secondary && input.secondaryStyle !== "outline" &&
|
|
3873
|
+
if (input.secondary && input.secondaryStyle !== "outline" && softOnCtaPasses(input.secondary, mode))
|
|
3824
3874
|
softOnCta(secondaryGroup, mode === "light" ? secondaryOnFillLight : secondaryOnFillDark);
|
|
3825
3875
|
const brandGroup = rampGroup(scale[mode], mode === "light" ? scale.onFillTextIsWhite : scale.onFillTextIsWhiteDark, brandExtra(scale, mode, CSS_FAMILY.brandPrimary));
|
|
3826
3876
|
const esc = input.ctaEscape ? escapeCtaFamily(nScale, mode, input.contrastProfile) : null;
|
|
@@ -3855,6 +3905,28 @@ function themeToFigma(r, input) {
|
|
|
3855
3905
|
ctaFamily(sig.scale, mode, sig.name)
|
|
3856
3906
|
);
|
|
3857
3907
|
}
|
|
3908
|
+
const pole = (white, alpha) => {
|
|
3909
|
+
const c = white ? 1 : 0;
|
|
3910
|
+
return {
|
|
3911
|
+
$type: "color",
|
|
3912
|
+
$value: { colorSpace: "srgb", components: [c, c, c], alpha, hex: white ? "#ffffff" : "#000000" }
|
|
3913
|
+
};
|
|
3914
|
+
};
|
|
3915
|
+
putLeaf(g2, SYSTEM_LEAF.ABS_BLACK, colorFromHex(false));
|
|
3916
|
+
putLeaf(g2, SYSTEM_LEAF.ABS_WHITE, colorFromHex(true));
|
|
3917
|
+
for (const [path, law] of Object.entries(SURFACE_PLANE_LAW)) {
|
|
3918
|
+
const tok = neutralGroup[law[mode]];
|
|
3919
|
+
if (tok && "$type" in tok) putLeaf(g2, path, tok);
|
|
3920
|
+
}
|
|
3921
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.TRANSPARENT, pole(true, 0));
|
|
3922
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.SCRIM, pole(false, SCRIM_ALPHA));
|
|
3923
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.INK, pole(mode === "dark", SOFT_ON_CTA_ALPHA[mode]));
|
|
3924
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.OFFSET_006, OFFSET_TOKEN(6, mode));
|
|
3925
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.OFFSET_008, OFFSET_TOKEN(8, mode));
|
|
3926
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.OFFSET_016, OFFSET_TOKEN(16, mode));
|
|
3927
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.SHADOW_04, pole(false, SHADOW_ALPHAS[4][mode]));
|
|
3928
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.SHADOW_08, pole(false, SHADOW_ALPHAS[8][mode]));
|
|
3929
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.SHADOW_12, pole(false, SHADOW_ALPHAS[12][mode]));
|
|
3858
3930
|
return g2;
|
|
3859
3931
|
};
|
|
3860
3932
|
return { light: build("light"), dark: build("dark") };
|
package/dist-lib/index.mjs
CHANGED
|
@@ -20,9 +20,11 @@ function stateStepL(restL, _mode, k) {
|
|
|
20
20
|
return k * STATE_HOVER_K;
|
|
21
21
|
}
|
|
22
22
|
var OVERRIDE_LIGHT_BELOW = ARCHETYPES.find((a) => a.name === "rich").min;
|
|
23
|
+
var OVERRIDE_DARK_ABOVE = ARCHETYPES.find((a) => a.name === "light").min;
|
|
23
24
|
function stateFillL(restL, mode, k) {
|
|
24
25
|
const natural = mode === "dark" ? 1 : -1;
|
|
25
|
-
const
|
|
26
|
+
const overridden = mode === "light" ? restL < OVERRIDE_LIGHT_BELOW : restL > OVERRIDE_DARK_ABOVE;
|
|
27
|
+
const preferred = overridden ? -natural : natural;
|
|
26
28
|
const fits = (d) => {
|
|
27
29
|
const p = restL + d * stateStepL(restL, mode, 2);
|
|
28
30
|
return p >= STATE_L_MIN && p <= STATE_L_MAX;
|
|
@@ -2549,7 +2551,7 @@ function generateNeutralScale(brandH, level = "default", contrastProfile) {
|
|
|
2549
2551
|
scale.ctaHoverDark = nState(10, "dark", scale.ctaDark, 1);
|
|
2550
2552
|
scale.ctaPressedDark = nState(11, "dark", scale.ctaDark, 2);
|
|
2551
2553
|
const onEnforce = contrastProfile !== "apca";
|
|
2552
|
-
const onFloor =
|
|
2554
|
+
const onFloor = 4.5;
|
|
2553
2555
|
scale.onFillTextIsWhite = onTextIsWhite(apcaY(scale.cta.r, scale.cta.g, scale.cta.b), scale.cta.L, scale.cta.C, scale.cta.H, onEnforce, onFloor);
|
|
2554
2556
|
scale.onFillTextIsWhiteDark = onTextIsWhite(apcaY(scale.ctaDark.r, scale.ctaDark.g, scale.ctaDark.b), scale.ctaDark.L, scale.ctaDark.C, scale.ctaDark.H, onEnforce, onFloor);
|
|
2555
2557
|
return scale;
|
|
@@ -2580,7 +2582,7 @@ function generateSubtleSecondary(hex, opts) {
|
|
|
2580
2582
|
scale.ctaHoverDark = st(10, "dark", scale.ctaDark, 1);
|
|
2581
2583
|
scale.ctaPressedDark = st(11, "dark", scale.ctaDark, 2);
|
|
2582
2584
|
const onEnforce = opts?.contrastProfile !== "apca";
|
|
2583
|
-
const onFloor =
|
|
2585
|
+
const onFloor = 4.5;
|
|
2584
2586
|
scale.onFillTextIsWhite = onTextIsWhite(apcaY(scale.cta.r, scale.cta.g, scale.cta.b), scale.cta.L, scale.cta.C, scale.cta.H, onEnforce, onFloor);
|
|
2585
2587
|
scale.onFillTextIsWhiteDark = onTextIsWhite(apcaY(scale.ctaDark.r, scale.ctaDark.g, scale.ctaDark.b), scale.ctaDark.L, scale.ctaDark.C, scale.ctaDark.H, onEnforce, onFloor);
|
|
2586
2588
|
return scale;
|
|
@@ -2625,7 +2627,7 @@ var COLOR_WORD = {
|
|
|
2625
2627
|
[FAMILY.info]: " (blue)"
|
|
2626
2628
|
};
|
|
2627
2629
|
var PAPER = { req: "backgrounds, inverted text", theming: (f) => TINT[f], collides: true };
|
|
2628
|
-
var WASH = { req: "subtle
|
|
2630
|
+
var WASH = { req: "subtle interactive states, decorative borders, illos, signal hierarchy", theming: (f) => TINT[f], collides: true };
|
|
2629
2631
|
var solved = (f) => `${TINT[f]}; re-solved to clear its floor`;
|
|
2630
2632
|
var OVERLAY = {
|
|
2631
2633
|
req: "translucent backgrounds that hold their reading on any paper",
|
|
@@ -2643,12 +2645,15 @@ var SCALE = {
|
|
|
2643
2645
|
"wash-89": WASH,
|
|
2644
2646
|
"wash-85": WASH,
|
|
2645
2647
|
"wash-80": WASH,
|
|
2648
|
+
// ("icons" KEPT through the 2026-08-28 on-flood strip (owner): an "icon" query
|
|
2649
|
+
// landing on the mark rows is worth its ic-ON-s noise — the one surviving body carrier)
|
|
2646
2650
|
"mark-74": { req: "focus rings, icons, large text", contrast: AA_LARGE, theming: solved, collides: true },
|
|
2647
2651
|
"lead-53": { req: "regular text, inverted backgrounds", contrast: AA_BODY, theming: solved, collides: true },
|
|
2648
2652
|
"ink-42": { req: "regular text, inverted backgrounds", contrast: AA_BODY, theming: solved, collides: true },
|
|
2649
2653
|
// ("high-emphasis" reworded 2026-08-12: the surface planes took low/high as label
|
|
2650
|
-
// words, and a body carrying either floods that token's picker search — the C50 law
|
|
2651
|
-
"
|
|
2654
|
+
// words, and a body carrying either floods that token's picker search — the C50 law;
|
|
2655
|
+
// "strong-emphasis" reworded 2026-08-28: str-ON-g fed the "on" flood)
|
|
2656
|
+
"ink-30": { req: "heavy-emphasis text, inverted backgrounds", contrast: AAA_BODY, theming: solved, collides: true },
|
|
2652
2657
|
// the stamp family (cta words → solid 2026-08-18, solid → stamp 2026-08-27). "CTA" stays in
|
|
2653
2658
|
// these bodies on purpose: it stopped being a token label, so it floods nothing,
|
|
2654
2659
|
// and a designer's "cta" query still lands on these rows.
|
|
@@ -2659,17 +2664,17 @@ var SCALE = {
|
|
|
2659
2664
|
// ("fill" reworded out 2026-08-18: fill became a label word and is foreign here)
|
|
2660
2665
|
"stamp/on": { req: "text over the CTA color", contrast: `${AA_BODY} over its CTA`, theming: (f) => `whichever pole passes; quiet CTAs take the soft pole${COLOR_WORD[f]}` }
|
|
2661
2666
|
};
|
|
2662
|
-
var ABS = { req: "
|
|
2663
|
-
var OFFSET = { req: "min APCA visibility", theming: "offsets
|
|
2667
|
+
var ABS = { req: "extreme poles for CTAs, aliased global endpoints" };
|
|
2668
|
+
var OFFSET = { req: "min APCA visibility", theming: "offsets CTAs in themes where they sit close to the page" };
|
|
2664
2669
|
var SHADOW = { req: "drop shadows" };
|
|
2665
2670
|
var PLANE = (req) => ({ req, theming: "aliased to the gray ramp" });
|
|
2666
2671
|
var LINK = (state, contrast) => ({
|
|
2667
2672
|
req: "links" + state,
|
|
2668
2673
|
contrast,
|
|
2669
|
-
theming: "rides the theme\u2019s
|
|
2674
|
+
theming: "rides the theme\u2019s link color; custom seed re-solves; overridable per theme"
|
|
2670
2675
|
});
|
|
2671
2676
|
var LINK_INVERSE = (state, contrast) => ({
|
|
2672
|
-
req: "links
|
|
2677
|
+
req: "links over inverted backgrounds" + state,
|
|
2673
2678
|
contrast,
|
|
2674
2679
|
theming: "same seed as the link, re-solved for inverted backgrounds; overridable per theme"
|
|
2675
2680
|
});
|
|
@@ -2680,19 +2685,23 @@ var SYSTEM = {
|
|
|
2680
2685
|
// the anchor is engine-resolved and rides the neutral in BOTH plugins now —
|
|
2681
2686
|
// NEUTRAL_ONLY above. Old files' static rows orphan unwritten.)
|
|
2682
2687
|
"system/abs-primary": { req: "identity seed reference", theming: "the theme\u2019s own input, as given" },
|
|
2683
|
-
"
|
|
2688
|
+
// ("companion" reworded 2026-08-28: compani-ON fed the "on" flood)
|
|
2689
|
+
"system/abs-alt": { req: "identity seed reference", theming: "the theme\u2019s paired input, as given" },
|
|
2684
2690
|
"system/alpha/transparent": { req: "aliased off-states" },
|
|
2685
2691
|
// ("dimming" reworded 2026-08-18: the surface planes took dim as a label word)
|
|
2686
2692
|
"system/alpha/abs-black-060": { req: "veils the page behind modals" },
|
|
2687
|
-
// ("fills" reworded 2026-08-18: fill became a label word and is foreign here
|
|
2688
|
-
"
|
|
2693
|
+
// ("fills" reworded 2026-08-18: fill became a label word and is foreign here;
|
|
2694
|
+
// "on-color" reworded 2026-08-28: the bare on fed the "on" flood)
|
|
2695
|
+
"system/alpha/ink": { req: "soft text pole for quiet CTAs" },
|
|
2689
2696
|
"system/alpha/006": OFFSET,
|
|
2690
2697
|
"system/alpha/008": OFFSET,
|
|
2691
2698
|
"system/alpha/016": OFFSET,
|
|
2692
2699
|
"system/alpha/shadow-04": SHADOW,
|
|
2693
2700
|
"system/alpha/shadow-08": SHADOW,
|
|
2694
2701
|
"system/alpha/shadow-12": SHADOW,
|
|
2695
|
-
"
|
|
2702
|
+
// ("elevation" dropped 2026-08-28: elevati-ON fed the "on" flood; the sibling
|
|
2703
|
+
// planes never carried the word)
|
|
2704
|
+
"system/surface/dim": PLANE("recessed plane"),
|
|
2696
2705
|
"system/surface/low": PLANE("resting page plane"),
|
|
2697
2706
|
"system/surface/mid": PLANE("raised plane \u2014 cards, menus"),
|
|
2698
2707
|
// ("overlays" reworded 2026-08-13: paper-overlay took the word as a label — the C50 law)
|
|
@@ -3323,6 +3332,33 @@ var STAMP_LEAF = {
|
|
|
3323
3332
|
EDGE: STAMP_STATE_LEAVES[STAMP_EDGE],
|
|
3324
3333
|
ON: STAMP_STATE_LEAVES[STAMP_ON]
|
|
3325
3334
|
};
|
|
3335
|
+
var SYSTEM_LEAF = {
|
|
3336
|
+
ABS_BLACK: "system/abs-black",
|
|
3337
|
+
ABS_WHITE: "system/abs-white",
|
|
3338
|
+
SURFACE: {
|
|
3339
|
+
DIM: "system/surface/dim",
|
|
3340
|
+
LOW: "system/surface/low",
|
|
3341
|
+
MID: "system/surface/mid",
|
|
3342
|
+
HIGH: "system/surface/high"
|
|
3343
|
+
},
|
|
3344
|
+
ALPHA: {
|
|
3345
|
+
TRANSPARENT: "system/alpha/transparent",
|
|
3346
|
+
SCRIM: "system/alpha/abs-black-060",
|
|
3347
|
+
INK: "system/alpha/ink",
|
|
3348
|
+
OFFSET_006: "system/alpha/006",
|
|
3349
|
+
OFFSET_008: "system/alpha/008",
|
|
3350
|
+
OFFSET_016: "system/alpha/016",
|
|
3351
|
+
SHADOW_04: "system/alpha/shadow-04",
|
|
3352
|
+
SHADOW_08: "system/alpha/shadow-08",
|
|
3353
|
+
SHADOW_12: "system/alpha/shadow-12"
|
|
3354
|
+
}
|
|
3355
|
+
};
|
|
3356
|
+
var SURFACE_PLANE_LAW = {
|
|
3357
|
+
[SYSTEM_LEAF.SURFACE.DIM]: { light: SHARED_NAMES[3], dark: PAPER_100 },
|
|
3358
|
+
[SYSTEM_LEAF.SURFACE.LOW]: { light: SHARED_NAMES[2], dark: SHARED_NAMES[1] },
|
|
3359
|
+
[SYSTEM_LEAF.SURFACE.MID]: { light: SHARED_NAMES[1], dark: SHARED_NAMES[2] },
|
|
3360
|
+
[SYSTEM_LEAF.SURFACE.HIGH]: { light: PAPER_100, dark: SHARED_NAMES[3] }
|
|
3361
|
+
};
|
|
3326
3362
|
var TOKEN_ORDER = [
|
|
3327
3363
|
...Object.values(SHARED_NAMES),
|
|
3328
3364
|
STAMP_FILL,
|
|
@@ -3368,6 +3404,12 @@ var OFFSET_ALPHAS = { 6: 0.06, 8: 0.08, 16: 0.16 };
|
|
|
3368
3404
|
var ctaBorderRung = (prefix) => prefix === CSS_NEUTRAL ? 8 : prefix === CSS_SECONDARY ? 6 : 16;
|
|
3369
3405
|
var offsetLeafName = (rung) => String(rung).padStart(3, "0");
|
|
3370
3406
|
var offsetVarName = (rung) => `--alpha-${offsetLeafName(rung)}`;
|
|
3407
|
+
var SHADOW_ALPHAS = {
|
|
3408
|
+
4: { light: 0.04, dark: 0.32 },
|
|
3409
|
+
8: { light: 0.08, dark: 0.48 },
|
|
3410
|
+
12: { light: 0.12, dark: 0.64 }
|
|
3411
|
+
};
|
|
3412
|
+
var SCRIM_ALPHA = 0.6;
|
|
3371
3413
|
var TRANSPARENT_VAR = "--alpha-transparent";
|
|
3372
3414
|
var offsetRgba = (rung, mode) => mode === "light" ? `rgba(0, 0, 0, ${OFFSET_ALPHAS[rung]})` : `rgba(255, 255, 255, ${OFFSET_ALPHAS[rung]})`;
|
|
3373
3415
|
var alphaRootVars = (mode) => [
|
|
@@ -3557,7 +3599,7 @@ function brandCss(slug, displayName, r, secondary, noteSuffix = "", neutralLevel
|
|
|
3557
3599
|
};
|
|
3558
3600
|
const softOnCta = (mode) => {
|
|
3559
3601
|
if (!secondary || secondaryStyle === "outline") return [];
|
|
3560
|
-
if (
|
|
3602
|
+
if (!softOnCtaPasses(secondary, mode)) return [];
|
|
3561
3603
|
const white = mode === "light" ? secondary.onFillTextIsWhite : secondary.onFillTextIsWhiteDark;
|
|
3562
3604
|
return [` --${CSS_SECONDARY}-stamp-on: rgba(${white ? "255, 255, 255" : "0, 0, 0"}, ${SOFT_ON_CTA_ALPHA[mode]});`];
|
|
3563
3605
|
};
|
|
@@ -3750,7 +3792,7 @@ function themeToFigma(r, input) {
|
|
|
3750
3792
|
});
|
|
3751
3793
|
};
|
|
3752
3794
|
softOnCta(neutralGroup, mode === "light" ? nScale.onFillTextIsWhite : nScale.onFillTextIsWhiteDark);
|
|
3753
|
-
if (input.secondary && input.secondaryStyle !== "outline" &&
|
|
3795
|
+
if (input.secondary && input.secondaryStyle !== "outline" && softOnCtaPasses(input.secondary, mode))
|
|
3754
3796
|
softOnCta(secondaryGroup, mode === "light" ? secondaryOnFillLight : secondaryOnFillDark);
|
|
3755
3797
|
const brandGroup = rampGroup(scale[mode], mode === "light" ? scale.onFillTextIsWhite : scale.onFillTextIsWhiteDark, brandExtra(scale, mode, CSS_FAMILY.brandPrimary));
|
|
3756
3798
|
const esc = input.ctaEscape ? escapeCtaFamily(nScale, mode, input.contrastProfile) : null;
|
|
@@ -3785,6 +3827,28 @@ function themeToFigma(r, input) {
|
|
|
3785
3827
|
ctaFamily(sig.scale, mode, sig.name)
|
|
3786
3828
|
);
|
|
3787
3829
|
}
|
|
3830
|
+
const pole = (white, alpha) => {
|
|
3831
|
+
const c = white ? 1 : 0;
|
|
3832
|
+
return {
|
|
3833
|
+
$type: "color",
|
|
3834
|
+
$value: { colorSpace: "srgb", components: [c, c, c], alpha, hex: white ? "#ffffff" : "#000000" }
|
|
3835
|
+
};
|
|
3836
|
+
};
|
|
3837
|
+
putLeaf(g2, SYSTEM_LEAF.ABS_BLACK, colorFromHex(false));
|
|
3838
|
+
putLeaf(g2, SYSTEM_LEAF.ABS_WHITE, colorFromHex(true));
|
|
3839
|
+
for (const [path, law] of Object.entries(SURFACE_PLANE_LAW)) {
|
|
3840
|
+
const tok = neutralGroup[law[mode]];
|
|
3841
|
+
if (tok && "$type" in tok) putLeaf(g2, path, tok);
|
|
3842
|
+
}
|
|
3843
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.TRANSPARENT, pole(true, 0));
|
|
3844
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.SCRIM, pole(false, SCRIM_ALPHA));
|
|
3845
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.INK, pole(mode === "dark", SOFT_ON_CTA_ALPHA[mode]));
|
|
3846
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.OFFSET_006, OFFSET_TOKEN(6, mode));
|
|
3847
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.OFFSET_008, OFFSET_TOKEN(8, mode));
|
|
3848
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.OFFSET_016, OFFSET_TOKEN(16, mode));
|
|
3849
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.SHADOW_04, pole(false, SHADOW_ALPHAS[4][mode]));
|
|
3850
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.SHADOW_08, pole(false, SHADOW_ALPHAS[8][mode]));
|
|
3851
|
+
putLeaf(g2, SYSTEM_LEAF.ALPHA.SHADOW_12, pole(false, SHADOW_ALPHAS[12][mode]));
|
|
3788
3852
|
return g2;
|
|
3789
3853
|
};
|
|
3790
3854
|
return { light: build("light"), dark: build("dark") };
|
|
@@ -3853,6 +3917,7 @@ function resolveDtcgRamp(group) {
|
|
|
3853
3917
|
return resolveRamp(seedHex, mode, { stops, roles, ons });
|
|
3854
3918
|
}
|
|
3855
3919
|
export {
|
|
3920
|
+
CSS_FAMILY,
|
|
3856
3921
|
DEFAULT_LINK_HEX,
|
|
3857
3922
|
EXT_KEY,
|
|
3858
3923
|
INK_0,
|
|
@@ -3862,7 +3927,9 @@ export {
|
|
|
3862
3927
|
PAPER_100,
|
|
3863
3928
|
RESOLVER_ID,
|
|
3864
3929
|
SCALE_STOP_COUNT,
|
|
3930
|
+
SCRIM_ALPHA,
|
|
3865
3931
|
SECONDARY_DISTINCT_DELTA_E,
|
|
3932
|
+
SHADOW_ALPHAS,
|
|
3866
3933
|
SIGNALS2 as SIGNALS,
|
|
3867
3934
|
SIGNAL_EMIT_NAME,
|
|
3868
3935
|
SIGNAL_SCALES,
|
|
@@ -3874,16 +3941,21 @@ export {
|
|
|
3874
3941
|
STAMP_STATE_LEAVES,
|
|
3875
3942
|
SUBTLE_PASTEL_K,
|
|
3876
3943
|
SUBTLE_TINT_MULT,
|
|
3944
|
+
SURFACE_PLANE_LAW,
|
|
3945
|
+
SYSTEM_LEAF,
|
|
3877
3946
|
brandCss,
|
|
3878
3947
|
checkAllCollisions,
|
|
3879
3948
|
checkCollision,
|
|
3880
3949
|
checkHueCollision,
|
|
3881
3950
|
classifyArchetype,
|
|
3951
|
+
ctaBorderRung,
|
|
3952
|
+
ctaNeedsBorder,
|
|
3882
3953
|
emitDtcgRamp,
|
|
3883
3954
|
generateNeutralScale,
|
|
3884
3955
|
generateScale,
|
|
3885
3956
|
generateSubtleSecondary,
|
|
3886
3957
|
neutralCss,
|
|
3958
|
+
pageStopFor,
|
|
3887
3959
|
parseToken,
|
|
3888
3960
|
resolveBrand,
|
|
3889
3961
|
resolveDtcgRamp,
|
|
@@ -17,6 +17,22 @@ export declare const ctaBorderRung: (prefix: string) => OffsetRung;
|
|
|
17
17
|
export declare const offsetLeafName: (rung: OffsetRung) => string;
|
|
18
18
|
export declare const offsetVarName: (rung: OffsetRung) => string;
|
|
19
19
|
export declare const offsetTokenPath: (rung: OffsetRung) => string;
|
|
20
|
+
export declare const SHADOW_ALPHAS: {
|
|
21
|
+
readonly 4: {
|
|
22
|
+
readonly light: 0.04;
|
|
23
|
+
readonly dark: 0.32;
|
|
24
|
+
};
|
|
25
|
+
readonly 8: {
|
|
26
|
+
readonly light: 0.08;
|
|
27
|
+
readonly dark: 0.48;
|
|
28
|
+
};
|
|
29
|
+
readonly 12: {
|
|
30
|
+
readonly light: 0.12;
|
|
31
|
+
readonly dark: 0.64;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export type ShadowRung = keyof typeof SHADOW_ALPHAS;
|
|
35
|
+
export declare const SCRIM_ALPHA = 0.6;
|
|
20
36
|
export declare const TRANSPARENT_VAR = "--alpha-transparent";
|
|
21
37
|
export declare const offsetRgba: (rung: OffsetRung, mode: "light" | "dark") => string;
|
|
22
38
|
export declare const alphaRootVars: (mode: "light" | "dark") => string[];
|
|
@@ -15,6 +15,31 @@ export declare const STAMP_LEAF: {
|
|
|
15
15
|
readonly EDGE: string;
|
|
16
16
|
readonly ON: string;
|
|
17
17
|
};
|
|
18
|
+
export declare const SYSTEM_LEAF: {
|
|
19
|
+
readonly ABS_BLACK: "system/abs-black";
|
|
20
|
+
readonly ABS_WHITE: "system/abs-white";
|
|
21
|
+
readonly SURFACE: {
|
|
22
|
+
readonly DIM: "system/surface/dim";
|
|
23
|
+
readonly LOW: "system/surface/low";
|
|
24
|
+
readonly MID: "system/surface/mid";
|
|
25
|
+
readonly HIGH: "system/surface/high";
|
|
26
|
+
};
|
|
27
|
+
readonly ALPHA: {
|
|
28
|
+
readonly TRANSPARENT: "system/alpha/transparent";
|
|
29
|
+
readonly SCRIM: "system/alpha/abs-black-060";
|
|
30
|
+
readonly INK: "system/alpha/ink";
|
|
31
|
+
readonly OFFSET_006: "system/alpha/006";
|
|
32
|
+
readonly OFFSET_008: "system/alpha/008";
|
|
33
|
+
readonly OFFSET_016: "system/alpha/016";
|
|
34
|
+
readonly SHADOW_04: "system/alpha/shadow-04";
|
|
35
|
+
readonly SHADOW_08: "system/alpha/shadow-08";
|
|
36
|
+
readonly SHADOW_12: "system/alpha/shadow-12";
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export declare const SURFACE_PLANE_LAW: Record<string, {
|
|
40
|
+
light: string;
|
|
41
|
+
dark: string;
|
|
42
|
+
}>;
|
|
18
43
|
export declare const CONTRACT_INVARIANT_ROWS: ReadonlySet<string>;
|
|
19
44
|
export declare const EXT_NON_OVERRIDABLE: (p: string) => boolean;
|
|
20
45
|
export declare const EXT_OVERRIDABLE_SYSTEM: (p: string) => boolean;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export { generateScale, generateNeutralScale, generateSubtleSecondary, type GeneratedScale, type ColorStop, type GenerateOptions, type NeutralLevel, type ContrastProfile, } from './engine/colorEngine';
|
|
2
2
|
export { resolveBrand, resolveTheme, resolveLinkTrio, resolveLinkInverseTrio, DEFAULT_LINK_HEX, SIGNAL_SCALES, signalScalesFor, SECONDARY_DISTINCT_DELTA_E, SUBTLE_TINT_MULT, SUBTLE_PASTEL_K, OUTLINE_HOVER_ALPHA, type ResolvedBrand, type ResolvedTheme, type ResolvedSecondary, type SecondaryLevel, type SecondaryStyle, type SignalOverride, } from './engine/resolve';
|
|
3
|
-
export { brandCss, neutralCss, signalsCss, stopsToVars, toHex, stopHex, OFFSET_ALPHAS } from './engine/cssRender';
|
|
3
|
+
export { brandCss, neutralCss, signalsCss, stopsToVars, toHex, stopHex, OFFSET_ALPHAS, SHADOW_ALPHAS, SCRIM_ALPHA, type ShadowRung, ctaNeedsBorder, ctaBorderRung, pageStopFor, } from './engine/cssRender';
|
|
4
|
+
export { CSS_FAMILY } from './engine/tokenDescriptions';
|
|
4
5
|
export { themeToFigma, type FigmaGroup, type FigmaColorToken, type ThemeInput, } from './engine/figmaRender';
|
|
5
6
|
export { emitDtcgRamp, resolveDtcgRamp, parseToken, EXT_KEY, RESOLVER_ID, type DtcgRampGroup, type DtcgRequirementToken, type DtcgSeedToken, type DtcgColorValue, } from './engine/requirements/dtcg';
|
|
6
7
|
export { MODE_SPECS, type ModeSpec } from './engine/requirements/spec';
|
|
7
|
-
export { stopTokenName, tokenOrder, SCALE_STOP_COUNT, PAPER_100, INK_0, STAMP_FILL, STAMP_FILL_HOVER, STAMP_FILL_PRESSED, STAMP_EDGE, STAMP_ON, STAMP_STATE_LEAVES, } from './engine/tokenNames';
|
|
8
|
+
export { stopTokenName, tokenOrder, SCALE_STOP_COUNT, PAPER_100, INK_0, STAMP_FILL, STAMP_FILL_HOVER, STAMP_FILL_PRESSED, STAMP_EDGE, STAMP_ON, STAMP_STATE_LEAVES, SYSTEM_LEAF, SURFACE_PLANE_LAW, } from './engine/tokenNames';
|
|
8
9
|
export { SIGNAL_EMIT_NAME } from './engine/signals';
|
|
9
10
|
export { classifyArchetype, type Archetype } from './engine/archetypes';
|
|
10
11
|
export { SIGNALS, type SignalDef } from './engine/signals';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "okchroma",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Color token engine: one brand hex in, a full WCAG-enforced light+dark token system out (CSS variables, DTCG JSON, Figma variables)",
|
|
6
6
|
"repository": {
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
|
-
"dist-lib"
|
|
21
|
+
"dist-lib",
|
|
22
|
+
"tokens"
|
|
22
23
|
],
|
|
23
24
|
"sideEffects": false,
|
|
24
25
|
"scripts": {
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Semantic token layer — maps role names to primitive tokens.
|
|
3
|
+
This file never changes per brand. Only the primitives (--brand-*, --neutral-*) change.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* ─── Global surface / fg / border ─────────────────────────────────────────── */
|
|
7
|
+
|
|
8
|
+
[data-brand] {
|
|
9
|
+
/* Elevation planes sunken → low → base → high (owner spec 2026-07-24 Figma
|
|
10
|
+
elevation study; renamed 2026-08-12 — base is the raised plane components sit
|
|
11
|
+
on, the page behind it is low, the two extremes are edge cases): both themes
|
|
12
|
+
use the SAME four stops, in reversed order — elevation always moves toward
|
|
13
|
+
paper-100's side of the ramp. Light descends the ramp as elevation rises
|
|
14
|
+
(sunken paper-95 → high paper-100 white); dark ascends it (sunken paper-100
|
|
15
|
+
black → high paper-95). paper-100 flips white→black with the mode, so it is
|
|
16
|
+
always the extreme pole: the high in light, the sunken in dark. The stops
|
|
17
|
+
themselves have never moved through any of the renames. */
|
|
18
|
+
--surface-dim: var(--neutral-paper-95);
|
|
19
|
+
--surface-low: var(--neutral-paper-97);
|
|
20
|
+
--surface-mid: var(--neutral-paper-99);
|
|
21
|
+
--surface-high: var(--paper-100, #ffffff);
|
|
22
|
+
|
|
23
|
+
--fg-default: var(--neutral-ink-30);
|
|
24
|
+
--fg-subtle: var(--neutral-lead-53);
|
|
25
|
+
/* --fg-link moved to the SYSTEM LINK trio below (owner 2026-07-16: one link per
|
|
26
|
+
theme, riding --link — no longer the brand's raw ink pair) */
|
|
27
|
+
|
|
28
|
+
/* --border-default IS THE ACCESSIBILITY BORDER (owner 2026-07-29): a border that has
|
|
29
|
+
to be there — inputs and other controls — so it rides mark-74, the stop that
|
|
30
|
+
carries the WCAG 1.4.11 3:1 non-text require (highlight-8 pre-Stage-B). It sat on
|
|
31
|
+
--neutral-highlight-9 until that stop was deleted; mark-74 is where the
|
|
32
|
+
requirement actually lives, and it is the one stop this round does not move.
|
|
33
|
+
Decorative borders are --border-subtle (wash-89) and the per-family
|
|
34
|
+
--*-border-default (wash-85). */
|
|
35
|
+
--border-default: var(--neutral-mark-74);
|
|
36
|
+
--border-subtle: var(--neutral-wash-89);
|
|
37
|
+
|
|
38
|
+
/* Shadow transparencies (owner 2026-07-27) — pure black, mirrors the plugin's
|
|
39
|
+
system/alpha/shadow-04|08|12 rows 1:1. Dark is heavier by necessity: near
|
|
40
|
+
black a light-mode alpha vanishes, so the dark values carry the same roles
|
|
41
|
+
at 32/48/64%. Elevation recipes (--elev-*) compose these, so dark shadows
|
|
42
|
+
fall out of the token swap with nothing bespoke per style. */
|
|
43
|
+
--shadow-04: rgba(0, 0, 0, 0.04);
|
|
44
|
+
--shadow-08: rgba(0, 0, 0, 0.08);
|
|
45
|
+
--shadow-12: rgba(0, 0, 0, 0.12);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
[data-brand][data-theme="dark"] {
|
|
49
|
+
/* Dark runs the same four stops upward: sunken paper-100 (black) → low paper-99 →
|
|
50
|
+
base paper-97 → high paper-95 — the one-level highest background (C27: every
|
|
51
|
+
family's paper-95 shares one photometric level, so chips sit flush on the high
|
|
52
|
+
plane by construction; a generated candidate for it was tried and retired,
|
|
53
|
+
owner 2026-07-28). Low needs its own override here because the shared block's
|
|
54
|
+
low is paper-97 (the light value); the stops themselves did not move. */
|
|
55
|
+
--surface-dim: var(--paper-100, #000000);
|
|
56
|
+
--surface-low: var(--neutral-paper-99);
|
|
57
|
+
--surface-mid: var(--neutral-paper-97);
|
|
58
|
+
--surface-high: var(--neutral-paper-95);
|
|
59
|
+
|
|
60
|
+
--shadow-04: rgba(0, 0, 0, 0.32);
|
|
61
|
+
--shadow-08: rgba(0, 0, 0, 0.48);
|
|
62
|
+
--shadow-12: rgba(0, 0, 0, 0.64);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* ─── role.brand ────────────────────────────────────────────────────────────── */
|
|
66
|
+
|
|
67
|
+
[data-brand] {
|
|
68
|
+
--brand-fg: var(--brand-ink-30);
|
|
69
|
+
--brand-fg-hover: var(--brand-lead-53);
|
|
70
|
+
--brand-fg-alt: var(--brand-lead-53);
|
|
71
|
+
--brand-fg-alt-hover: var(--brand-ink-30);
|
|
72
|
+
--brand-fg-on-emphasis: var(--brand-stamp-on);
|
|
73
|
+
|
|
74
|
+
--brand-bg-faint: var(--brand-paper-97);
|
|
75
|
+
--brand-bg-subtle: var(--brand-wash-89);
|
|
76
|
+
--brand-bg-subtle-hover: var(--brand-wash-85);
|
|
77
|
+
--brand-bg-emphasis: var(--brand-stamp-fill);
|
|
78
|
+
--brand-bg-emphasis-hover: var(--brand-stamp-fill-hover);
|
|
79
|
+
--brand-bg-emphasis-pressed: var(--brand-stamp-fill-pressed);
|
|
80
|
+
|
|
81
|
+
--brand-border-subtle: var(--brand-wash-92);
|
|
82
|
+
--brand-border-subtle-hover: var(--brand-wash-89);
|
|
83
|
+
--brand-border-default: var(--brand-wash-85);
|
|
84
|
+
--brand-border-default-hover: var(--brand-mark-74);
|
|
85
|
+
--brand-border-emphasis: var(--brand-stamp-fill);
|
|
86
|
+
--brand-border-emphasis-hover: var(--brand-stamp-fill-hover);
|
|
87
|
+
|
|
88
|
+
/* the SYSTEM LINK (one trio per theme — aliases the primary's ink stops unless a custom
|
|
89
|
+
link color de-conflicts it; --link/-hover/-pressed are emitted per brand) */
|
|
90
|
+
--fg-link: var(--link);
|
|
91
|
+
--fg-link-hover: var(--link-hover);
|
|
92
|
+
--fg-link-pressed: var(--link-pressed);
|
|
93
|
+
|
|
94
|
+
/* the INVERSE link trio (owner round 2026-08-19): the same link seed re-solved for
|
|
95
|
+
text on inverted surfaces (an ink-30 fill); always its own emitted values —
|
|
96
|
+
no stop is anchored against that ground, so there is no alias posture */
|
|
97
|
+
--fg-link-inverse: var(--link-inverse);
|
|
98
|
+
--fg-link-inverse-hover: var(--link-inverse-hover);
|
|
99
|
+
--fg-link-inverse-pressed: var(--link-inverse-pressed);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* ─── role.secondary (the brand's secondary ramp; mirrors brand when none) ──── */
|
|
103
|
+
|
|
104
|
+
[data-brand] {
|
|
105
|
+
--brand-alt-fg: var(--brand-alt-ink-30);
|
|
106
|
+
--brand-alt-fg-hover: var(--brand-alt-lead-53);
|
|
107
|
+
--brand-alt-fg-alt: var(--brand-alt-lead-53);
|
|
108
|
+
--brand-alt-fg-alt-hover: var(--brand-alt-ink-30);
|
|
109
|
+
--brand-alt-fg-on-emphasis: var(--brand-alt-stamp-on);
|
|
110
|
+
|
|
111
|
+
--brand-alt-bg-faint: var(--brand-alt-paper-97);
|
|
112
|
+
--brand-alt-bg-subtle: var(--brand-alt-wash-89);
|
|
113
|
+
--brand-alt-bg-subtle-hover: var(--brand-alt-wash-85);
|
|
114
|
+
--brand-alt-bg-emphasis: var(--brand-alt-stamp-fill);
|
|
115
|
+
--brand-alt-bg-emphasis-hover: var(--brand-alt-stamp-fill-hover);
|
|
116
|
+
--brand-alt-bg-emphasis-pressed: var(--brand-alt-stamp-fill-pressed);
|
|
117
|
+
|
|
118
|
+
--brand-alt-border-subtle: var(--brand-alt-wash-92);
|
|
119
|
+
--brand-alt-border-subtle-hover: var(--brand-alt-wash-89);
|
|
120
|
+
--brand-alt-border-default: var(--brand-alt-wash-85);
|
|
121
|
+
--brand-alt-border-default-hover: var(--brand-alt-mark-74);
|
|
122
|
+
--brand-alt-border-emphasis: var(--brand-alt-stamp-fill);
|
|
123
|
+
--brand-alt-border-emphasis-hover: var(--brand-alt-stamp-fill-hover);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* ─── Signal roles ──────────────────────────────────────────────────────────
|
|
127
|
+
Aliases onto engine-generated signal primitives (dist/signals.css).
|
|
128
|
+
Mode switching happens at the primitive layer, so one block covers both.
|
|
129
|
+
Signal families emit by ROLE (owner 2026-07-27: critical/warning/positive/
|
|
130
|
+
info — the re-pointable in-between tier; identity stays engine-internal),
|
|
131
|
+
so the role tokens and the family ramp share a prefix: --critical-fg rides
|
|
132
|
+
--critical-ink-30. The old alert-high/alert-med role prefixes collapsed
|
|
133
|
+
into critical/warning in the same round.
|
|
134
|
+
|
|
135
|
+
-fg-on-emphasis rides --paper-100, NOT a solved on-color: the engine's on-highlight
|
|
136
|
+
token was deleted with the highlight band (owner 2026-07-29). paper-100 is the
|
|
137
|
+
mode-flipping paper extreme — white in light, the tinted deep ground in dark — and
|
|
138
|
+
it clears 4.5 against lead-53 everywhere (agnostic 360-seed sweep, worst 4.96
|
|
139
|
+
light / 8.04 dark). -bg-emphasis / -border-emphasis moved from highlight-9 to
|
|
140
|
+
lead-53 (ink-9 pre-Stage-B) with it; in dark that reads lighter (contrast vs
|
|
141
|
+
paper-95, median 6.01 → 7.72). Stage B (owner 2026-08-07, names only) relabeled
|
|
142
|
+
every leaf in the block below; the stops themselves did not move. */
|
|
143
|
+
|
|
144
|
+
[data-brand] {
|
|
145
|
+
--critical-fg: var(--critical-ink-30);
|
|
146
|
+
--critical-fg-hover: var(--critical-lead-53);
|
|
147
|
+
--critical-fg-alt: var(--critical-lead-53);
|
|
148
|
+
--critical-fg-alt-hover: var(--critical-ink-30);
|
|
149
|
+
--critical-fg-on-emphasis: var(--paper-100);
|
|
150
|
+
--critical-bg-faint: var(--critical-paper-97);
|
|
151
|
+
--critical-bg-subtle: var(--critical-wash-89);
|
|
152
|
+
--critical-bg-subtle-hover: var(--critical-wash-85);
|
|
153
|
+
--critical-bg-emphasis: var(--critical-lead-53);
|
|
154
|
+
--critical-border-subtle: var(--critical-wash-92);
|
|
155
|
+
--critical-border-subtle-hover: var(--critical-wash-89);
|
|
156
|
+
--critical-border-default: var(--critical-wash-85);
|
|
157
|
+
--critical-border-default-hover: var(--critical-mark-74);
|
|
158
|
+
--critical-border-emphasis: var(--critical-lead-53);
|
|
159
|
+
|
|
160
|
+
--warning-fg: var(--warning-ink-30);
|
|
161
|
+
--warning-fg-hover: var(--warning-lead-53);
|
|
162
|
+
--warning-fg-alt: var(--warning-lead-53);
|
|
163
|
+
--warning-fg-alt-hover: var(--warning-ink-30);
|
|
164
|
+
--warning-fg-on-emphasis: var(--paper-100);
|
|
165
|
+
--warning-bg-faint: var(--warning-paper-97);
|
|
166
|
+
--warning-bg-subtle: var(--warning-wash-89);
|
|
167
|
+
--warning-bg-subtle-hover: var(--warning-wash-85);
|
|
168
|
+
--warning-bg-emphasis: var(--warning-lead-53);
|
|
169
|
+
--warning-border-subtle: var(--warning-wash-92);
|
|
170
|
+
--warning-border-subtle-hover: var(--warning-wash-89);
|
|
171
|
+
--warning-border-default: var(--warning-wash-85);
|
|
172
|
+
--warning-border-default-hover: var(--warning-mark-74);
|
|
173
|
+
--warning-border-emphasis: var(--warning-lead-53);
|
|
174
|
+
|
|
175
|
+
--positive-fg: var(--positive-ink-30);
|
|
176
|
+
--positive-fg-hover: var(--positive-lead-53);
|
|
177
|
+
--positive-fg-alt: var(--positive-lead-53);
|
|
178
|
+
--positive-fg-alt-hover: var(--positive-ink-30);
|
|
179
|
+
--positive-fg-on-emphasis: var(--paper-100);
|
|
180
|
+
--positive-bg-faint: var(--positive-paper-97);
|
|
181
|
+
--positive-bg-subtle: var(--positive-wash-89);
|
|
182
|
+
--positive-bg-subtle-hover: var(--positive-wash-85);
|
|
183
|
+
--positive-bg-emphasis: var(--positive-lead-53);
|
|
184
|
+
--positive-border-subtle: var(--positive-wash-92);
|
|
185
|
+
--positive-border-subtle-hover: var(--positive-wash-89);
|
|
186
|
+
--positive-border-default: var(--positive-wash-85);
|
|
187
|
+
--positive-border-default-hover: var(--positive-mark-74);
|
|
188
|
+
--positive-border-emphasis: var(--positive-lead-53);
|
|
189
|
+
|
|
190
|
+
--info-fg: var(--info-ink-30);
|
|
191
|
+
--info-fg-hover: var(--info-lead-53);
|
|
192
|
+
--info-fg-alt: var(--info-lead-53);
|
|
193
|
+
--info-fg-alt-hover: var(--info-ink-30);
|
|
194
|
+
--info-fg-on-emphasis: var(--paper-100);
|
|
195
|
+
--info-bg-faint: var(--info-paper-97);
|
|
196
|
+
--info-bg-subtle: var(--info-wash-89);
|
|
197
|
+
--info-bg-subtle-hover: var(--info-wash-85);
|
|
198
|
+
--info-bg-emphasis: var(--info-lead-53);
|
|
199
|
+
--info-border-subtle: var(--info-wash-92);
|
|
200
|
+
--info-border-subtle-hover: var(--info-wash-89);
|
|
201
|
+
--info-border-default: var(--info-wash-85);
|
|
202
|
+
--info-border-default-hover: var(--info-mark-74);
|
|
203
|
+
--info-border-emphasis: var(--info-lead-53);
|
|
204
|
+
}
|