tyrell-components 1.0.0-RC11 → 1.0.0-RC13
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/README.md +1 -0
- package/css/tyrell-colors-static.css +316 -0
- package/css/tyrell-theme.css +1454 -0
- package/css/tyrell.css +112 -420
- package/dist/tyrell-colors-static.css +316 -0
- package/dist/tyrell-theme.css +1454 -0
- package/dist/tyrell.css +112 -420
- package/dist/tyrell.js +1 -1
- package/lib/base/ty-component.d.ts +7 -0
- package/lib/base/ty-component.d.ts.map +1 -1
- package/lib/base/ty-component.js +27 -0
- package/lib/base/ty-component.js.map +1 -1
- package/lib/components/button.d.ts +16 -1
- package/lib/components/button.d.ts.map +1 -1
- package/lib/components/button.js +34 -4
- package/lib/components/button.js.map +1 -1
- package/lib/components/calendar-month.d.ts +23 -0
- package/lib/components/calendar-month.d.ts.map +1 -1
- package/lib/components/calendar-month.js +168 -11
- package/lib/components/calendar-month.js.map +1 -1
- package/lib/components/calendar-navigation.d.ts +31 -5
- package/lib/components/calendar-navigation.d.ts.map +1 -1
- package/lib/components/calendar-navigation.js +71 -31
- package/lib/components/calendar-navigation.js.map +1 -1
- package/lib/components/calendar.d.ts +17 -2
- package/lib/components/calendar.d.ts.map +1 -1
- package/lib/components/calendar.js +83 -12
- package/lib/components/calendar.js.map +1 -1
- package/lib/components/checkbox.d.ts +14 -3
- package/lib/components/checkbox.d.ts.map +1 -1
- package/lib/components/checkbox.js +86 -57
- package/lib/components/checkbox.js.map +1 -1
- package/lib/components/copy.d.ts +14 -3
- package/lib/components/copy.d.ts.map +1 -1
- package/lib/components/copy.js +47 -25
- package/lib/components/copy.js.map +1 -1
- package/lib/components/date-picker.d.ts +26 -1
- package/lib/components/date-picker.d.ts.map +1 -1
- package/lib/components/date-picker.js +151 -32
- package/lib/components/date-picker.js.map +1 -1
- package/lib/components/input.d.ts +17 -2
- package/lib/components/input.d.ts.map +1 -1
- package/lib/components/input.js +104 -25
- package/lib/components/input.js.map +1 -1
- package/lib/components/modal.d.ts.map +1 -1
- package/lib/components/modal.js +28 -3
- package/lib/components/modal.js.map +1 -1
- package/lib/components/option.d.ts +0 -27
- package/lib/components/option.d.ts.map +1 -1
- package/lib/components/option.js +11 -102
- package/lib/components/option.js.map +1 -1
- package/lib/components/popup.d.ts.map +1 -1
- package/lib/components/popup.js +36 -2
- package/lib/components/popup.js.map +1 -1
- package/lib/components/radio.d.ts +6 -2
- package/lib/components/radio.d.ts.map +1 -1
- package/lib/components/radio.js +55 -13
- package/lib/components/radio.js.map +1 -1
- package/lib/components/scroll-container.d.ts +16 -0
- package/lib/components/scroll-container.d.ts.map +1 -1
- package/lib/components/scroll-container.js +105 -1
- package/lib/components/scroll-container.js.map +1 -1
- package/lib/components/select.d.ts +550 -0
- package/lib/components/select.d.ts.map +1 -0
- package/lib/components/select.js +2115 -0
- package/lib/components/select.js.map +1 -0
- package/lib/components/selected-tags.d.ts +93 -0
- package/lib/components/selected-tags.d.ts.map +1 -0
- package/lib/components/selected-tags.js +286 -0
- package/lib/components/selected-tags.js.map +1 -0
- package/lib/components/switch.d.ts +6 -3
- package/lib/components/switch.d.ts.map +1 -1
- package/lib/components/switch.js +54 -36
- package/lib/components/switch.js.map +1 -1
- package/lib/components/tabs.d.ts.map +1 -1
- package/lib/components/tabs.js +190 -25
- package/lib/components/tabs.js.map +1 -1
- package/lib/components/tag.d.ts +9 -1
- package/lib/components/tag.d.ts.map +1 -1
- package/lib/components/tag.js +41 -5
- package/lib/components/tag.js.map +1 -1
- package/lib/components/textarea.d.ts +3 -0
- package/lib/components/textarea.d.ts.map +1 -1
- package/lib/components/textarea.js +61 -6
- package/lib/components/textarea.js.map +1 -1
- package/lib/components/tooltip.d.ts +4 -2
- package/lib/components/tooltip.d.ts.map +1 -1
- package/lib/components/tooltip.js +109 -70
- package/lib/components/tooltip.js.map +1 -1
- package/lib/components/wizard.d.ts.map +1 -1
- package/lib/components/wizard.js +22 -3
- package/lib/components/wizard.js.map +1 -1
- package/lib/index.d.ts +3 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -2
- package/lib/index.js.map +1 -1
- package/lib/styles/button.d.ts +41 -6
- package/lib/styles/button.d.ts.map +1 -1
- package/lib/styles/button.js +294 -254
- package/lib/styles/button.js.map +1 -1
- package/lib/styles/calendar-month.d.ts +3 -1
- package/lib/styles/calendar-month.d.ts.map +1 -1
- package/lib/styles/calendar-month.js +100 -67
- package/lib/styles/calendar-month.js.map +1 -1
- package/lib/styles/calendar-navigation.d.ts +1 -1
- package/lib/styles/calendar-navigation.d.ts.map +1 -1
- package/lib/styles/calendar-navigation.js +20 -28
- package/lib/styles/calendar-navigation.js.map +1 -1
- package/lib/styles/checkbox.d.ts +7 -5
- package/lib/styles/checkbox.d.ts.map +1 -1
- package/lib/styles/checkbox.js +125 -8
- package/lib/styles/checkbox.js.map +1 -1
- package/lib/styles/copy.d.ts +3 -1
- package/lib/styles/copy.d.ts.map +1 -1
- package/lib/styles/copy.js +61 -6
- package/lib/styles/copy.js.map +1 -1
- package/lib/styles/custom-scrollbar.d.ts +1 -1
- package/lib/styles/custom-scrollbar.d.ts.map +1 -1
- package/lib/styles/custom-scrollbar.js +2 -2
- package/lib/styles/date-picker.d.ts +3 -1
- package/lib/styles/date-picker.d.ts.map +1 -1
- package/lib/styles/date-picker.js +65 -103
- package/lib/styles/date-picker.js.map +1 -1
- package/lib/styles/file-upload.d.ts +1 -1
- package/lib/styles/file-upload.d.ts.map +1 -1
- package/lib/styles/file-upload.js +3 -3
- package/lib/styles/input.d.ts +3 -1
- package/lib/styles/input.d.ts.map +1 -1
- package/lib/styles/input.js +93 -419
- package/lib/styles/input.js.map +1 -1
- package/lib/styles/multiselect.d.ts +3 -1
- package/lib/styles/multiselect.d.ts.map +1 -1
- package/lib/styles/multiselect.js +26 -2
- package/lib/styles/multiselect.js.map +1 -1
- package/lib/styles/option.d.ts +1 -1
- package/lib/styles/option.d.ts.map +1 -1
- package/lib/styles/option.js +20 -47
- package/lib/styles/option.js.map +1 -1
- package/lib/styles/radio.d.ts +3 -1
- package/lib/styles/radio.d.ts.map +1 -1
- package/lib/styles/radio.js +24 -21
- package/lib/styles/radio.js.map +1 -1
- package/lib/styles/scroll-container.d.ts +1 -1
- package/lib/styles/scroll-container.d.ts.map +1 -1
- package/lib/styles/scroll-container.js +6 -0
- package/lib/styles/scroll-container.js.map +1 -1
- package/lib/styles/select-base.d.ts +9 -0
- package/lib/styles/select-base.d.ts.map +1 -0
- package/lib/styles/select-base.js +973 -0
- package/lib/styles/select-base.js.map +1 -0
- package/lib/styles/select.d.ts +12 -0
- package/lib/styles/select.d.ts.map +1 -0
- package/lib/styles/select.js +308 -0
- package/lib/styles/select.js.map +1 -0
- package/lib/styles/step.d.ts +1 -1
- package/lib/styles/step.d.ts.map +1 -1
- package/lib/styles/switch.d.ts +3 -1
- package/lib/styles/switch.d.ts.map +1 -1
- package/lib/styles/switch.js +25 -10
- package/lib/styles/switch.js.map +1 -1
- package/lib/styles/tab.d.ts +1 -1
- package/lib/styles/tab.d.ts.map +1 -1
- package/lib/styles/tabs.d.ts +1 -1
- package/lib/styles/tabs.d.ts.map +1 -1
- package/lib/styles/tabs.js +71 -1
- package/lib/styles/tabs.js.map +1 -1
- package/lib/styles/tag.d.ts +1 -1
- package/lib/styles/tag.d.ts.map +1 -1
- package/lib/styles/tag.js +40 -141
- package/lib/styles/tag.js.map +1 -1
- package/lib/styles/textarea.d.ts +1 -1
- package/lib/styles/textarea.d.ts.map +1 -1
- package/lib/styles/textarea.js +71 -37
- package/lib/styles/textarea.js.map +1 -1
- package/lib/styles/tooltip.d.ts +4 -2
- package/lib/styles/tooltip.d.ts.map +1 -1
- package/lib/styles/tooltip.js +4 -119
- package/lib/styles/tooltip.js.map +1 -1
- package/lib/styles/wizard.d.ts +1 -1
- package/lib/styles/wizard.d.ts.map +1 -1
- package/lib/styles/wizard.js +18 -6
- package/lib/styles/wizard.js.map +1 -1
- package/lib/types/common.d.ts +2 -1
- package/lib/types/common.d.ts.map +1 -1
- package/lib/types/common.js +15 -1
- package/lib/types/common.js.map +1 -1
- package/lib/utils/calendar-utils.d.ts +0 -48
- package/lib/utils/calendar-utils.d.ts.map +1 -1
- package/lib/utils/calendar-utils.js +0 -69
- package/lib/utils/calendar-utils.js.map +1 -1
- package/lib/utils/flavor-sheet.d.ts +32 -0
- package/lib/utils/flavor-sheet.d.ts.map +1 -0
- package/lib/utils/flavor-sheet.js +40 -0
- package/lib/utils/flavor-sheet.js.map +1 -0
- package/lib/utils/icon-registry.d.ts +0 -13
- package/lib/utils/icon-registry.d.ts.map +1 -1
- package/lib/utils/icon-registry.js +0 -35
- package/lib/utils/icon-registry.js.map +1 -1
- package/lib/utils/icons.d.ts +10 -0
- package/lib/utils/icons.d.ts.map +1 -0
- package/lib/utils/icons.js +10 -0
- package/lib/utils/icons.js.map +1 -0
- package/lib/utils/loader-registry.d.ts +2 -2
- package/lib/utils/loader-registry.js +2 -2
- package/lib/utils/locale.d.ts +0 -57
- package/lib/utils/locale.d.ts.map +1 -1
- package/lib/utils/locale.js +0 -89
- package/lib/utils/locale.js.map +1 -1
- package/lib/utils/number-format.d.ts +0 -21
- package/lib/utils/number-format.d.ts.map +1 -1
- package/lib/utils/number-format.js +0 -27
- package/lib/utils/number-format.js.map +1 -1
- package/lib/utils/positioning.d.ts +29 -22
- package/lib/utils/positioning.d.ts.map +1 -1
- package/lib/utils/positioning.js +23 -87
- package/lib/utils/positioning.js.map +1 -1
- package/lib/utils/scroll-lock.d.ts.map +1 -1
- package/lib/utils/scroll-lock.js +0 -1
- package/lib/utils/scroll-lock.js.map +1 -1
- package/lib/utils/styles.d.ts +0 -5
- package/lib/utils/styles.d.ts.map +1 -1
- package/lib/utils/styles.js +0 -7
- package/lib/utils/styles.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +22 -11
- package/css/tyrell-brand.css +0 -913
- package/dist/tyrell-brand.css +0 -913
- package/lib/components/dropdown.d.ts +0 -424
- package/lib/components/dropdown.d.ts.map +0 -1
- package/lib/components/dropdown.js +0 -1640
- package/lib/components/dropdown.js.map +0 -1
- package/lib/components/multiselect.d.ts +0 -397
- package/lib/components/multiselect.d.ts.map +0 -1
- package/lib/components/multiselect.js +0 -1595
- package/lib/components/multiselect.js.map +0 -1
- package/lib/styles/dropdown.d.ts +0 -12
- package/lib/styles/dropdown.d.ts.map +0 -1
- package/lib/styles/dropdown.js +0 -1081
- package/lib/styles/dropdown.js.map +0 -1
|
@@ -0,0 +1,1454 @@
|
|
|
1
|
+
/* =====================================================================
|
|
2
|
+
* tyrell-theme.css — the OKLCH theme engine for Tyrell Components
|
|
3
|
+
* =====================================================================
|
|
4
|
+
*
|
|
5
|
+
* Opt-in. Load AFTER `tyrell.css`. Override a few variables to rebrand —
|
|
6
|
+
* or seed a color directly, declare a named theme, scope one to a
|
|
7
|
+
* subtree. `tyrell.css` alone is correct and accessible without this
|
|
8
|
+
* file; this is what turns it into a theming ENGINE rather than a fixed
|
|
9
|
+
* palette: auto-contrast text, seed ingestion, named/scoped themes,
|
|
10
|
+
* animated theme transitions. See CSS_GUIDE.md → Color Customization.
|
|
11
|
+
*
|
|
12
|
+
* <link rel="stylesheet" href=".../tyrell.css">
|
|
13
|
+
* <link rel="stylesheet" href=".../tyrell-theme.css">
|
|
14
|
+
*
|
|
15
|
+
* :root {
|
|
16
|
+
* --ty-brand-hue: 200; // teal. Try 260 indigo, 30 orange, 145 emerald.
|
|
17
|
+
* --ty-brand-chroma: 0.13;
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* =====================================================================
|
|
21
|
+
* THE FORMULA
|
|
22
|
+
* =====================================================================
|
|
23
|
+
*
|
|
24
|
+
* Every color in the library is one formula on five axes:
|
|
25
|
+
*
|
|
26
|
+
* oklch(
|
|
27
|
+
* L = L-curve[shade] × flavor-l-factor ← Tier 3 × Tier 5
|
|
28
|
+
* C = flavor-chroma × saturation-curve[shade] ← Tier 2 × Tier 4
|
|
29
|
+
* H = flavor-hue ← Tier 2
|
|
30
|
+
* )
|
|
31
|
+
*
|
|
32
|
+
* Pick a flavor (primary / success / warning / danger /
|
|
33
|
+
* neutral). Pick a shade (strong / bold / base / soft / faint). That's
|
|
34
|
+
* the cell; the formula gives you its color.
|
|
35
|
+
*
|
|
36
|
+
* FLAVOR axis — which semantic role (carries its own hue, chroma,
|
|
37
|
+
* l-factor seeds)
|
|
38
|
+
* SHADE axis — 5 emphasis stops shared across flavors
|
|
39
|
+
* (strong / bold / base / soft / faint)
|
|
40
|
+
* HUE axis — what color family (0°–360°)
|
|
41
|
+
* CHROMA axis — how saturated (0 = grey, ~0.4 = max vivid)
|
|
42
|
+
* L axis — how dark or light (0 = black, 1 = white)
|
|
43
|
+
* Light mode: low L = more emphasis.
|
|
44
|
+
* Dark mode: high L = more emphasis (curve flips).
|
|
45
|
+
*
|
|
46
|
+
* Worked example — `--ty-color-warning-bold` in LIGHT mode:
|
|
47
|
+
*
|
|
48
|
+
* L = 0.46 × 1 = 0.46 ← l-bold × warning-l-factor
|
|
49
|
+
* C = 0.26 × 1.00 = 0.26 ← warning-chroma × c-bold-mult
|
|
50
|
+
* H = 75° ← warning-hue
|
|
51
|
+
* → oklch(0.46 0.26 75) (a punchy amber for +1 emphasis text)
|
|
52
|
+
*
|
|
53
|
+
* Want warning a notch darker without touching anything else? Set
|
|
54
|
+
* `--ty-warning-l-factor: 0.85` and the new L becomes 0.46 × 0.85 =
|
|
55
|
+
* 0.39. Every warning shade shifts in step; primary / success / danger
|
|
56
|
+
* are untouched.
|
|
57
|
+
*
|
|
58
|
+
* =====================================================================
|
|
59
|
+
* FILE LAYOUT
|
|
60
|
+
* =====================================================================
|
|
61
|
+
*
|
|
62
|
+
* SECTION 1 — KNOBS
|
|
63
|
+
* The variables you might want to override. Six tiers from drop-in
|
|
64
|
+
* rebrand (Tier 1) to surgical per-flavor tweak (Tier 5) plus solid
|
|
65
|
+
* buttons (Tier 6).
|
|
66
|
+
*
|
|
67
|
+
* SECTION 2 — IMPLEMENTATION
|
|
68
|
+
* The oklch() expressions that wire the knobs through to the actual
|
|
69
|
+
* color tokens. Rarely needs editing — Section 1 is the contract.
|
|
70
|
+
*
|
|
71
|
+
* Browser support: oklch() is in every evergreen browser since mid-2023.
|
|
72
|
+
* Tier 6 (solid) additionally uses OKLCH relative color — oklch(from …) —
|
|
73
|
+
* which lands later: Chrome 119, Safari 16.4, Firefox 128 (mid-2024).
|
|
74
|
+
* Solid fills have no fallback below those versions.
|
|
75
|
+
*
|
|
76
|
+
* ===================================================================== */
|
|
77
|
+
|
|
78
|
+
/* =====================================================================
|
|
79
|
+
* SECTION 1 — KNOBS
|
|
80
|
+
* =====================================================================
|
|
81
|
+
*
|
|
82
|
+
* Five tiers, ordered by how often you'd touch them. Override any of
|
|
83
|
+
* these in your own `:root` (or `html.dark` for per-mode tuning) —
|
|
84
|
+
* your declaration wins by source order.
|
|
85
|
+
*
|
|
86
|
+
* Tier 1 — SEEDS brand-hue + chroma. Rebrand in 2 lines.
|
|
87
|
+
* Tier 2 — PER-FLAVOR ANCHORS each flavor's hue + chroma.
|
|
88
|
+
* Tier 3 — L-CURVE 5 lightness stops for the emphasis ramp.
|
|
89
|
+
* Tier 4 — SATURATION CURVE per-shade chroma multipliers.
|
|
90
|
+
* Tier 5 — PER-FLAVOR L-FACTOR per-flavor lightness multiplier — push
|
|
91
|
+
* one flavor up or down without touching
|
|
92
|
+
* the others. Default 1.
|
|
93
|
+
* Tier 6 — SOLID FILLS solid-button system: hover/active/tone
|
|
94
|
+
* L offsets + per-theme dim/desaturate.
|
|
95
|
+
* ===================================================================== */
|
|
96
|
+
|
|
97
|
+
:root {
|
|
98
|
+
/* ----------------------------------------------------------------
|
|
99
|
+
* Tier 1 — SEEDS
|
|
100
|
+
* Brand-hue + chroma drive primary, neutral, surfaces, inputs,
|
|
101
|
+
* solid buttons. One slider rebrands the page.
|
|
102
|
+
* --------------------------------------------------------------*/
|
|
103
|
+
|
|
104
|
+
--ty-brand-hue: 45;
|
|
105
|
+
--ty-brand-chroma: 0.125; /* restrained default; the loud 0.2 read as "bollywood" */
|
|
106
|
+
|
|
107
|
+
/* Surface tint. 0 = monochrome surfaces (default, no brand leak).
|
|
108
|
+
* Bump to ~0.005 (light) / ~0.012 (dark) to warm surfaces toward brand. */
|
|
109
|
+
--ty-surface-chroma: 0;
|
|
110
|
+
|
|
111
|
+
/* ----------------------------------------------------------------
|
|
112
|
+
* Tier 2 — PER-FLAVOR ANCHORS
|
|
113
|
+
* Semantic colors (success/warning/danger/neutral) have their own
|
|
114
|
+
* hue + chroma seeds so they keep meaning across brand changes.
|
|
115
|
+
* Override any individually:
|
|
116
|
+
* --ty-success-hue: 160; (more teal)
|
|
117
|
+
* --ty-warning-chroma: 0.2; (more vivid)
|
|
118
|
+
* --------------------------------------------------------------*/
|
|
119
|
+
|
|
120
|
+
--ty-success-hue: 145;
|
|
121
|
+
--ty-success-chroma: calc(var(--ty-brand-chroma) * 1.08);
|
|
122
|
+
|
|
123
|
+
--ty-warning-hue: 75;
|
|
124
|
+
--ty-warning-chroma: calc(var(--ty-brand-chroma) * 2);
|
|
125
|
+
|
|
126
|
+
--ty-danger-hue: 25;
|
|
127
|
+
--ty-danger-chroma: calc(var(--ty-brand-chroma) * 1.31);
|
|
128
|
+
|
|
129
|
+
/* Neutral is ACHROMATIC by default — greys do not follow the brand.
|
|
130
|
+
* Most of an interface is monochrome; a rebrand should not drift it.
|
|
131
|
+
* To warm greys toward the brand (the pre-2026-08 behavior), opt in:
|
|
132
|
+
* --ty-neutral-hue: var(--ty-brand-hue);
|
|
133
|
+
* --ty-neutral-chroma: calc(var(--ty-brand-chroma) * 0.04); */
|
|
134
|
+
--ty-neutral-hue: 0;
|
|
135
|
+
--ty-neutral-chroma: 0;
|
|
136
|
+
|
|
137
|
+
/* ----------------------------------------------------------------
|
|
138
|
+
* Tier 3 — L-CURVE (light mode)
|
|
139
|
+
* 5 lightness stops per flavor for the emphasis ramp.
|
|
140
|
+
* Lower L = darker = more emphasis in light mode.
|
|
141
|
+
* Plus 3 bg L stops for the soft-tint backgrounds.
|
|
142
|
+
* --------------------------------------------------------------*/
|
|
143
|
+
|
|
144
|
+
--ty-l-strong: 0.38; /* ++ max emphasis */
|
|
145
|
+
--ty-l-bold: 0.46; /* + high emphasis */
|
|
146
|
+
--ty-l-base: 0.54; /* body */
|
|
147
|
+
--ty-l-soft: 0.72; /* - low emphasis */
|
|
148
|
+
--ty-l-faint: 0.88; /* -- min emphasis */
|
|
149
|
+
|
|
150
|
+
--ty-l-bg-base: 0.96;
|
|
151
|
+
--ty-l-bg-bold: 0.92;
|
|
152
|
+
--ty-l-bg-soft: 0.98;
|
|
153
|
+
|
|
154
|
+
/* Text ladder (--ty-text-*) and surface borders — historically
|
|
155
|
+
* hardcoded hexes in tyrell.css that a rebrand never touched; now
|
|
156
|
+
* engine-wired at the SAME lightness the hexes had (measured via
|
|
157
|
+
* oklch(from #hex l c h)), tinted by the neutral seeds. At the
|
|
158
|
+
* default --ty-neutral-chroma (≈0.005) the tint is imperceptible. */
|
|
159
|
+
--ty-l-text-strong: 0; /* was #000 */
|
|
160
|
+
--ty-l-text-bold: 0; /* was #000 */
|
|
161
|
+
--ty-l-text-base: 0.21; /* was #111827 */
|
|
162
|
+
--ty-l-text-soft: 0.37; /* was #374151 */
|
|
163
|
+
--ty-l-text-faint: 0.71; /* was #9ca3af */
|
|
164
|
+
|
|
165
|
+
--ty-l-border-content: 0.93; /* was #e5e7eb */
|
|
166
|
+
--ty-l-border-elevated: 0.93;
|
|
167
|
+
--ty-l-border-floating: 0.93;
|
|
168
|
+
|
|
169
|
+
/* Generic border ladder — borders are their OWN family, not ink.
|
|
170
|
+
* Historically --ty-border-* aliased the neutral text ramp; that tied
|
|
171
|
+
* app chrome to the text emphasis curve (and to --ty-neutral-l-factor),
|
|
172
|
+
* so tuning text moved every border. Defaults preserve the exact L the
|
|
173
|
+
* aliases produced. Borders sit relative to the surfaces they separate;
|
|
174
|
+
* tune them here without touching text. */
|
|
175
|
+
--ty-l-border-strong: 0.46; /* was color-neutral-bold */
|
|
176
|
+
--ty-l-border-bold: 0.64;
|
|
177
|
+
--ty-l-border: 0.76; /* was color-neutral-soft */
|
|
178
|
+
--ty-l-border-soft: 0.88; /* was color-neutral-faint */
|
|
179
|
+
--ty-l-border-faint: 0.92;
|
|
180
|
+
|
|
181
|
+
/* Surface ladder + remaining per-mode absolutes, as L dials. These were
|
|
182
|
+
* whole oklch() declarations swapped per mode; as numeric dials they are
|
|
183
|
+
* (a) consistent with every other family and (b) interpolable — which is
|
|
184
|
+
* what lets theme/mode switches ANIMATE (see THEME TRANSITIONS at the
|
|
185
|
+
* end of this file). */
|
|
186
|
+
--ty-l-surface-canvas: 0.985;
|
|
187
|
+
--ty-l-surface-content: 1;
|
|
188
|
+
--ty-l-surface-elevated: 1;
|
|
189
|
+
--ty-l-surface-floating: 1;
|
|
190
|
+
--ty-l-surface-input: 1;
|
|
191
|
+
|
|
192
|
+
--ty-l-solid-neutral: 0.4; /* the neutral "ink" fill — dark in BOTH modes */
|
|
193
|
+
/* neutral+ is FULL-CONTRAST ink — near-black on light, near-white on dark
|
|
194
|
+
(mode block below) — not "anchor + shared offset" like other tones: the
|
|
195
|
+
max-emphasis monochrome button is an absolute, not a nudge. Matches the
|
|
196
|
+
static tyrell.css light value (#000) that predates this dial. */
|
|
197
|
+
--ty-l-solid-neutral-strong: 0.15;
|
|
198
|
+
--ty-l-bg-neutral-strong: 0.25; /* opposes the mode: dark bg on light page */
|
|
199
|
+
--ty-l-bg-neutral-faint: 0.99; /* follows the mode */
|
|
200
|
+
--ty-c-bg-neutral-faint-mult: 0.4;
|
|
201
|
+
|
|
202
|
+
--ty-focus-ring-alpha: 5%; /* focus ring mix strength (dark needs more) */
|
|
203
|
+
|
|
204
|
+
/* ----------------------------------------------------------------
|
|
205
|
+
* Tier 4 — SATURATION CURVE
|
|
206
|
+
* Per-shade chroma multipliers. Each shade's chroma =
|
|
207
|
+
* flavor-chroma × multiplier. Drops near the extremes so
|
|
208
|
+
* near-white and near-black can hold their tint.
|
|
209
|
+
* --------------------------------------------------------------*/
|
|
210
|
+
|
|
211
|
+
--ty-c-strong-mult: 0.77;
|
|
212
|
+
--ty-c-bold-mult: 1;
|
|
213
|
+
--ty-c-base-mult: 0.92;
|
|
214
|
+
--ty-c-soft-mult: 0.77;
|
|
215
|
+
--ty-c-faint-mult: 0.46;
|
|
216
|
+
|
|
217
|
+
--ty-c-bg-base-mult: 0.15;
|
|
218
|
+
--ty-c-bg-bold-mult: 0.38;
|
|
219
|
+
--ty-c-bg-soft-mult: 0.08;
|
|
220
|
+
|
|
221
|
+
/* ----------------------------------------------------------------
|
|
222
|
+
* Tier 5 — PER-FLAVOR L-FACTOR
|
|
223
|
+
* Multiplies the L-curve values for that flavor only. Default 1 =
|
|
224
|
+
* no change. Useful when one flavor's brand-default sits too close
|
|
225
|
+
* to brand-hue on the wheel and the buttons blend.
|
|
226
|
+
*
|
|
227
|
+
* Example: brand-hue: 47° (gold). Warning sits at 75° (amber).
|
|
228
|
+
* Both render as similar warm browns at brand-chroma. Drop warning
|
|
229
|
+
* a notch and it darkens enough to stand apart:
|
|
230
|
+
* --ty-warning-l-factor: 0.85;
|
|
231
|
+
*
|
|
232
|
+
* NOTE: the L-curve flips between light and dark mode, so a factor
|
|
233
|
+
* < 1 darkens in light mode but DIMS in dark mode. If you want
|
|
234
|
+
* symmetric "more emphatic" in both modes, set the factor here for
|
|
235
|
+
* light AND set its inverse (1 / factor, roughly) in `html.dark`.
|
|
236
|
+
* --------------------------------------------------------------*/
|
|
237
|
+
|
|
238
|
+
--ty-primary-l-factor: 1;
|
|
239
|
+
--ty-success-l-factor: 1;
|
|
240
|
+
--ty-warning-l-factor: 1.15;
|
|
241
|
+
--ty-danger-l-factor: 1;
|
|
242
|
+
--ty-neutral-l-factor: 1;
|
|
243
|
+
|
|
244
|
+
/* ----------------------------------------------------------------
|
|
245
|
+
* Tier 6 — SOLID FILLS
|
|
246
|
+
* Solid buttons are their OWN system, not the emphasis ramp. Each
|
|
247
|
+
* flavor's fill defaults to --ty-color-{flavor}; the knobs below
|
|
248
|
+
* derive its hover / active / tone+ / tone- and per-theme adjust.
|
|
249
|
+
* Math lives in SECTION 2 (search "Tier 6 — SOLID"); these are the
|
|
250
|
+
* dials.
|
|
251
|
+
*
|
|
252
|
+
* Axis A — interaction & tone, OKLCH L offsets on the fill.
|
|
253
|
+
* Axis B — per-theme adjust applied to the base fill (dim/desaturate).
|
|
254
|
+
*
|
|
255
|
+
* NOTE: like Tier 5, the emphasis curve flips for dark, so these L
|
|
256
|
+
* offsets are sign-flipped in `html.dark` below (darken in light =
|
|
257
|
+
* lighten in dark). Keep the two blocks in sync.
|
|
258
|
+
* --------------------------------------------------------------*/
|
|
259
|
+
|
|
260
|
+
/* Axis A — interaction (light: darken on press, so offsets are negative) */
|
|
261
|
+
--ty-solid-hover-l: -0.04; /* :hover */
|
|
262
|
+
--ty-solid-active-l: -0.08; /* :active */
|
|
263
|
+
--ty-solid-strong-l: -0.06; /* tone+ */
|
|
264
|
+
--ty-solid-soft-l: 0.1; /* tone- */
|
|
265
|
+
|
|
266
|
+
/* Axis B — per-theme adjust (light reads fine → identity) */
|
|
267
|
+
--ty-solid-l: 0; /* lightness offset — negative dims */
|
|
268
|
+
--ty-solid-c: 1; /* chroma multiplier — <1 desaturates */
|
|
269
|
+
--ty-solid-h: 0; /* hue offset (deg) */
|
|
270
|
+
|
|
271
|
+
/* Axis C — per-flavor solid anchor lift (added to the base fill's L,
|
|
272
|
+
* tones/hover/active then derive from the lifted anchor). The solid
|
|
273
|
+
* ladder's "darker = stronger" is FALSE for the yellow family: darkened
|
|
274
|
+
* hue-75 is brown, so warning's whole ladder shifts UP instead — soft
|
|
275
|
+
* 0.82 pale amber, base 0.72 vivid orange, strong 0.66 deep orange, all
|
|
276
|
+
* black-text (Material treats amber the same way). Other flavors: 0. */
|
|
277
|
+
--ty-primary-solid-l: 0;
|
|
278
|
+
--ty-success-solid-l: 0;
|
|
279
|
+
--ty-warning-solid-l: 0.1;
|
|
280
|
+
--ty-danger-solid-l: 0;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/* Dark mode overrides for the L-curve and saturation curve. Tier 1 + 2
|
|
284
|
+
* seeds and Tier 5 L-factors carry through unchanged from :root. */
|
|
285
|
+
html.dark,
|
|
286
|
+
html[data-theme="dark"],
|
|
287
|
+
[data-ty-theme].dark,
|
|
288
|
+
[data-ty-theme][data-theme="dark"] {
|
|
289
|
+
/* Tier 3 dark — inverted curve. Higher L = lighter text = more
|
|
290
|
+
* emphasis on a dark background. */
|
|
291
|
+
--ty-l-strong: 0.72;
|
|
292
|
+
--ty-l-bold: 0.66;
|
|
293
|
+
--ty-l-base: 0.62;
|
|
294
|
+
--ty-l-soft: 0.46;
|
|
295
|
+
--ty-l-faint: 0.3;
|
|
296
|
+
|
|
297
|
+
--ty-l-bg-base: 0.22;
|
|
298
|
+
--ty-l-bg-bold: 0.26;
|
|
299
|
+
--ty-l-bg-soft: 0.19;
|
|
300
|
+
|
|
301
|
+
/* Text ladder + surface borders dark — L matched to the hexes
|
|
302
|
+
* tyrell.css used to hardcode (#fff/#f9fafb/#d6d6d6/#7f8590/#555a63,
|
|
303
|
+
* borders #030712/#414141/#494949). */
|
|
304
|
+
--ty-l-text-strong: 1;
|
|
305
|
+
--ty-l-text-bold: 0.985;
|
|
306
|
+
--ty-l-text-base: 0.88;
|
|
307
|
+
--ty-l-text-soft: 0.62;
|
|
308
|
+
--ty-l-text-faint: 0.47;
|
|
309
|
+
|
|
310
|
+
--ty-l-border-content: 0.13;
|
|
311
|
+
--ty-l-border-elevated: 0.375;
|
|
312
|
+
--ty-l-border-floating: 0.41;
|
|
313
|
+
|
|
314
|
+
--ty-l-border-strong: 0.66;
|
|
315
|
+
--ty-l-border-bold: 0.46;
|
|
316
|
+
--ty-l-border: 0.38;
|
|
317
|
+
--ty-l-border-soft: 0.3;
|
|
318
|
+
--ty-l-border-faint: 0.3;
|
|
319
|
+
|
|
320
|
+
/* Surface ladder + absolutes dark — hand-tuned values, now as dials. */
|
|
321
|
+
--ty-l-surface-canvas: 0.12;
|
|
322
|
+
--ty-l-surface-content: 0.16;
|
|
323
|
+
--ty-l-surface-elevated: 0.19;
|
|
324
|
+
--ty-l-surface-floating: 0.22;
|
|
325
|
+
--ty-l-surface-input: 0.18;
|
|
326
|
+
|
|
327
|
+
--ty-l-solid-neutral: 0.18;
|
|
328
|
+
--ty-l-solid-neutral-strong: 0.88; /* inverted ink: white button, black text */
|
|
329
|
+
--ty-l-bg-neutral-strong: 0.95;
|
|
330
|
+
--ty-l-bg-neutral-faint: 0.15;
|
|
331
|
+
--ty-c-bg-neutral-faint-mult: 2;
|
|
332
|
+
|
|
333
|
+
/* Tier 5 dark — neutral inks pulled down a notch against dark surfaces. */
|
|
334
|
+
--ty-neutral-l-factor: 0.8;
|
|
335
|
+
|
|
336
|
+
--ty-focus-ring-alpha: 20%;
|
|
337
|
+
|
|
338
|
+
/* Tier 4 dark — dim shades hold more chroma so they don't grey out;
|
|
339
|
+
* strong shades trim chroma so bright tones don't over-pop. */
|
|
340
|
+
--ty-c-strong-mult: 0.77;
|
|
341
|
+
--ty-c-bold-mult: 1;
|
|
342
|
+
--ty-c-base-mult: 0.92;
|
|
343
|
+
--ty-c-soft-mult: 0.77;
|
|
344
|
+
--ty-c-faint-mult: 0.5;
|
|
345
|
+
|
|
346
|
+
--ty-c-bg-base-mult: 0.38;
|
|
347
|
+
--ty-c-bg-bold-mult: 0.54;
|
|
348
|
+
--ty-c-bg-soft-mult: 0.23;
|
|
349
|
+
|
|
350
|
+
/* Tier 6 dark — interaction offsets flip sign (press LIGHTENS on dark),
|
|
351
|
+
* and the per-theme adjust dims + desaturates the fills against the
|
|
352
|
+
* dark canvas. (Computed solid tokens are declared once at html:root.) */
|
|
353
|
+
/* Bigger than light mode's 0.04/0.08: small L deltas at the dark end of
|
|
354
|
+
* an emissive screen read much weaker than the same delta mid-scale, so
|
|
355
|
+
* dark hover needs more push to be felt at all. */
|
|
356
|
+
--ty-solid-hover-l: 0.07; /* :hover */
|
|
357
|
+
--ty-solid-active-l: 0.11; /* :active */
|
|
358
|
+
--ty-solid-strong-l: 0.06; /* tone+ */
|
|
359
|
+
--ty-solid-soft-l: -0.1; /* tone- */
|
|
360
|
+
|
|
361
|
+
--ty-solid-l: -0.2; /* dim against dark canvas */
|
|
362
|
+
--ty-solid-c: 0.7; /* desaturate against dark canvas */
|
|
363
|
+
--ty-solid-h: 0; /* hue offset */
|
|
364
|
+
|
|
365
|
+
/* Axis C — dark warning fills are already dim enough not to brown out
|
|
366
|
+
* (and browns read intentional on dark); no lift needed. */
|
|
367
|
+
--ty-warning-solid-l: 0;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/* =====================================================================
|
|
371
|
+
* SECTION 2 — IMPLEMENTATION
|
|
372
|
+
* =====================================================================
|
|
373
|
+
*
|
|
374
|
+
* The oklch() expressions that turn Section 1's knobs into the actual
|
|
375
|
+
* --ty-color-*, --ty-bg-*, --ty-border-*, --ty-surface-*, --ty-input-*,
|
|
376
|
+
* and --ty-solid-* tokens that components read.
|
|
377
|
+
*
|
|
378
|
+
* Pattern for each flavor's 5-shade fg ramp + 3-shade bg ramp:
|
|
379
|
+
*
|
|
380
|
+
* --ty-color-{flavor}-{shade}: oklch(
|
|
381
|
+
* calc(var(--ty-l-{shade}) * var(--ty-{flavor}-l-factor)) ← L
|
|
382
|
+
* calc(var(--ty-{flavor}-chroma) * var(--ty-c-{shade}-mult)) ← C
|
|
383
|
+
* var(--ty-{flavor}-hue) ← H
|
|
384
|
+
* );
|
|
385
|
+
*
|
|
386
|
+
* Formulas are declared ONCE, at `html:root` (specificity 0,1,1 — NOT
|
|
387
|
+
* plain `:root` (0,1,0)): they out-rank tyrell.css's hardcoded light
|
|
388
|
+
* tokens by specificity and its hardcoded `html.dark` hexes (0,1,1) by
|
|
389
|
+
* source order, since the brand layer loads after. Dark mode needs no
|
|
390
|
+
* formula duplicates — the dials they read (Tier 3/4, SECTION 1) are
|
|
391
|
+
* what flip per mode. The `html.dark` block at the END of this file
|
|
392
|
+
* holds only genuine per-mode DATA (surface ladder, hand-pinned
|
|
393
|
+
* absolutes) — never formulas. If you add a token here, do NOT mirror
|
|
394
|
+
* it there unless its VALUE is mode-specific.
|
|
395
|
+
* ===================================================================== */
|
|
396
|
+
|
|
397
|
+
html:root,
|
|
398
|
+
[data-ty-theme] {
|
|
399
|
+
/* ----------------------------------------------------------------
|
|
400
|
+
* Flavor color ramps (fg + bg + border)
|
|
401
|
+
*
|
|
402
|
+
* SEED INGESTION — every flavor resolves ONE seed color, and every
|
|
403
|
+
* ramp formula reads that seed's c + h channels via relative color
|
|
404
|
+
* syntax; L always comes from the mode-flipped curve. Two ways in:
|
|
405
|
+
*
|
|
406
|
+
* numbers (default) — the Tier 1/2 hue+chroma dials construct the
|
|
407
|
+
* seed: --ty-brand-hue: 200; --ty-brand-chroma: 0.13;
|
|
408
|
+
*
|
|
409
|
+
* a color — set the seed directly and the dials are bypassed:
|
|
410
|
+
* --ty-primary-seed: #76467c;
|
|
411
|
+
* --ty-danger-seed: crimson;
|
|
412
|
+
*
|
|
413
|
+
* The seed's LIGHTNESS is discarded by design: a color's identity
|
|
414
|
+
* here is hue + chroma; where each shade sits per mode is the
|
|
415
|
+
* L-curve's job. That is what makes dark mode, tones and contrast
|
|
416
|
+
* correct for ANY seed — light or dark. (Your exact pixel may
|
|
417
|
+
* appear nowhere; pin --ty-solid-X etc. if you need it literally.)
|
|
418
|
+
* --------------------------------------------------------------*/
|
|
419
|
+
--ty-primary-seed-resolved: var(
|
|
420
|
+
--ty-primary-seed,
|
|
421
|
+
oklch(0.5 var(--ty-brand-chroma) var(--ty-brand-hue))
|
|
422
|
+
);
|
|
423
|
+
--ty-success-seed-resolved: var(
|
|
424
|
+
--ty-success-seed,
|
|
425
|
+
oklch(0.5 var(--ty-success-chroma) var(--ty-success-hue))
|
|
426
|
+
);
|
|
427
|
+
--ty-warning-seed-resolved: var(
|
|
428
|
+
--ty-warning-seed,
|
|
429
|
+
oklch(0.5 var(--ty-warning-chroma) var(--ty-warning-hue))
|
|
430
|
+
);
|
|
431
|
+
--ty-danger-seed-resolved: var(
|
|
432
|
+
--ty-danger-seed,
|
|
433
|
+
oklch(0.5 var(--ty-danger-chroma) var(--ty-danger-hue))
|
|
434
|
+
);
|
|
435
|
+
--ty-neutral-seed-resolved: var(
|
|
436
|
+
--ty-neutral-seed,
|
|
437
|
+
oklch(0.5 var(--ty-neutral-chroma) var(--ty-neutral-hue))
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
/* Primary */
|
|
441
|
+
--ty-color-primary-strong: oklch(
|
|
442
|
+
from var(--ty-primary-seed-resolved)
|
|
443
|
+
calc(var(--ty-l-strong) * var(--ty-primary-l-factor))
|
|
444
|
+
calc(c * var(--ty-c-strong-mult)) h
|
|
445
|
+
);
|
|
446
|
+
--ty-color-primary-bold: oklch(
|
|
447
|
+
from var(--ty-primary-seed-resolved)
|
|
448
|
+
calc(var(--ty-l-bold) * var(--ty-primary-l-factor))
|
|
449
|
+
calc(c * var(--ty-c-bold-mult)) h
|
|
450
|
+
);
|
|
451
|
+
--ty-color-primary: oklch(
|
|
452
|
+
from var(--ty-primary-seed-resolved)
|
|
453
|
+
calc(var(--ty-l-base) * var(--ty-primary-l-factor))
|
|
454
|
+
calc(c * var(--ty-c-base-mult)) h
|
|
455
|
+
);
|
|
456
|
+
--ty-color-primary-soft: oklch(
|
|
457
|
+
from var(--ty-primary-seed-resolved)
|
|
458
|
+
calc(var(--ty-l-soft) * var(--ty-primary-l-factor))
|
|
459
|
+
calc(c * var(--ty-c-soft-mult)) h
|
|
460
|
+
);
|
|
461
|
+
--ty-color-primary-faint: oklch(
|
|
462
|
+
from var(--ty-primary-seed-resolved)
|
|
463
|
+
calc(var(--ty-l-faint) * var(--ty-primary-l-factor))
|
|
464
|
+
calc(c * var(--ty-c-faint-mult)) h
|
|
465
|
+
);
|
|
466
|
+
--ty-bg-primary: oklch(
|
|
467
|
+
from var(--ty-primary-seed-resolved)
|
|
468
|
+
calc(var(--ty-l-bg-base) * var(--ty-primary-l-factor))
|
|
469
|
+
calc(c * var(--ty-c-bg-base-mult)) h
|
|
470
|
+
);
|
|
471
|
+
--ty-bg-primary-bold: oklch(
|
|
472
|
+
from var(--ty-primary-seed-resolved)
|
|
473
|
+
calc(var(--ty-l-bg-bold) * var(--ty-primary-l-factor))
|
|
474
|
+
calc(c * var(--ty-c-bg-bold-mult)) h
|
|
475
|
+
);
|
|
476
|
+
--ty-bg-primary-soft: oklch(
|
|
477
|
+
from var(--ty-primary-seed-resolved)
|
|
478
|
+
calc(var(--ty-l-bg-soft) * var(--ty-primary-l-factor))
|
|
479
|
+
calc(c * var(--ty-c-bg-soft-mult)) h
|
|
480
|
+
);
|
|
481
|
+
--ty-border-primary: var(--ty-color-primary-soft);
|
|
482
|
+
|
|
483
|
+
/* Success */
|
|
484
|
+
--ty-color-success-strong: oklch(
|
|
485
|
+
from var(--ty-success-seed-resolved)
|
|
486
|
+
calc(var(--ty-l-strong) * var(--ty-success-l-factor))
|
|
487
|
+
calc(c * var(--ty-c-strong-mult)) h
|
|
488
|
+
);
|
|
489
|
+
--ty-color-success-bold: oklch(
|
|
490
|
+
from var(--ty-success-seed-resolved)
|
|
491
|
+
calc(var(--ty-l-bold) * var(--ty-success-l-factor))
|
|
492
|
+
calc(c * var(--ty-c-bold-mult)) h
|
|
493
|
+
);
|
|
494
|
+
--ty-color-success: oklch(
|
|
495
|
+
from var(--ty-success-seed-resolved)
|
|
496
|
+
calc(var(--ty-l-base) * var(--ty-success-l-factor))
|
|
497
|
+
calc(c * var(--ty-c-base-mult)) h
|
|
498
|
+
);
|
|
499
|
+
--ty-color-success-soft: oklch(
|
|
500
|
+
from var(--ty-success-seed-resolved)
|
|
501
|
+
calc(var(--ty-l-soft) * var(--ty-success-l-factor))
|
|
502
|
+
calc(c * var(--ty-c-soft-mult)) h
|
|
503
|
+
);
|
|
504
|
+
--ty-color-success-faint: oklch(
|
|
505
|
+
from var(--ty-success-seed-resolved)
|
|
506
|
+
calc(var(--ty-l-faint) * var(--ty-success-l-factor))
|
|
507
|
+
calc(c * var(--ty-c-faint-mult)) h
|
|
508
|
+
);
|
|
509
|
+
--ty-bg-success: oklch(
|
|
510
|
+
from var(--ty-success-seed-resolved)
|
|
511
|
+
calc(var(--ty-l-bg-base) * var(--ty-success-l-factor))
|
|
512
|
+
calc(c * var(--ty-c-bg-base-mult)) h
|
|
513
|
+
);
|
|
514
|
+
--ty-bg-success-bold: oklch(
|
|
515
|
+
from var(--ty-success-seed-resolved)
|
|
516
|
+
calc(var(--ty-l-bg-bold) * var(--ty-success-l-factor))
|
|
517
|
+
calc(c * var(--ty-c-bg-bold-mult)) h
|
|
518
|
+
);
|
|
519
|
+
--ty-bg-success-soft: oklch(
|
|
520
|
+
from var(--ty-success-seed-resolved)
|
|
521
|
+
calc(var(--ty-l-bg-soft) * var(--ty-success-l-factor))
|
|
522
|
+
calc(c * var(--ty-c-bg-soft-mult)) h
|
|
523
|
+
);
|
|
524
|
+
--ty-border-success: var(--ty-color-success-soft);
|
|
525
|
+
|
|
526
|
+
/* Danger */
|
|
527
|
+
--ty-color-danger-strong: oklch(
|
|
528
|
+
from var(--ty-danger-seed-resolved)
|
|
529
|
+
calc(var(--ty-l-strong) * var(--ty-danger-l-factor))
|
|
530
|
+
calc(c * var(--ty-c-strong-mult)) h
|
|
531
|
+
);
|
|
532
|
+
--ty-color-danger-bold: oklch(
|
|
533
|
+
from var(--ty-danger-seed-resolved)
|
|
534
|
+
calc(var(--ty-l-bold) * var(--ty-danger-l-factor))
|
|
535
|
+
calc(c * var(--ty-c-bold-mult)) h
|
|
536
|
+
);
|
|
537
|
+
--ty-color-danger: oklch(
|
|
538
|
+
from var(--ty-danger-seed-resolved)
|
|
539
|
+
calc(var(--ty-l-base) * var(--ty-danger-l-factor))
|
|
540
|
+
calc(c * var(--ty-c-base-mult)) h
|
|
541
|
+
);
|
|
542
|
+
--ty-color-danger-soft: oklch(
|
|
543
|
+
from var(--ty-danger-seed-resolved)
|
|
544
|
+
calc(var(--ty-l-soft) * var(--ty-danger-l-factor))
|
|
545
|
+
calc(c * var(--ty-c-soft-mult)) h
|
|
546
|
+
);
|
|
547
|
+
--ty-color-danger-faint: oklch(
|
|
548
|
+
from var(--ty-danger-seed-resolved)
|
|
549
|
+
calc(var(--ty-l-faint) * var(--ty-danger-l-factor))
|
|
550
|
+
calc(c * var(--ty-c-faint-mult)) h
|
|
551
|
+
);
|
|
552
|
+
--ty-bg-danger: oklch(
|
|
553
|
+
from var(--ty-danger-seed-resolved)
|
|
554
|
+
calc(var(--ty-l-bg-base) * var(--ty-danger-l-factor))
|
|
555
|
+
calc(c * var(--ty-c-bg-base-mult)) h
|
|
556
|
+
);
|
|
557
|
+
--ty-bg-danger-bold: oklch(
|
|
558
|
+
from var(--ty-danger-seed-resolved)
|
|
559
|
+
calc(var(--ty-l-bg-bold) * var(--ty-danger-l-factor))
|
|
560
|
+
calc(c * var(--ty-c-bg-bold-mult)) h
|
|
561
|
+
);
|
|
562
|
+
--ty-bg-danger-soft: oklch(
|
|
563
|
+
from var(--ty-danger-seed-resolved)
|
|
564
|
+
calc(var(--ty-l-bg-soft) * var(--ty-danger-l-factor))
|
|
565
|
+
calc(c * var(--ty-c-bg-soft-mult)) h
|
|
566
|
+
);
|
|
567
|
+
--ty-border-danger: var(--ty-color-danger-soft);
|
|
568
|
+
|
|
569
|
+
/* Warning */
|
|
570
|
+
--ty-color-warning-strong: oklch(
|
|
571
|
+
from var(--ty-warning-seed-resolved)
|
|
572
|
+
calc(var(--ty-l-strong) * var(--ty-warning-l-factor))
|
|
573
|
+
calc(c * var(--ty-c-strong-mult)) h
|
|
574
|
+
);
|
|
575
|
+
--ty-color-warning-bold: oklch(
|
|
576
|
+
from var(--ty-warning-seed-resolved)
|
|
577
|
+
calc(var(--ty-l-bold) * var(--ty-warning-l-factor))
|
|
578
|
+
calc(c * var(--ty-c-bold-mult)) h
|
|
579
|
+
);
|
|
580
|
+
--ty-color-warning: oklch(
|
|
581
|
+
from var(--ty-warning-seed-resolved)
|
|
582
|
+
calc(var(--ty-l-base) * var(--ty-warning-l-factor))
|
|
583
|
+
calc(c * var(--ty-c-base-mult)) h
|
|
584
|
+
);
|
|
585
|
+
--ty-color-warning-soft: oklch(
|
|
586
|
+
from var(--ty-warning-seed-resolved)
|
|
587
|
+
calc(var(--ty-l-soft) * var(--ty-warning-l-factor))
|
|
588
|
+
calc(c * var(--ty-c-soft-mult)) h
|
|
589
|
+
);
|
|
590
|
+
--ty-color-warning-faint: oklch(
|
|
591
|
+
from var(--ty-warning-seed-resolved)
|
|
592
|
+
calc(var(--ty-l-faint) * var(--ty-warning-l-factor))
|
|
593
|
+
calc(c * var(--ty-c-faint-mult)) h
|
|
594
|
+
);
|
|
595
|
+
--ty-bg-warning: oklch(
|
|
596
|
+
from var(--ty-warning-seed-resolved)
|
|
597
|
+
calc(var(--ty-l-bg-base) * var(--ty-warning-l-factor))
|
|
598
|
+
calc(c * var(--ty-c-bg-base-mult)) h
|
|
599
|
+
);
|
|
600
|
+
--ty-bg-warning-bold: oklch(
|
|
601
|
+
from var(--ty-warning-seed-resolved)
|
|
602
|
+
calc(var(--ty-l-bg-bold) * var(--ty-warning-l-factor))
|
|
603
|
+
calc(c * var(--ty-c-bg-bold-mult)) h
|
|
604
|
+
);
|
|
605
|
+
--ty-bg-warning-soft: oklch(
|
|
606
|
+
from var(--ty-warning-seed-resolved)
|
|
607
|
+
calc(var(--ty-l-bg-soft) * var(--ty-warning-l-factor))
|
|
608
|
+
calc(c * var(--ty-c-bg-soft-mult)) h
|
|
609
|
+
);
|
|
610
|
+
--ty-border-warning: var(--ty-color-warning-soft);
|
|
611
|
+
|
|
612
|
+
/* Neutral — same L curve, near-zero chroma so the grey scale stays grey. */
|
|
613
|
+
--ty-color-neutral-strong: oklch(
|
|
614
|
+
from var(--ty-neutral-seed-resolved)
|
|
615
|
+
calc(var(--ty-l-strong) * var(--ty-neutral-l-factor))
|
|
616
|
+
calc(c * var(--ty-c-strong-mult)) h
|
|
617
|
+
);
|
|
618
|
+
--ty-color-neutral-bold: oklch(
|
|
619
|
+
from var(--ty-neutral-seed-resolved)
|
|
620
|
+
calc(var(--ty-l-bold) * var(--ty-neutral-l-factor))
|
|
621
|
+
calc(c * var(--ty-c-bold-mult)) h
|
|
622
|
+
);
|
|
623
|
+
--ty-color-neutral: oklch(
|
|
624
|
+
from var(--ty-neutral-seed-resolved)
|
|
625
|
+
calc(var(--ty-l-base) * var(--ty-neutral-l-factor))
|
|
626
|
+
calc(c * var(--ty-c-base-mult)) h
|
|
627
|
+
);
|
|
628
|
+
--ty-color-neutral-soft: oklch(
|
|
629
|
+
from var(--ty-neutral-seed-resolved)
|
|
630
|
+
calc(var(--ty-l-soft) * var(--ty-neutral-l-factor))
|
|
631
|
+
calc(c * var(--ty-c-soft-mult)) h
|
|
632
|
+
);
|
|
633
|
+
--ty-color-neutral-faint: oklch(
|
|
634
|
+
from var(--ty-neutral-seed-resolved)
|
|
635
|
+
calc(var(--ty-l-faint) * var(--ty-neutral-l-factor))
|
|
636
|
+
calc(c * var(--ty-c-faint-mult)) h
|
|
637
|
+
);
|
|
638
|
+
--ty-bg-neutral: oklch(
|
|
639
|
+
from var(--ty-neutral-seed-resolved)
|
|
640
|
+
calc(var(--ty-l-bg-base) * var(--ty-neutral-l-factor))
|
|
641
|
+
calc(c * var(--ty-c-bg-base-mult)) h
|
|
642
|
+
);
|
|
643
|
+
--ty-bg-neutral-bold: oklch(
|
|
644
|
+
from var(--ty-neutral-seed-resolved)
|
|
645
|
+
calc(var(--ty-l-bg-bold) * var(--ty-neutral-l-factor))
|
|
646
|
+
calc(c * var(--ty-c-bg-bold-mult)) h
|
|
647
|
+
);
|
|
648
|
+
--ty-bg-neutral-soft: oklch(
|
|
649
|
+
from var(--ty-neutral-seed-resolved)
|
|
650
|
+
calc(var(--ty-l-bg-soft) * var(--ty-neutral-l-factor))
|
|
651
|
+
calc(c * var(--ty-c-bg-soft-mult)) h
|
|
652
|
+
);
|
|
653
|
+
--ty-bg-neutral-strong: oklch(
|
|
654
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-bg-neutral-strong)
|
|
655
|
+
calc(c * 2) h
|
|
656
|
+
);
|
|
657
|
+
--ty-bg-neutral-faint: oklch(
|
|
658
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-bg-neutral-faint)
|
|
659
|
+
calc(c * var(--ty-c-bg-neutral-faint-mult)) h
|
|
660
|
+
);
|
|
661
|
+
|
|
662
|
+
/* ----------------------------------------------------------------
|
|
663
|
+
* Global neutral borders — own family, own L ladder (Tier 3).
|
|
664
|
+
* Tinted by the neutral seeds like everything grey, but NOT tied to
|
|
665
|
+
* the text emphasis curve or --ty-neutral-l-factor. Per-flavor
|
|
666
|
+
* accent borders (--ty-border-{flavor}) stay ink aliases — a colored
|
|
667
|
+
* border SHOULD track its flavor's ink.
|
|
668
|
+
* --------------------------------------------------------------*/
|
|
669
|
+
--ty-border-strong: oklch(
|
|
670
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-border-strong) c h
|
|
671
|
+
);
|
|
672
|
+
--ty-border: oklch(
|
|
673
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-border) c h
|
|
674
|
+
);
|
|
675
|
+
--ty-border-bold: oklch(
|
|
676
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-border-bold) c h
|
|
677
|
+
);
|
|
678
|
+
--ty-border-soft: oklch(
|
|
679
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-border-soft) c h
|
|
680
|
+
);
|
|
681
|
+
--ty-border-faint: oklch(
|
|
682
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-border-faint) c h
|
|
683
|
+
);
|
|
684
|
+
|
|
685
|
+
/* ----------------------------------------------------------------
|
|
686
|
+
* Text ladder + surface borders — engine-wired versions of tokens
|
|
687
|
+
* tyrell.css hardcodes as hexes. Own L dials (Tier 3), neutral
|
|
688
|
+
* hue/chroma tint. These out-rank the base hexes the same way every
|
|
689
|
+
* other token here does; a rebrand now reaches body text too.
|
|
690
|
+
* --------------------------------------------------------------*/
|
|
691
|
+
--ty-text-strong: oklch(
|
|
692
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-text-strong) c h
|
|
693
|
+
);
|
|
694
|
+
--ty-text-bold: oklch(
|
|
695
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-text-bold) c h
|
|
696
|
+
);
|
|
697
|
+
--ty-text: oklch(
|
|
698
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-text-base) c h
|
|
699
|
+
);
|
|
700
|
+
--ty-text-soft: oklch(
|
|
701
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-text-soft) c h
|
|
702
|
+
);
|
|
703
|
+
--ty-text-faint: oklch(
|
|
704
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-text-faint) c h
|
|
705
|
+
);
|
|
706
|
+
|
|
707
|
+
--ty-content-border: oklch(
|
|
708
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-border-content) c h
|
|
709
|
+
);
|
|
710
|
+
--ty-elevated-border: oklch(
|
|
711
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-border-elevated) c h
|
|
712
|
+
);
|
|
713
|
+
--ty-floating-border: oklch(
|
|
714
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-border-floating) c h
|
|
715
|
+
);
|
|
716
|
+
|
|
717
|
+
/* ----------------------------------------------------------------
|
|
718
|
+
* Surfaces — monochrome by default; --ty-surface-chroma warms them.
|
|
719
|
+
* --------------------------------------------------------------*/
|
|
720
|
+
--ty-surface-canvas: oklch(
|
|
721
|
+
from var(--ty-primary-seed-resolved) var(--ty-l-surface-canvas)
|
|
722
|
+
var(--ty-surface-chroma) h
|
|
723
|
+
);
|
|
724
|
+
--ty-surface-content: oklch(
|
|
725
|
+
from var(--ty-primary-seed-resolved) var(--ty-l-surface-content)
|
|
726
|
+
var(--ty-surface-chroma) h
|
|
727
|
+
);
|
|
728
|
+
--ty-surface-elevated: oklch(
|
|
729
|
+
from var(--ty-primary-seed-resolved) var(--ty-l-surface-elevated)
|
|
730
|
+
var(--ty-surface-chroma) h
|
|
731
|
+
);
|
|
732
|
+
--ty-surface-floating: oklch(
|
|
733
|
+
from var(--ty-primary-seed-resolved) var(--ty-l-surface-floating)
|
|
734
|
+
var(--ty-surface-chroma) h
|
|
735
|
+
);
|
|
736
|
+
--ty-surface-input: oklch(
|
|
737
|
+
from var(--ty-primary-seed-resolved) var(--ty-l-surface-input)
|
|
738
|
+
var(--ty-surface-chroma) h
|
|
739
|
+
);
|
|
740
|
+
|
|
741
|
+
/* ----------------------------------------------------------------
|
|
742
|
+
* Inputs — tied to neutral ramp so form controls retint with brand.
|
|
743
|
+
* --------------------------------------------------------------*/
|
|
744
|
+
--ty-input-bg: var(--ty-surface-input);
|
|
745
|
+
--ty-input-color: var(--ty-color-neutral-strong);
|
|
746
|
+
--ty-input-border: var(--ty-color-neutral-faint);
|
|
747
|
+
--ty-input-border-hover: var(--ty-color-neutral-soft);
|
|
748
|
+
--ty-input-border-focus: var(--ty-color-primary);
|
|
749
|
+
--ty-input-placeholder: var(--ty-color-neutral-soft);
|
|
750
|
+
--ty-input-disabled-bg: var(--ty-color-neutral-faint);
|
|
751
|
+
--ty-input-disabled-border: var(--ty-color-neutral-faint);
|
|
752
|
+
--ty-input-disabled-color: var(--ty-color-neutral-bold);
|
|
753
|
+
--ty-input-shadow-focus: color-mix(
|
|
754
|
+
in oklab,
|
|
755
|
+
var(--ty-color-primary) var(--ty-focus-ring-alpha),
|
|
756
|
+
transparent
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
/* ----------------------------------------------------------------
|
|
761
|
+
* Tier 6 — SOLID (implementation)
|
|
762
|
+
* Solid is its OWN system, NOT the text/emphasis ramp. The dials
|
|
763
|
+
* (--ty-solid-hover-l / -active-l / -strong-l / -soft-l and
|
|
764
|
+
* --ty-solid-l / -c / -h) live in SECTION 1, Tier 6. Below is the
|
|
765
|
+
* derivation only: base fill bakes in the per-theme adjust (Axis B);
|
|
766
|
+
* hover/active/strong/soft offset the base by Axis A. Override any
|
|
767
|
+
* single --ty-solid-{flavor}-{state} to recolor just that segment.
|
|
768
|
+
*
|
|
769
|
+
* Declared at `html:root` (specificity 0,1,1) — NOT plain `:root` (0,1,0) —
|
|
770
|
+
* on purpose: it must out-rank tyrell.css's hardcoded dark solids at
|
|
771
|
+
* `html.dark` (0,1,1). It wins light by specificity over base's `html{}`,
|
|
772
|
+
* and wins dark by source order over base's `html.dark` (brand loads after).
|
|
773
|
+
* That's what lets dark solids re-tint with --ty-brand-hue. Declared ONCE —
|
|
774
|
+
* the oklch(from var(--ty-color-*)) formulas resolve per-mode automatically,
|
|
775
|
+
* so no dark duplicate is needed.
|
|
776
|
+
* --------------------------------------------------------------*/
|
|
777
|
+
html:root,
|
|
778
|
+
[data-ty-theme] {
|
|
779
|
+
/* base fill per flavor (= flavor color, theme-adjusted by Axis B) */
|
|
780
|
+
--ty-solid-primary: oklch(
|
|
781
|
+
from var(--ty-color-primary)
|
|
782
|
+
calc(l + var(--ty-solid-l) + var(--ty-primary-solid-l, 0))
|
|
783
|
+
calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
|
|
784
|
+
);
|
|
785
|
+
--ty-solid-success: oklch(
|
|
786
|
+
from var(--ty-color-success)
|
|
787
|
+
calc(l + var(--ty-solid-l) + var(--ty-success-solid-l, 0))
|
|
788
|
+
calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
|
|
789
|
+
);
|
|
790
|
+
--ty-solid-danger: oklch(
|
|
791
|
+
from var(--ty-color-danger)
|
|
792
|
+
calc(l + var(--ty-solid-l) + var(--ty-danger-solid-l, 0))
|
|
793
|
+
calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
|
|
794
|
+
);
|
|
795
|
+
--ty-solid-warning: oklch(
|
|
796
|
+
from var(--ty-color-warning)
|
|
797
|
+
calc(l + var(--ty-solid-l) + var(--ty-warning-solid-l, 0))
|
|
798
|
+
calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
|
|
799
|
+
);
|
|
800
|
+
/* neutral is a deliberate dark grey fill, not the neutral text color */
|
|
801
|
+
--ty-solid-neutral: oklch(
|
|
802
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-solid-neutral)
|
|
803
|
+
calc(c * var(--ty-c-strong-mult)) h
|
|
804
|
+
);
|
|
805
|
+
|
|
806
|
+
/* ----------------------------------------------------------------
|
|
807
|
+
* SOLID FOREGROUNDS — auto-contrast.
|
|
808
|
+
*
|
|
809
|
+
* Each fill gets a foreground picked from its OWN lightness, so a
|
|
810
|
+
* rebrand (--ty-brand-hue / --ty-brand-chroma / any L-curve override)
|
|
811
|
+
* can't strand white text on a pale fill. Branchless, no JS:
|
|
812
|
+
*
|
|
813
|
+
* clamp(0, (threshold - l) * 1000, 1) -> 1 (white) when the fill
|
|
814
|
+
* is darker than the threshold, 0 (black) when it's lighter.
|
|
815
|
+
*
|
|
816
|
+
* One token per FILL, not per flavor — base / -soft (tone-) / -strong
|
|
817
|
+
* (tone+) each carry a different L, so each needs its own decision.
|
|
818
|
+
* Declared once: the oklch(from ...) formulas re-resolve per mode,
|
|
819
|
+
* because html.dark redefines the fills these read.
|
|
820
|
+
*
|
|
821
|
+
* TO REVERT to the old fixed-white behaviour, override in your app:
|
|
822
|
+
* :root { --ty-solid-primary-fg: white; ... }
|
|
823
|
+
* or set --ty-solid-fg-threshold: 1 to force white everywhere.
|
|
824
|
+
* --------------------------------------------------------------*/
|
|
825
|
+
|
|
826
|
+
/* Crossover point. Fills lighter than this get black text. ~0.58-0.62
|
|
827
|
+
is the sRGB break-even; higher = prefers white, lower = prefers black. */
|
|
828
|
+
--ty-solid-fg-threshold: 0.62;
|
|
829
|
+
|
|
830
|
+
--ty-solid-primary-fg: oklch(
|
|
831
|
+
from var(--ty-solid-primary)
|
|
832
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
833
|
+
);
|
|
834
|
+
--ty-solid-primary-soft-fg: oklch(
|
|
835
|
+
from var(--ty-solid-primary-soft)
|
|
836
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
837
|
+
);
|
|
838
|
+
--ty-solid-primary-strong-fg: oklch(
|
|
839
|
+
from var(--ty-solid-primary-strong)
|
|
840
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
841
|
+
);
|
|
842
|
+
|
|
843
|
+
--ty-solid-success-fg: oklch(
|
|
844
|
+
from var(--ty-solid-success)
|
|
845
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
846
|
+
);
|
|
847
|
+
--ty-solid-success-soft-fg: oklch(
|
|
848
|
+
from var(--ty-solid-success-soft)
|
|
849
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
850
|
+
);
|
|
851
|
+
--ty-solid-success-strong-fg: oklch(
|
|
852
|
+
from var(--ty-solid-success-strong)
|
|
853
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
854
|
+
);
|
|
855
|
+
|
|
856
|
+
--ty-solid-danger-fg: oklch(
|
|
857
|
+
from var(--ty-solid-danger)
|
|
858
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
859
|
+
);
|
|
860
|
+
--ty-solid-danger-soft-fg: oklch(
|
|
861
|
+
from var(--ty-solid-danger-soft)
|
|
862
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
863
|
+
);
|
|
864
|
+
--ty-solid-danger-strong-fg: oklch(
|
|
865
|
+
from var(--ty-solid-danger-strong)
|
|
866
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
867
|
+
);
|
|
868
|
+
|
|
869
|
+
--ty-solid-warning-fg: oklch(
|
|
870
|
+
from var(--ty-solid-warning)
|
|
871
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
872
|
+
);
|
|
873
|
+
--ty-solid-warning-soft-fg: oklch(
|
|
874
|
+
from var(--ty-solid-warning-soft)
|
|
875
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
876
|
+
);
|
|
877
|
+
--ty-solid-warning-strong-fg: oklch(
|
|
878
|
+
from var(--ty-solid-warning-strong)
|
|
879
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
880
|
+
);
|
|
881
|
+
|
|
882
|
+
--ty-solid-neutral-fg: oklch(
|
|
883
|
+
from var(--ty-solid-neutral)
|
|
884
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
885
|
+
);
|
|
886
|
+
--ty-solid-neutral-soft-fg: oklch(
|
|
887
|
+
from var(--ty-solid-neutral-soft)
|
|
888
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
889
|
+
);
|
|
890
|
+
--ty-solid-neutral-strong-fg: oklch(
|
|
891
|
+
from var(--ty-solid-neutral-strong)
|
|
892
|
+
clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
|
|
893
|
+
);
|
|
894
|
+
|
|
895
|
+
/* derived states — axis 2 offsets on each base fill */
|
|
896
|
+
--ty-solid-primary-hover: oklch(
|
|
897
|
+
from var(--ty-solid-primary) calc(l + var(--ty-solid-hover-l)) c h
|
|
898
|
+
);
|
|
899
|
+
--ty-solid-primary-active: oklch(
|
|
900
|
+
from var(--ty-solid-primary) calc(l + var(--ty-solid-active-l)) c h
|
|
901
|
+
);
|
|
902
|
+
--ty-solid-primary-strong: oklch(
|
|
903
|
+
from var(--ty-solid-primary) calc(l + var(--ty-solid-strong-l)) c h
|
|
904
|
+
);
|
|
905
|
+
--ty-solid-primary-soft: oklch(
|
|
906
|
+
from var(--ty-solid-primary) calc(l + var(--ty-solid-soft-l)) c h
|
|
907
|
+
);
|
|
908
|
+
|
|
909
|
+
--ty-solid-success-hover: oklch(
|
|
910
|
+
from var(--ty-solid-success) calc(l + var(--ty-solid-hover-l)) c h
|
|
911
|
+
);
|
|
912
|
+
--ty-solid-success-active: oklch(
|
|
913
|
+
from var(--ty-solid-success) calc(l + var(--ty-solid-active-l)) c h
|
|
914
|
+
);
|
|
915
|
+
--ty-solid-success-strong: oklch(
|
|
916
|
+
from var(--ty-solid-success) calc(l + var(--ty-solid-strong-l)) c h
|
|
917
|
+
);
|
|
918
|
+
--ty-solid-success-soft: oklch(
|
|
919
|
+
from var(--ty-solid-success) calc(l + var(--ty-solid-soft-l)) c h
|
|
920
|
+
);
|
|
921
|
+
|
|
922
|
+
--ty-solid-danger-hover: oklch(
|
|
923
|
+
from var(--ty-solid-danger) calc(l + var(--ty-solid-hover-l)) c h
|
|
924
|
+
);
|
|
925
|
+
--ty-solid-danger-active: oklch(
|
|
926
|
+
from var(--ty-solid-danger) calc(l + var(--ty-solid-active-l)) c h
|
|
927
|
+
);
|
|
928
|
+
--ty-solid-danger-strong: oklch(
|
|
929
|
+
from var(--ty-solid-danger) calc(l + var(--ty-solid-strong-l)) c h
|
|
930
|
+
);
|
|
931
|
+
--ty-solid-danger-soft: oklch(
|
|
932
|
+
from var(--ty-solid-danger) calc(l + var(--ty-solid-soft-l)) c h
|
|
933
|
+
);
|
|
934
|
+
|
|
935
|
+
--ty-solid-warning-hover: oklch(
|
|
936
|
+
from var(--ty-solid-warning) calc(l + var(--ty-solid-hover-l)) c h
|
|
937
|
+
);
|
|
938
|
+
--ty-solid-warning-active: oklch(
|
|
939
|
+
from var(--ty-solid-warning) calc(l + var(--ty-solid-active-l)) c h
|
|
940
|
+
);
|
|
941
|
+
--ty-solid-warning-strong: oklch(
|
|
942
|
+
from var(--ty-solid-warning) calc(l + var(--ty-solid-strong-l)) c h
|
|
943
|
+
);
|
|
944
|
+
--ty-solid-warning-soft: oklch(
|
|
945
|
+
from var(--ty-solid-warning) calc(l + var(--ty-solid-soft-l)) c h
|
|
946
|
+
);
|
|
947
|
+
|
|
948
|
+
--ty-solid-neutral-hover: oklch(
|
|
949
|
+
from var(--ty-solid-neutral) calc(l + var(--ty-solid-hover-l)) c h
|
|
950
|
+
);
|
|
951
|
+
--ty-solid-neutral-active: oklch(
|
|
952
|
+
from var(--ty-solid-neutral) calc(l + var(--ty-solid-active-l)) c h
|
|
953
|
+
);
|
|
954
|
+
/* neutral+ reads its own absolute L dial, not anchor + shared offset —
|
|
955
|
+
it's the full-contrast ink endpoint (see --ty-l-solid-neutral-strong). */
|
|
956
|
+
--ty-solid-neutral-strong: oklch(
|
|
957
|
+
from var(--ty-neutral-seed-resolved) var(--ty-l-solid-neutral-strong)
|
|
958
|
+
calc(c * var(--ty-c-strong-mult)) h
|
|
959
|
+
);
|
|
960
|
+
--ty-solid-neutral-soft: oklch(
|
|
961
|
+
from var(--ty-solid-neutral) calc(l + var(--ty-solid-soft-l)) c h
|
|
962
|
+
);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
/* =====================================================================
|
|
966
|
+
* SECTION 3 — THEME TRANSITIONS
|
|
967
|
+
* =====================================================================
|
|
968
|
+
*
|
|
969
|
+
* Every dial above is a plain number (or percentage) — and every color
|
|
970
|
+
* in the system is a pure function of those dials. Registering the
|
|
971
|
+
* dials as typed custom properties makes them INTERPOLABLE, so a theme
|
|
972
|
+
* or mode switch (html.dark, html.love, a [data-ty-theme] pack) does
|
|
973
|
+
* not snap: the dials animate, and every derived color — buttons,
|
|
974
|
+
* borders, surfaces, text, focus rings — crossfades through OKLCH
|
|
975
|
+
* space frame by frame. No JS, no repaint tricks; it falls out of the
|
|
976
|
+
* dials-not-colors architecture.
|
|
977
|
+
*
|
|
978
|
+
* Opt out (or retune) per app:
|
|
979
|
+
* :root { --ty-theme-transition: 0s; } no animation
|
|
980
|
+
* :root { --ty-theme-transition: 1.2s; } slower crossfade
|
|
981
|
+
* Reduced-motion users never get the animation.
|
|
982
|
+
*
|
|
983
|
+
* Browsers without @property simply skip registration — themes still
|
|
984
|
+
* work, switches just snap (the pre-TC37 behavior).
|
|
985
|
+
* ===================================================================== */
|
|
986
|
+
|
|
987
|
+
@property --ty-brand-hue {
|
|
988
|
+
syntax: "<number>";
|
|
989
|
+
inherits: true;
|
|
990
|
+
initial-value: 45;
|
|
991
|
+
}
|
|
992
|
+
@property --ty-brand-chroma {
|
|
993
|
+
syntax: "<number>";
|
|
994
|
+
inherits: true;
|
|
995
|
+
initial-value: 0.125;
|
|
996
|
+
}
|
|
997
|
+
@property --ty-surface-chroma {
|
|
998
|
+
syntax: "<number>";
|
|
999
|
+
inherits: true;
|
|
1000
|
+
initial-value: 0;
|
|
1001
|
+
}
|
|
1002
|
+
@property --ty-success-hue {
|
|
1003
|
+
syntax: "<number>";
|
|
1004
|
+
inherits: true;
|
|
1005
|
+
initial-value: 145;
|
|
1006
|
+
}
|
|
1007
|
+
@property --ty-success-chroma {
|
|
1008
|
+
syntax: "<number>";
|
|
1009
|
+
inherits: true;
|
|
1010
|
+
initial-value: 0.135;
|
|
1011
|
+
}
|
|
1012
|
+
@property --ty-warning-hue {
|
|
1013
|
+
syntax: "<number>";
|
|
1014
|
+
inherits: true;
|
|
1015
|
+
initial-value: 75;
|
|
1016
|
+
}
|
|
1017
|
+
@property --ty-warning-chroma {
|
|
1018
|
+
syntax: "<number>";
|
|
1019
|
+
inherits: true;
|
|
1020
|
+
initial-value: 0.25;
|
|
1021
|
+
}
|
|
1022
|
+
@property --ty-danger-hue {
|
|
1023
|
+
syntax: "<number>";
|
|
1024
|
+
inherits: true;
|
|
1025
|
+
initial-value: 25;
|
|
1026
|
+
}
|
|
1027
|
+
@property --ty-danger-chroma {
|
|
1028
|
+
syntax: "<number>";
|
|
1029
|
+
inherits: true;
|
|
1030
|
+
initial-value: 0.164;
|
|
1031
|
+
}
|
|
1032
|
+
@property --ty-neutral-hue {
|
|
1033
|
+
syntax: "<number>";
|
|
1034
|
+
inherits: true;
|
|
1035
|
+
initial-value: 0;
|
|
1036
|
+
}
|
|
1037
|
+
@property --ty-neutral-chroma {
|
|
1038
|
+
syntax: "<number>";
|
|
1039
|
+
inherits: true;
|
|
1040
|
+
initial-value: 0;
|
|
1041
|
+
}
|
|
1042
|
+
@property --ty-l-strong {
|
|
1043
|
+
syntax: "<number>";
|
|
1044
|
+
inherits: true;
|
|
1045
|
+
initial-value: 0.38;
|
|
1046
|
+
}
|
|
1047
|
+
@property --ty-l-bold {
|
|
1048
|
+
syntax: "<number>";
|
|
1049
|
+
inherits: true;
|
|
1050
|
+
initial-value: 0.46;
|
|
1051
|
+
}
|
|
1052
|
+
@property --ty-l-base {
|
|
1053
|
+
syntax: "<number>";
|
|
1054
|
+
inherits: true;
|
|
1055
|
+
initial-value: 0.54;
|
|
1056
|
+
}
|
|
1057
|
+
@property --ty-l-soft {
|
|
1058
|
+
syntax: "<number>";
|
|
1059
|
+
inherits: true;
|
|
1060
|
+
initial-value: 0.72;
|
|
1061
|
+
}
|
|
1062
|
+
@property --ty-l-faint {
|
|
1063
|
+
syntax: "<number>";
|
|
1064
|
+
inherits: true;
|
|
1065
|
+
initial-value: 0.88;
|
|
1066
|
+
}
|
|
1067
|
+
@property --ty-l-bg-base {
|
|
1068
|
+
syntax: "<number>";
|
|
1069
|
+
inherits: true;
|
|
1070
|
+
initial-value: 0.96;
|
|
1071
|
+
}
|
|
1072
|
+
@property --ty-l-bg-bold {
|
|
1073
|
+
syntax: "<number>";
|
|
1074
|
+
inherits: true;
|
|
1075
|
+
initial-value: 0.92;
|
|
1076
|
+
}
|
|
1077
|
+
@property --ty-l-bg-soft {
|
|
1078
|
+
syntax: "<number>";
|
|
1079
|
+
inherits: true;
|
|
1080
|
+
initial-value: 0.98;
|
|
1081
|
+
}
|
|
1082
|
+
@property --ty-l-text-strong {
|
|
1083
|
+
syntax: "<number>";
|
|
1084
|
+
inherits: true;
|
|
1085
|
+
initial-value: 0;
|
|
1086
|
+
}
|
|
1087
|
+
@property --ty-l-text-bold {
|
|
1088
|
+
syntax: "<number>";
|
|
1089
|
+
inherits: true;
|
|
1090
|
+
initial-value: 0;
|
|
1091
|
+
}
|
|
1092
|
+
@property --ty-l-text-base {
|
|
1093
|
+
syntax: "<number>";
|
|
1094
|
+
inherits: true;
|
|
1095
|
+
initial-value: 0.21;
|
|
1096
|
+
}
|
|
1097
|
+
@property --ty-l-text-soft {
|
|
1098
|
+
syntax: "<number>";
|
|
1099
|
+
inherits: true;
|
|
1100
|
+
initial-value: 0.37;
|
|
1101
|
+
}
|
|
1102
|
+
@property --ty-l-text-faint {
|
|
1103
|
+
syntax: "<number>";
|
|
1104
|
+
inherits: true;
|
|
1105
|
+
initial-value: 0.71;
|
|
1106
|
+
}
|
|
1107
|
+
@property --ty-l-border-content {
|
|
1108
|
+
syntax: "<number>";
|
|
1109
|
+
inherits: true;
|
|
1110
|
+
initial-value: 0.93;
|
|
1111
|
+
}
|
|
1112
|
+
@property --ty-l-border-elevated {
|
|
1113
|
+
syntax: "<number>";
|
|
1114
|
+
inherits: true;
|
|
1115
|
+
initial-value: 0.93;
|
|
1116
|
+
}
|
|
1117
|
+
@property --ty-l-border-floating {
|
|
1118
|
+
syntax: "<number>";
|
|
1119
|
+
inherits: true;
|
|
1120
|
+
initial-value: 0.93;
|
|
1121
|
+
}
|
|
1122
|
+
@property --ty-l-border-strong {
|
|
1123
|
+
syntax: "<number>";
|
|
1124
|
+
inherits: true;
|
|
1125
|
+
initial-value: 0.46;
|
|
1126
|
+
}
|
|
1127
|
+
@property --ty-l-border-bold {
|
|
1128
|
+
syntax: "<number>";
|
|
1129
|
+
inherits: true;
|
|
1130
|
+
initial-value: 0.64;
|
|
1131
|
+
}
|
|
1132
|
+
@property --ty-l-border {
|
|
1133
|
+
syntax: "<number>";
|
|
1134
|
+
inherits: true;
|
|
1135
|
+
initial-value: 0.76;
|
|
1136
|
+
}
|
|
1137
|
+
@property --ty-l-border-soft {
|
|
1138
|
+
syntax: "<number>";
|
|
1139
|
+
inherits: true;
|
|
1140
|
+
initial-value: 0.88;
|
|
1141
|
+
}
|
|
1142
|
+
@property --ty-l-border-faint {
|
|
1143
|
+
syntax: "<number>";
|
|
1144
|
+
inherits: true;
|
|
1145
|
+
initial-value: 0.92;
|
|
1146
|
+
}
|
|
1147
|
+
@property --ty-l-surface-canvas {
|
|
1148
|
+
syntax: "<number>";
|
|
1149
|
+
inherits: true;
|
|
1150
|
+
initial-value: 0.985;
|
|
1151
|
+
}
|
|
1152
|
+
@property --ty-l-surface-content {
|
|
1153
|
+
syntax: "<number>";
|
|
1154
|
+
inherits: true;
|
|
1155
|
+
initial-value: 1;
|
|
1156
|
+
}
|
|
1157
|
+
@property --ty-l-surface-elevated {
|
|
1158
|
+
syntax: "<number>";
|
|
1159
|
+
inherits: true;
|
|
1160
|
+
initial-value: 1;
|
|
1161
|
+
}
|
|
1162
|
+
@property --ty-l-surface-floating {
|
|
1163
|
+
syntax: "<number>";
|
|
1164
|
+
inherits: true;
|
|
1165
|
+
initial-value: 1;
|
|
1166
|
+
}
|
|
1167
|
+
@property --ty-l-surface-input {
|
|
1168
|
+
syntax: "<number>";
|
|
1169
|
+
inherits: true;
|
|
1170
|
+
initial-value: 1;
|
|
1171
|
+
}
|
|
1172
|
+
@property --ty-l-solid-neutral {
|
|
1173
|
+
syntax: "<number>";
|
|
1174
|
+
inherits: true;
|
|
1175
|
+
initial-value: 0.4;
|
|
1176
|
+
}
|
|
1177
|
+
@property --ty-l-solid-neutral-strong {
|
|
1178
|
+
syntax: "<number>";
|
|
1179
|
+
inherits: true;
|
|
1180
|
+
initial-value: 0.15;
|
|
1181
|
+
}
|
|
1182
|
+
@property --ty-l-bg-neutral-strong {
|
|
1183
|
+
syntax: "<number>";
|
|
1184
|
+
inherits: true;
|
|
1185
|
+
initial-value: 0.25;
|
|
1186
|
+
}
|
|
1187
|
+
@property --ty-l-bg-neutral-faint {
|
|
1188
|
+
syntax: "<number>";
|
|
1189
|
+
inherits: true;
|
|
1190
|
+
initial-value: 0.99;
|
|
1191
|
+
}
|
|
1192
|
+
@property --ty-c-bg-neutral-faint-mult {
|
|
1193
|
+
syntax: "<number>";
|
|
1194
|
+
inherits: true;
|
|
1195
|
+
initial-value: 0.4;
|
|
1196
|
+
}
|
|
1197
|
+
@property --ty-c-strong-mult {
|
|
1198
|
+
syntax: "<number>";
|
|
1199
|
+
inherits: true;
|
|
1200
|
+
initial-value: 0.77;
|
|
1201
|
+
}
|
|
1202
|
+
@property --ty-c-bold-mult {
|
|
1203
|
+
syntax: "<number>";
|
|
1204
|
+
inherits: true;
|
|
1205
|
+
initial-value: 1;
|
|
1206
|
+
}
|
|
1207
|
+
@property --ty-c-base-mult {
|
|
1208
|
+
syntax: "<number>";
|
|
1209
|
+
inherits: true;
|
|
1210
|
+
initial-value: 0.92;
|
|
1211
|
+
}
|
|
1212
|
+
@property --ty-c-soft-mult {
|
|
1213
|
+
syntax: "<number>";
|
|
1214
|
+
inherits: true;
|
|
1215
|
+
initial-value: 0.77;
|
|
1216
|
+
}
|
|
1217
|
+
@property --ty-c-faint-mult {
|
|
1218
|
+
syntax: "<number>";
|
|
1219
|
+
inherits: true;
|
|
1220
|
+
initial-value: 0.46;
|
|
1221
|
+
}
|
|
1222
|
+
@property --ty-c-bg-base-mult {
|
|
1223
|
+
syntax: "<number>";
|
|
1224
|
+
inherits: true;
|
|
1225
|
+
initial-value: 0.15;
|
|
1226
|
+
}
|
|
1227
|
+
@property --ty-c-bg-bold-mult {
|
|
1228
|
+
syntax: "<number>";
|
|
1229
|
+
inherits: true;
|
|
1230
|
+
initial-value: 0.38;
|
|
1231
|
+
}
|
|
1232
|
+
@property --ty-c-bg-soft-mult {
|
|
1233
|
+
syntax: "<number>";
|
|
1234
|
+
inherits: true;
|
|
1235
|
+
initial-value: 0.08;
|
|
1236
|
+
}
|
|
1237
|
+
@property --ty-primary-l-factor {
|
|
1238
|
+
syntax: "<number>";
|
|
1239
|
+
inherits: true;
|
|
1240
|
+
initial-value: 1;
|
|
1241
|
+
}
|
|
1242
|
+
@property --ty-success-l-factor {
|
|
1243
|
+
syntax: "<number>";
|
|
1244
|
+
inherits: true;
|
|
1245
|
+
initial-value: 1;
|
|
1246
|
+
}
|
|
1247
|
+
@property --ty-warning-l-factor {
|
|
1248
|
+
syntax: "<number>";
|
|
1249
|
+
inherits: true;
|
|
1250
|
+
initial-value: 1.15;
|
|
1251
|
+
}
|
|
1252
|
+
@property --ty-danger-l-factor {
|
|
1253
|
+
syntax: "<number>";
|
|
1254
|
+
inherits: true;
|
|
1255
|
+
initial-value: 1;
|
|
1256
|
+
}
|
|
1257
|
+
@property --ty-neutral-l-factor {
|
|
1258
|
+
syntax: "<number>";
|
|
1259
|
+
inherits: true;
|
|
1260
|
+
initial-value: 1;
|
|
1261
|
+
}
|
|
1262
|
+
/* Typography + button-depth dials (defined in tyrell.css, mode-flipped
|
|
1263
|
+
there). Registered here so they interpolate on theme switch: with a
|
|
1264
|
+
variable font, text weight crossfades along with the colors, and the
|
|
1265
|
+
solid-button depth chrome (border offset) glides rather than snaps. */
|
|
1266
|
+
@property --ty-weight-action {
|
|
1267
|
+
syntax: "<number>";
|
|
1268
|
+
inherits: true;
|
|
1269
|
+
initial-value: 510;
|
|
1270
|
+
}
|
|
1271
|
+
@property --ty-weight-label {
|
|
1272
|
+
syntax: "<number>";
|
|
1273
|
+
inherits: true;
|
|
1274
|
+
initial-value: 440;
|
|
1275
|
+
}
|
|
1276
|
+
@property --ty-button-depth {
|
|
1277
|
+
syntax: "<number>";
|
|
1278
|
+
inherits: true;
|
|
1279
|
+
initial-value: 0.35;
|
|
1280
|
+
}
|
|
1281
|
+
@property --ty-button-border-l {
|
|
1282
|
+
syntax: "<number>";
|
|
1283
|
+
inherits: true;
|
|
1284
|
+
initial-value: -0.08;
|
|
1285
|
+
}
|
|
1286
|
+
@property --ty-button-border-l-neutral {
|
|
1287
|
+
syntax: "<number>";
|
|
1288
|
+
inherits: true;
|
|
1289
|
+
initial-value: -0.25;
|
|
1290
|
+
}
|
|
1291
|
+
@property --ty-primary-solid-l {
|
|
1292
|
+
syntax: "<number>";
|
|
1293
|
+
inherits: true;
|
|
1294
|
+
initial-value: 0;
|
|
1295
|
+
}
|
|
1296
|
+
@property --ty-success-solid-l {
|
|
1297
|
+
syntax: "<number>";
|
|
1298
|
+
inherits: true;
|
|
1299
|
+
initial-value: 0;
|
|
1300
|
+
}
|
|
1301
|
+
@property --ty-warning-solid-l {
|
|
1302
|
+
syntax: "<number>";
|
|
1303
|
+
inherits: true;
|
|
1304
|
+
initial-value: 0.1;
|
|
1305
|
+
}
|
|
1306
|
+
@property --ty-danger-solid-l {
|
|
1307
|
+
syntax: "<number>";
|
|
1308
|
+
inherits: true;
|
|
1309
|
+
initial-value: 0;
|
|
1310
|
+
}
|
|
1311
|
+
@property --ty-solid-hover-l {
|
|
1312
|
+
syntax: "<number>";
|
|
1313
|
+
inherits: true;
|
|
1314
|
+
initial-value: -0.04;
|
|
1315
|
+
}
|
|
1316
|
+
@property --ty-solid-active-l {
|
|
1317
|
+
syntax: "<number>";
|
|
1318
|
+
inherits: true;
|
|
1319
|
+
initial-value: -0.08;
|
|
1320
|
+
}
|
|
1321
|
+
@property --ty-solid-strong-l {
|
|
1322
|
+
syntax: "<number>";
|
|
1323
|
+
inherits: true;
|
|
1324
|
+
initial-value: -0.06;
|
|
1325
|
+
}
|
|
1326
|
+
@property --ty-solid-soft-l {
|
|
1327
|
+
syntax: "<number>";
|
|
1328
|
+
inherits: true;
|
|
1329
|
+
initial-value: 0.1;
|
|
1330
|
+
}
|
|
1331
|
+
@property --ty-solid-l {
|
|
1332
|
+
syntax: "<number>";
|
|
1333
|
+
inherits: true;
|
|
1334
|
+
initial-value: 0;
|
|
1335
|
+
}
|
|
1336
|
+
@property --ty-solid-c {
|
|
1337
|
+
syntax: "<number>";
|
|
1338
|
+
inherits: true;
|
|
1339
|
+
initial-value: 1;
|
|
1340
|
+
}
|
|
1341
|
+
@property --ty-solid-h {
|
|
1342
|
+
syntax: "<number>";
|
|
1343
|
+
inherits: true;
|
|
1344
|
+
initial-value: 0;
|
|
1345
|
+
}
|
|
1346
|
+
@property --ty-solid-fg-threshold {
|
|
1347
|
+
syntax: "<number>";
|
|
1348
|
+
inherits: true;
|
|
1349
|
+
initial-value: 0.62;
|
|
1350
|
+
}
|
|
1351
|
+
@property --ty-focus-ring-alpha {
|
|
1352
|
+
syntax: "<percentage>";
|
|
1353
|
+
inherits: true;
|
|
1354
|
+
initial-value: 5%;
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
@property --ty-primary-seed-resolved {
|
|
1358
|
+
syntax: "<color>";
|
|
1359
|
+
inherits: true;
|
|
1360
|
+
initial-value: #808080;
|
|
1361
|
+
}
|
|
1362
|
+
@property --ty-success-seed-resolved {
|
|
1363
|
+
syntax: "<color>";
|
|
1364
|
+
inherits: true;
|
|
1365
|
+
initial-value: #808080;
|
|
1366
|
+
}
|
|
1367
|
+
@property --ty-warning-seed-resolved {
|
|
1368
|
+
syntax: "<color>";
|
|
1369
|
+
inherits: true;
|
|
1370
|
+
initial-value: #808080;
|
|
1371
|
+
}
|
|
1372
|
+
@property --ty-danger-seed-resolved {
|
|
1373
|
+
syntax: "<color>";
|
|
1374
|
+
inherits: true;
|
|
1375
|
+
initial-value: #808080;
|
|
1376
|
+
}
|
|
1377
|
+
@property --ty-neutral-seed-resolved {
|
|
1378
|
+
syntax: "<color>";
|
|
1379
|
+
inherits: true;
|
|
1380
|
+
initial-value: #808080;
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
1384
|
+
html,
|
|
1385
|
+
[data-ty-theme] {
|
|
1386
|
+
transition-property:
|
|
1387
|
+
--ty-brand-hue, --ty-brand-chroma, --ty-surface-chroma, --ty-success-hue,
|
|
1388
|
+
--ty-success-chroma, --ty-warning-hue, --ty-warning-chroma,
|
|
1389
|
+
--ty-danger-hue, --ty-danger-chroma, --ty-neutral-hue,
|
|
1390
|
+
--ty-neutral-chroma, --ty-l-strong, --ty-l-bold, --ty-l-base, --ty-l-soft,
|
|
1391
|
+
--ty-l-faint, --ty-l-bg-base, --ty-l-bg-bold, --ty-l-bg-soft,
|
|
1392
|
+
--ty-l-text-strong, --ty-l-text-bold, --ty-l-text-base, --ty-l-text-soft,
|
|
1393
|
+
--ty-l-text-faint, --ty-l-border-content, --ty-l-border-elevated,
|
|
1394
|
+
--ty-l-border-floating, --ty-l-border-strong, --ty-l-border-bold,
|
|
1395
|
+
--ty-l-border, --ty-l-border-soft, --ty-l-border-faint,
|
|
1396
|
+
--ty-l-surface-canvas, --ty-l-surface-content, --ty-l-surface-elevated,
|
|
1397
|
+
--ty-l-surface-floating, --ty-l-surface-input, --ty-l-solid-neutral,
|
|
1398
|
+
--ty-l-solid-neutral-strong, --ty-l-bg-neutral-strong,
|
|
1399
|
+
--ty-l-bg-neutral-faint, --ty-c-bg-neutral-faint-mult, --ty-c-strong-mult,
|
|
1400
|
+
--ty-c-bold-mult, --ty-c-base-mult, --ty-c-soft-mult, --ty-c-faint-mult,
|
|
1401
|
+
--ty-c-bg-base-mult, --ty-c-bg-bold-mult, --ty-c-bg-soft-mult,
|
|
1402
|
+
--ty-primary-l-factor, --ty-success-l-factor, --ty-warning-l-factor,
|
|
1403
|
+
--ty-danger-l-factor, --ty-neutral-l-factor, --ty-primary-solid-l,
|
|
1404
|
+
--ty-success-solid-l, --ty-warning-solid-l, --ty-danger-solid-l,
|
|
1405
|
+
--ty-solid-hover-l, --ty-solid-active-l, --ty-solid-strong-l,
|
|
1406
|
+
--ty-solid-soft-l, --ty-solid-l, --ty-solid-c, --ty-solid-h,
|
|
1407
|
+
--ty-solid-fg-threshold, --ty-focus-ring-alpha, --ty-weight-action,
|
|
1408
|
+
--ty-weight-label, --ty-button-depth, --ty-button-border-l,
|
|
1409
|
+
--ty-button-border-l-neutral;
|
|
1410
|
+
transition-duration: var(--ty-theme-transition, 0.45s);
|
|
1411
|
+
transition-timing-function: ease;
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
/* Interactive components (button, input, switch, tabs, …) each carry their
|
|
1416
|
+
* OWN short transition — background-color/border-color/color at 0.15–0.2s —
|
|
1417
|
+
* for snappy hover/focus/active feedback. CSS transitions fire on ANY
|
|
1418
|
+
* computed-value change, not just interaction, so a theme switch also
|
|
1419
|
+
* (re-)triggers every one of those, racing the coordinated 0.45s dial
|
|
1420
|
+
* crossfade above at a different speed on every element — hundreds of
|
|
1421
|
+
* mistimed transitions instead of one wash, which reads as jittery rather
|
|
1422
|
+
* than smooth.
|
|
1423
|
+
*
|
|
1424
|
+
* `.ty-theme-switching` is an opt-in escape hatch: add it to `<html>` (or
|
|
1425
|
+
* a scoped `[data-ty-theme]` root) for the duration of a theme switch to
|
|
1426
|
+
* silence local transitions on its descendants — NOT on the switching
|
|
1427
|
+
* element itself, so the dial crossfade above is untouched. Five lines of
|
|
1428
|
+
* JS around your theme toggle:
|
|
1429
|
+
*
|
|
1430
|
+
* root.classList.add('ty-theme-switching');
|
|
1431
|
+
* root.classList.toggle('dark'); // or flip the theme pack
|
|
1432
|
+
* setTimeout(() => root.classList.remove('ty-theme-switching'),
|
|
1433
|
+
* parseFloat(getComputedStyle(root)
|
|
1434
|
+
* .getPropertyValue('--ty-theme-transition')) * 1000 || 450);
|
|
1435
|
+
*
|
|
1436
|
+
* Two mechanisms, because Shadow DOM blocks the first from reaching the
|
|
1437
|
+
* second: the `*` rule below only matches LIGHT-DOM elements (your own
|
|
1438
|
+
* markup, Tailwind-transitioned nav items, etc.) — it cannot reach inside
|
|
1439
|
+
* any ty-* component's shadow root, style encapsulation blocks a document
|
|
1440
|
+
* stylesheet's universal selector from crossing that boundary. Every ty-*
|
|
1441
|
+
* component's OWN local transition is instead wired to the inheriting
|
|
1442
|
+
* custom property `--ty-local-transition` (unset by default; components
|
|
1443
|
+
* fall back to their normal value) — custom properties DO inherit through
|
|
1444
|
+
* shadow boundaries, so setting it once here reaches every component's
|
|
1445
|
+
* internal styles for free. Purely additive — nothing here runs unless you
|
|
1446
|
+
* add the class yourself. */
|
|
1447
|
+
.ty-theme-switching {
|
|
1448
|
+
--ty-local-transition: none;
|
|
1449
|
+
}
|
|
1450
|
+
.ty-theme-switching *,
|
|
1451
|
+
.ty-theme-switching *::before,
|
|
1452
|
+
.ty-theme-switching *::after {
|
|
1453
|
+
transition: none !important;
|
|
1454
|
+
}
|