tyrell-components 1.0.0-RC10 → 1.0.0-RC12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/css/tyrell-brand.css +531 -283
  2. package/css/tyrell.css +38 -31
  3. package/dist/tyrell-brand.css +531 -283
  4. package/dist/tyrell.css +38 -31
  5. package/dist/tyrell.js +1 -1
  6. package/lib/base/ty-component.d.ts +7 -0
  7. package/lib/base/ty-component.d.ts.map +1 -1
  8. package/lib/base/ty-component.js +27 -0
  9. package/lib/base/ty-component.js.map +1 -1
  10. package/lib/components/button.d.ts +9 -1
  11. package/lib/components/button.d.ts.map +1 -1
  12. package/lib/components/button.js +22 -3
  13. package/lib/components/button.js.map +1 -1
  14. package/lib/components/calendar-month.d.ts +6 -0
  15. package/lib/components/calendar-month.d.ts.map +1 -1
  16. package/lib/components/calendar-month.js +52 -9
  17. package/lib/components/calendar-month.js.map +1 -1
  18. package/lib/components/calendar-navigation.d.ts +31 -5
  19. package/lib/components/calendar-navigation.d.ts.map +1 -1
  20. package/lib/components/calendar-navigation.js +71 -31
  21. package/lib/components/calendar-navigation.js.map +1 -1
  22. package/lib/components/calendar.d.ts +14 -1
  23. package/lib/components/calendar.d.ts.map +1 -1
  24. package/lib/components/calendar.js +65 -4
  25. package/lib/components/calendar.js.map +1 -1
  26. package/lib/components/checkbox.d.ts +10 -0
  27. package/lib/components/checkbox.d.ts.map +1 -1
  28. package/lib/components/checkbox.js +68 -27
  29. package/lib/components/checkbox.js.map +1 -1
  30. package/lib/components/copy.d.ts +10 -0
  31. package/lib/components/copy.d.ts.map +1 -1
  32. package/lib/components/copy.js +25 -4
  33. package/lib/components/copy.js.map +1 -1
  34. package/lib/components/date-picker.d.ts +14 -0
  35. package/lib/components/date-picker.d.ts.map +1 -1
  36. package/lib/components/date-picker.js +29 -0
  37. package/lib/components/date-picker.js.map +1 -1
  38. package/lib/components/input.d.ts +14 -0
  39. package/lib/components/input.d.ts.map +1 -1
  40. package/lib/components/input.js +80 -4
  41. package/lib/components/input.js.map +1 -1
  42. package/lib/components/modal.js +6 -0
  43. package/lib/components/modal.js.map +1 -1
  44. package/lib/components/option.d.ts +0 -16
  45. package/lib/components/option.d.ts.map +1 -1
  46. package/lib/components/option.js +9 -1
  47. package/lib/components/option.js.map +1 -1
  48. package/lib/components/radio.d.ts +1 -0
  49. package/lib/components/radio.d.ts.map +1 -1
  50. package/lib/components/radio.js +39 -8
  51. package/lib/components/radio.js.map +1 -1
  52. package/lib/components/scroll-container.d.ts +16 -0
  53. package/lib/components/scroll-container.d.ts.map +1 -1
  54. package/lib/components/scroll-container.js +105 -1
  55. package/lib/components/scroll-container.js.map +1 -1
  56. package/lib/components/{multiselect.d.ts → select.d.ts} +110 -67
  57. package/lib/components/select.d.ts.map +1 -0
  58. package/lib/components/{multiselect.js → select.js} +642 -490
  59. package/lib/components/select.js.map +1 -0
  60. package/lib/components/selected-tags.d.ts +80 -0
  61. package/lib/components/selected-tags.d.ts.map +1 -0
  62. package/lib/components/selected-tags.js +250 -0
  63. package/lib/components/selected-tags.js.map +1 -0
  64. package/lib/components/switch.d.ts +2 -0
  65. package/lib/components/switch.d.ts.map +1 -1
  66. package/lib/components/switch.js +37 -7
  67. package/lib/components/switch.js.map +1 -1
  68. package/lib/components/tabs.d.ts.map +1 -1
  69. package/lib/components/tabs.js +10 -0
  70. package/lib/components/tabs.js.map +1 -1
  71. package/lib/components/tag.d.ts +9 -1
  72. package/lib/components/tag.d.ts.map +1 -1
  73. package/lib/components/tag.js +40 -4
  74. package/lib/components/tag.js.map +1 -1
  75. package/lib/components/textarea.d.ts +3 -0
  76. package/lib/components/textarea.d.ts.map +1 -1
  77. package/lib/components/textarea.js +61 -6
  78. package/lib/components/textarea.js.map +1 -1
  79. package/lib/index.d.ts +2 -2
  80. package/lib/index.d.ts.map +1 -1
  81. package/lib/index.js +2 -2
  82. package/lib/index.js.map +1 -1
  83. package/lib/styles/button.d.ts +7 -2
  84. package/lib/styles/button.d.ts.map +1 -1
  85. package/lib/styles/button.js +75 -238
  86. package/lib/styles/button.js.map +1 -1
  87. package/lib/styles/calendar-month.d.ts +1 -1
  88. package/lib/styles/calendar-month.d.ts.map +1 -1
  89. package/lib/styles/calendar-month.js +44 -66
  90. package/lib/styles/calendar-month.js.map +1 -1
  91. package/lib/styles/calendar-navigation.d.ts +1 -1
  92. package/lib/styles/calendar-navigation.d.ts.map +1 -1
  93. package/lib/styles/calendar-navigation.js +19 -27
  94. package/lib/styles/calendar-navigation.js.map +1 -1
  95. package/lib/styles/checkbox.d.ts +5 -5
  96. package/lib/styles/checkbox.d.ts.map +1 -1
  97. package/lib/styles/checkbox.js +147 -8
  98. package/lib/styles/checkbox.js.map +1 -1
  99. package/lib/styles/copy.d.ts +1 -1
  100. package/lib/styles/copy.d.ts.map +1 -1
  101. package/lib/styles/copy.js +32 -0
  102. package/lib/styles/copy.js.map +1 -1
  103. package/lib/styles/date-picker.d.ts +1 -1
  104. package/lib/styles/date-picker.d.ts.map +1 -1
  105. package/lib/styles/date-picker.js +12 -4
  106. package/lib/styles/date-picker.js.map +1 -1
  107. package/lib/styles/input.d.ts +1 -1
  108. package/lib/styles/input.d.ts.map +1 -1
  109. package/lib/styles/input.js +28 -298
  110. package/lib/styles/input.js.map +1 -1
  111. package/lib/styles/option.d.ts +1 -1
  112. package/lib/styles/option.d.ts.map +1 -1
  113. package/lib/styles/option.js +29 -5
  114. package/lib/styles/option.js.map +1 -1
  115. package/lib/styles/radio.d.ts +1 -1
  116. package/lib/styles/radio.d.ts.map +1 -1
  117. package/lib/styles/scroll-container.d.ts +1 -1
  118. package/lib/styles/scroll-container.d.ts.map +1 -1
  119. package/lib/styles/scroll-container.js +6 -0
  120. package/lib/styles/scroll-container.js.map +1 -1
  121. package/lib/styles/select.d.ts +12 -0
  122. package/lib/styles/select.d.ts.map +1 -0
  123. package/lib/styles/select.js +240 -0
  124. package/lib/styles/select.js.map +1 -0
  125. package/lib/styles/switch.d.ts +1 -1
  126. package/lib/styles/switch.d.ts.map +1 -1
  127. package/lib/styles/tag.d.ts +1 -1
  128. package/lib/styles/tag.d.ts.map +1 -1
  129. package/lib/styles/tag.js +36 -140
  130. package/lib/styles/tag.js.map +1 -1
  131. package/lib/styles/textarea.d.ts +1 -1
  132. package/lib/styles/textarea.d.ts.map +1 -1
  133. package/lib/styles/textarea.js +67 -33
  134. package/lib/styles/textarea.js.map +1 -1
  135. package/lib/types/common.d.ts +2 -1
  136. package/lib/types/common.d.ts.map +1 -1
  137. package/lib/types/common.js +13 -1
  138. package/lib/types/common.js.map +1 -1
  139. package/lib/utils/calendar-utils.d.ts +0 -48
  140. package/lib/utils/calendar-utils.d.ts.map +1 -1
  141. package/lib/utils/calendar-utils.js +0 -69
  142. package/lib/utils/calendar-utils.js.map +1 -1
  143. package/lib/utils/flavor-sheet.d.ts +32 -0
  144. package/lib/utils/flavor-sheet.d.ts.map +1 -0
  145. package/lib/utils/flavor-sheet.js +40 -0
  146. package/lib/utils/flavor-sheet.js.map +1 -0
  147. package/lib/utils/icon-registry.d.ts +0 -13
  148. package/lib/utils/icon-registry.d.ts.map +1 -1
  149. package/lib/utils/icon-registry.js +0 -35
  150. package/lib/utils/icon-registry.js.map +1 -1
  151. package/lib/utils/locale.d.ts +0 -57
  152. package/lib/utils/locale.d.ts.map +1 -1
  153. package/lib/utils/locale.js +0 -89
  154. package/lib/utils/locale.js.map +1 -1
  155. package/lib/utils/number-format.d.ts +0 -21
  156. package/lib/utils/number-format.d.ts.map +1 -1
  157. package/lib/utils/number-format.js +0 -27
  158. package/lib/utils/number-format.js.map +1 -1
  159. package/lib/utils/positioning.d.ts +0 -24
  160. package/lib/utils/positioning.d.ts.map +1 -1
  161. package/lib/utils/positioning.js +3 -86
  162. package/lib/utils/positioning.js.map +1 -1
  163. package/lib/utils/scroll-lock.d.ts.map +1 -1
  164. package/lib/utils/scroll-lock.js +0 -1
  165. package/lib/utils/scroll-lock.js.map +1 -1
  166. package/lib/utils/styles.d.ts +0 -5
  167. package/lib/utils/styles.d.ts.map +1 -1
  168. package/lib/utils/styles.js +0 -7
  169. package/lib/utils/styles.js.map +1 -1
  170. package/lib/version.d.ts +1 -1
  171. package/lib/version.js +1 -1
  172. package/package.json +17 -9
  173. package/lib/components/dropdown.d.ts +0 -424
  174. package/lib/components/dropdown.d.ts.map +0 -1
  175. package/lib/components/dropdown.js +0 -1640
  176. package/lib/components/dropdown.js.map +0 -1
  177. package/lib/components/multiselect.d.ts.map +0 -1
  178. package/lib/components/multiselect.js.map +0 -1
  179. package/lib/styles/dropdown.d.ts +0 -12
  180. package/lib/styles/dropdown.d.ts.map +0 -1
  181. package/lib/styles/dropdown.js +0 -1081
  182. package/lib/styles/dropdown.js.map +0 -1
@@ -12,79 +12,132 @@
12
12
  * --ty-brand-chroma: 0.13;
13
13
  * }
14
14
  *
15
- * Primary, secondary, neutral, surfaces, inputs, solid buttons all retint.
16
- * Success / danger / warning stay semantic (green / red / amber) — override
17
- * their *-hue/*-chroma seeds if you want them to follow the brand too.
15
+ * =====================================================================
16
+ * THE FORMULA
17
+ * =====================================================================
18
+ *
19
+ * Every color in the library is one formula on five axes:
20
+ *
21
+ * oklch(
22
+ * L = L-curve[shade] × flavor-l-factor ← Tier 3 × Tier 5
23
+ * C = flavor-chroma × saturation-curve[shade] ← Tier 2 × Tier 4
24
+ * H = flavor-hue ← Tier 2
25
+ * )
26
+ *
27
+ * Pick a flavor (primary / secondary / success / warning / danger /
28
+ * neutral). Pick a shade (strong / bold / base / soft / faint). That's
29
+ * the cell; the formula gives you its color.
30
+ *
31
+ * FLAVOR axis — which semantic role (carries its own hue, chroma,
32
+ * l-factor seeds)
33
+ * SHADE axis — 5 emphasis stops shared across flavors
34
+ * (strong / bold / base / soft / faint)
35
+ * HUE axis — what color family (0°–360°)
36
+ * CHROMA axis — how saturated (0 = grey, ~0.4 = max vivid)
37
+ * L axis — how dark or light (0 = black, 1 = white)
38
+ * Light mode: low L = more emphasis.
39
+ * Dark mode: high L = more emphasis (curve flips).
40
+ *
41
+ * Worked example — `--ty-color-warning-bold` in LIGHT mode:
42
+ *
43
+ * L = 0.46 × 1 = 0.46 ← l-bold × warning-l-factor
44
+ * C = 0.26 × 1.00 = 0.26 ← warning-chroma × c-bold-mult
45
+ * H = 75° ← warning-hue
46
+ * → oklch(0.46 0.26 75) (a punchy amber for +1 emphasis text)
47
+ *
48
+ * Want warning a notch darker without touching anything else? Set
49
+ * `--ty-warning-l-factor: 0.85` and the new L becomes 0.46 × 0.85 =
50
+ * 0.39. Every warning shade shifts in step; primary / success / danger
51
+ * are untouched.
52
+ *
53
+ * =====================================================================
54
+ * FILE LAYOUT
55
+ * =====================================================================
18
56
  *
19
- * Three layers of knobs you can override at :root (or html.dark for
20
- * per-mode tuning):
57
+ * SECTION 1 KNOBS
58
+ * The variables you might want to override. Six tiers from drop-in
59
+ * rebrand (Tier 1) to surgical per-flavor tweak (Tier 5) plus solid
60
+ * buttons (Tier 6).
21
61
  *
22
- * 1. SEEDSper-flavor hue + chroma.
23
- * --ty-brand-hue, --ty-brand-chroma
24
- * --ty-secondary-hue, --ty-secondary-chroma (default: brand + 60°)
25
- * --ty-success-hue, --ty-success-chroma (default: 145°)
26
- * --ty-danger-hue, --ty-danger-chroma (default: 25°)
27
- * --ty-warning-hue, --ty-warning-chroma (default: 75°)
28
- * --ty-neutral-hue, --ty-neutral-chroma (default: brand-hue, 0.005)
62
+ * SECTION 2IMPLEMENTATION
63
+ * The oklch() expressions that wire the knobs through to the actual
64
+ * color tokens. Rarely needs editing — Section 1 is the contract.
29
65
  *
30
- * 2. L-CURVE lightness stops shared by every flavor.
31
- * --ty-l-strong, --ty-l-bold, --ty-l-base, --ty-l-soft, --ty-l-faint
32
- * --ty-l-bg-base, --ty-l-bg-bold, --ty-l-bg-soft
33
- * Defaults in `:root` are tuned for light mode (lower L = more
34
- * emphasis). The `html.dark` block redefines them with inverted
35
- * values. Override either block to compress / expand the ladder.
66
+ * Browser support: oklch() is in every evergreen browser since mid-2023.
67
+ * Tier 6 (solid) additionally uses OKLCH relative color — oklch(from …) —
68
+ * which lands later: Chrome 119, Safari 16.4, Firefox 128 (mid-2024).
69
+ * Solid fills have no fallback below those versions.
36
70
  *
37
- * 3. SATURATION CURVE — chroma multipliers per shade.
38
- * --ty-c-strong-mult, --ty-c-bold-mult, --ty-c-base-mult,
39
- * --ty-c-soft-mult, --ty-c-faint-mult
40
- * --ty-c-bg-base-mult, --ty-c-bg-bold-mult, --ty-c-bg-soft-mult
41
- * Multiplied against the flavor chroma seed. Bump --ty-c-bold-mult
42
- * to 1.2 to make `+`-emphasis text more saturated; drop
43
- * --ty-c-faint-mult to 0.2 for whisper-quiet placeholders.
71
+ * ===================================================================== */
72
+
73
+ /* =====================================================================
74
+ * SECTION 1 — KNOBS
75
+ * =====================================================================
44
76
  *
45
- * Browser support: OKLCH is in every evergreen browser since mid-2023.
77
+ * Five tiers, ordered by how often you'd touch them. Override any of
78
+ * these in your own `:root` (or `html.dark` for per-mode tuning) —
79
+ * your declaration wins by source order.
46
80
  *
81
+ * Tier 1 — SEEDS brand-hue + chroma. Rebrand in 2 lines.
82
+ * Tier 2 — PER-FLAVOR ANCHORS each flavor's hue + chroma.
83
+ * Tier 3 — L-CURVE 5 lightness stops for the emphasis ramp.
84
+ * Tier 4 — SATURATION CURVE per-shade chroma multipliers.
85
+ * Tier 5 — PER-FLAVOR L-FACTOR per-flavor lightness multiplier — push
86
+ * one flavor up or down without touching
87
+ * the others. Default 1.
88
+ * Tier 6 — SOLID FILLS solid-button system: hover/active/tone
89
+ * L offsets + per-theme dim/desaturate.
47
90
  * ===================================================================== */
48
91
 
49
92
  :root {
50
93
  /* ----------------------------------------------------------------
51
- * SEEDS
94
+ * Tier 1 — SEEDS
95
+ * Brand-hue + chroma drive primary, neutral, surfaces, inputs,
96
+ * solid buttons. One slider rebrands the page.
52
97
  * --------------------------------------------------------------*/
53
98
 
54
99
  --ty-brand-hue: 230;
55
- --ty-brand-chroma: 0.13;
100
+ --ty-brand-chroma: 0.12; /* restrained EU default; the loud 0.2 read as "bollywood" */
56
101
 
57
- /* Every flavor's chroma tracks --ty-brand-chroma by default, at a
58
- * proportion that preserves the relative saturation hierarchy (danger
59
- * punchier than primary, neutral near-grey). Drag --ty-brand-chroma to
60
- * 0 → everything goes greyscale; push to 0.30 → everything goes vibrant.
61
- *
62
- * Pin any flavor independently by setting --ty-{flavor}-chroma to a
63
- * literal number (e.g. --ty-success-chroma: 0.14;). The multiplier
64
- * relationship breaks for that one flavor only. */
102
+ /* Surface tint. 0 = monochrome surfaces (default, no brand leak).
103
+ * Bump to ~0.005 (light) / ~0.012 (dark) to warm surfaces toward brand. */
104
+ --ty-surface-chroma: 0;
65
105
 
66
- /* Secondary rotates from brand by an exposed offset. Defaults to +60°
106
+ /* Secondary rotates from brand by an exposed offset. Default +60°
67
107
  * (sibling accent). Try 30° for a close sibling, 120° for triadic,
68
- * 180° for complement. Set --ty-secondary-hue to a literal number to
69
- * detach completely. */
108
+ * 180° for complement. Set --ty-secondary-hue to a literal number
109
+ * to detach completely. */
70
110
  --ty-secondary-offset: 60;
111
+
112
+ /* ----------------------------------------------------------------
113
+ * Tier 2 — PER-FLAVOR ANCHORS
114
+ * Semantic colors (success/warning/danger/neutral) have their own
115
+ * hue + chroma seeds so they keep meaning across brand changes.
116
+ * Override any individually:
117
+ * --ty-success-hue: 160; (more teal)
118
+ * --ty-warning-chroma: 0.2; (more vivid)
119
+ * --------------------------------------------------------------*/
120
+
71
121
  --ty-secondary-hue: calc(var(--ty-brand-hue) + var(--ty-secondary-offset));
72
122
  --ty-secondary-chroma: var(--ty-brand-chroma);
73
123
 
74
124
  --ty-success-hue: 145;
75
125
  --ty-success-chroma: calc(var(--ty-brand-chroma) * 1.08);
76
126
 
127
+ --ty-warning-hue: 75;
128
+ --ty-warning-chroma: calc(var(--ty-brand-chroma) * 2);
129
+
77
130
  --ty-danger-hue: 25;
78
131
  --ty-danger-chroma: calc(var(--ty-brand-chroma) * 1.31);
79
132
 
80
- --ty-warning-hue: 75;
81
- --ty-warning-chroma: calc(var(--ty-brand-chroma) * 1.15);
82
-
83
133
  --ty-neutral-hue: var(--ty-brand-hue);
84
134
  --ty-neutral-chroma: calc(var(--ty-brand-chroma) * 0.04);
85
135
 
86
136
  /* ----------------------------------------------------------------
87
- * L-CURVE light mode. Lower L = more emphasis.
137
+ * Tier 3 — L-CURVE (light mode)
138
+ * 5 lightness stops per flavor for the emphasis ramp.
139
+ * Lower L = darker = more emphasis in light mode.
140
+ * Plus 3 bg L stops for the soft-tint backgrounds.
88
141
  * --------------------------------------------------------------*/
89
142
 
90
143
  --ty-l-strong: 0.38; /* ++ max emphasis */
@@ -98,8 +151,10 @@
98
151
  --ty-l-bg-soft: 0.98;
99
152
 
100
153
  /* ----------------------------------------------------------------
101
- * SATURATION CURVEper-shade chroma multipliers.
102
- * Each shade's chroma = flavor-chroma × multiplier.
154
+ * Tier 4SATURATION CURVE
155
+ * Per-shade chroma multipliers. Each shade's chroma =
156
+ * flavor-chroma × multiplier. Drops near the extremes so
157
+ * near-white and near-black can hold their tint.
103
158
  * --------------------------------------------------------------*/
104
159
 
105
160
  --ty-c-strong-mult: 0.77;
@@ -112,80 +167,203 @@
112
167
  --ty-c-bg-bold-mult: 0.38;
113
168
  --ty-c-bg-soft-mult: 0.08;
114
169
 
115
- /* ================================================================
116
- * LIGHT MODEderived tokens. The math is the same for every
117
- * flavor; only the seed (hue + chroma) differs.
118
- * ================================================================ */
170
+ /* ----------------------------------------------------------------
171
+ * Tier 5PER-FLAVOR L-FACTOR
172
+ * Multiplies the L-curve values for that flavor only. Default 1 =
173
+ * no change. Useful when one flavor's brand-default sits too close
174
+ * to brand-hue on the wheel and the buttons blend.
175
+ *
176
+ * Example: brand-hue: 47° (gold). Warning sits at 75° (amber).
177
+ * Both render as similar warm browns at brand-chroma. Drop warning
178
+ * a notch and it darkens enough to stand apart:
179
+ * --ty-warning-l-factor: 0.85;
180
+ *
181
+ * NOTE: the L-curve flips between light and dark mode, so a factor
182
+ * < 1 darkens in light mode but DIMS in dark mode. If you want
183
+ * symmetric "more emphatic" in both modes, set the factor here for
184
+ * light AND set its inverse (1 / factor, roughly) in `html.dark`.
185
+ * --------------------------------------------------------------*/
186
+
187
+ --ty-primary-l-factor: 1;
188
+ --ty-secondary-l-factor: 1;
189
+ --ty-success-l-factor: 1;
190
+ --ty-warning-l-factor: 1.15;
191
+ --ty-danger-l-factor: 1;
192
+ --ty-neutral-l-factor: 1;
193
+
194
+ /* ----------------------------------------------------------------
195
+ * Tier 6 — SOLID FILLS
196
+ * Solid buttons are their OWN system, not the emphasis ramp. Each
197
+ * flavor's fill defaults to --ty-color-{flavor}; the knobs below
198
+ * derive its hover / active / tone+ / tone- and per-theme adjust.
199
+ * Math lives in SECTION 2 (search "Tier 6 — SOLID"); these are the
200
+ * dials.
201
+ *
202
+ * Axis A — interaction & tone, OKLCH L offsets on the fill.
203
+ * Axis B — per-theme adjust applied to the base fill (dim/desaturate).
204
+ *
205
+ * NOTE: like Tier 5, the emphasis curve flips for dark, so these L
206
+ * offsets are sign-flipped in `html.dark` below (darken in light =
207
+ * lighten in dark). Keep the two blocks in sync.
208
+ * --------------------------------------------------------------*/
209
+
210
+ /* Axis A — interaction (light: darken on press, so offsets are negative) */
211
+ --ty-solid-hover-l: -0.04; /* :hover */
212
+ --ty-solid-active-l: -0.08; /* :active */
213
+ --ty-solid-strong-l: -0.06; /* tone+ */
214
+ --ty-solid-soft-l: 0.1; /* tone- */
215
+
216
+ /* Axis B — per-theme adjust (light reads fine → identity) */
217
+ --ty-solid-l: 0; /* lightness offset — negative dims */
218
+ --ty-solid-c: 1; /* chroma multiplier — <1 desaturates */
219
+ --ty-solid-h: 0; /* hue offset (deg) */
220
+ }
221
+
222
+ /* Dark mode overrides for the L-curve and saturation curve. Tier 1 + 2
223
+ * seeds and Tier 5 L-factors carry through unchanged from :root. */
224
+ html.dark,
225
+ html[data-theme="dark"] {
226
+ /* Tier 3 dark — inverted curve. Higher L = lighter text = more
227
+ * emphasis on a dark background. */
228
+ --ty-l-strong: 0.72;
229
+ --ty-l-bold: 0.66;
230
+ --ty-l-base: 0.62;
231
+ --ty-l-soft: 0.46;
232
+ --ty-l-faint: 0.3;
233
+
234
+ --ty-l-bg-base: 0.22;
235
+ --ty-l-bg-bold: 0.26;
236
+ --ty-l-bg-soft: 0.19;
237
+
238
+ /* Tier 4 dark — dim shades hold more chroma so they don't grey out;
239
+ * strong shades trim chroma so bright tones don't over-pop. */
240
+ --ty-c-strong-mult: 0.77;
241
+ --ty-c-bold-mult: 1;
242
+ --ty-c-base-mult: 0.92;
243
+ --ty-c-soft-mult: 0.77;
244
+ --ty-c-faint-mult: 0.5;
245
+
246
+ --ty-c-bg-base-mult: 0.38;
247
+ --ty-c-bg-bold-mult: 0.54;
248
+ --ty-c-bg-soft-mult: 0.23;
249
+
250
+ /* Tier 6 dark — interaction offsets flip sign (press LIGHTENS on dark),
251
+ * and the per-theme adjust dims + desaturates the fills against the
252
+ * dark canvas. (Computed solid tokens live in SECTION 2 DARK.) */
253
+ --ty-solid-hover-l: 0.04; /* :hover */
254
+ --ty-solid-active-l: 0.08; /* :active */
255
+ --ty-solid-strong-l: 0.06; /* tone+ */
256
+ --ty-solid-soft-l: -0.1; /* tone- */
257
+
258
+ --ty-solid-l: -0.25; /* dim against dark canvas */
259
+ --ty-solid-c: 0.65; /* desaturate against dark canvas */
260
+ --ty-solid-h: 0; /* hue offset */
261
+ }
262
+
263
+ /* =====================================================================
264
+ * SECTION 2 — IMPLEMENTATION
265
+ * =====================================================================
266
+ *
267
+ * The oklch() expressions that turn Section 1's knobs into the actual
268
+ * --ty-color-*, --ty-bg-*, --ty-border-*, --ty-surface-*, --ty-input-*,
269
+ * and --ty-solid-* tokens that components read.
270
+ *
271
+ * Pattern for each flavor's 5-shade fg ramp + 3-shade bg ramp:
272
+ *
273
+ * --ty-color-{flavor}-{shade}: oklch(
274
+ * calc(var(--ty-l-{shade}) * var(--ty-{flavor}-l-factor)) ← L
275
+ * calc(var(--ty-{flavor}-chroma) * var(--ty-c-{shade}-mult)) ← C
276
+ * var(--ty-{flavor}-hue) ← H
277
+ * );
278
+ *
279
+ * Computed tokens are declared in BOTH `:root` and `html.dark` blocks
280
+ * because tyrell.css ships hardcoded dark-mode hexes at html.dark
281
+ * specificity (0,1,1); our brand-layer `:root` (0,1,0) would lose
282
+ * source-order otherwise. Same math both blocks — just different L/C
283
+ * inputs from Tier 3/4.
284
+ * ===================================================================== */
285
+
286
+ :root {
287
+ /* ----------------------------------------------------------------
288
+ * Flavor color ramps (fg + bg + border)
289
+ * --------------------------------------------------------------*/
119
290
 
120
291
  /* Primary */
121
292
  --ty-color-primary-strong: oklch(
122
- var(--ty-l-strong) calc(var(--ty-brand-chroma) * var(--ty-c-strong-mult))
123
- var(--ty-brand-hue)
293
+ calc(var(--ty-l-strong) * var(--ty-primary-l-factor))
294
+ calc(var(--ty-brand-chroma) * var(--ty-c-strong-mult)) var(--ty-brand-hue)
124
295
  );
125
296
  --ty-color-primary-bold: oklch(
126
- var(--ty-l-bold) calc(var(--ty-brand-chroma) * var(--ty-c-bold-mult))
127
- var(--ty-brand-hue)
297
+ calc(var(--ty-l-bold) * var(--ty-primary-l-factor))
298
+ calc(var(--ty-brand-chroma) * var(--ty-c-bold-mult)) var(--ty-brand-hue)
128
299
  );
129
300
  --ty-color-primary: oklch(
130
- var(--ty-l-base) calc(var(--ty-brand-chroma) * var(--ty-c-base-mult))
131
- var(--ty-brand-hue)
301
+ calc(var(--ty-l-base) * var(--ty-primary-l-factor))
302
+ calc(var(--ty-brand-chroma) * var(--ty-c-base-mult)) var(--ty-brand-hue)
132
303
  );
133
304
  --ty-color-primary-soft: oklch(
134
- var(--ty-l-soft) calc(var(--ty-brand-chroma) * var(--ty-c-soft-mult))
135
- var(--ty-brand-hue)
305
+ calc(var(--ty-l-soft) * var(--ty-primary-l-factor))
306
+ calc(var(--ty-brand-chroma) * var(--ty-c-soft-mult)) var(--ty-brand-hue)
136
307
  );
137
308
  --ty-color-primary-faint: oklch(
138
- var(--ty-l-faint) calc(var(--ty-brand-chroma) * var(--ty-c-faint-mult))
139
- var(--ty-brand-hue)
309
+ calc(var(--ty-l-faint) * var(--ty-primary-l-factor))
310
+ calc(var(--ty-brand-chroma) * var(--ty-c-faint-mult)) var(--ty-brand-hue)
140
311
  );
141
312
  --ty-bg-primary: oklch(
142
- var(--ty-l-bg-base) calc(var(--ty-brand-chroma) * var(--ty-c-bg-base-mult))
313
+ calc(var(--ty-l-bg-base) * var(--ty-primary-l-factor))
314
+ calc(var(--ty-brand-chroma) * var(--ty-c-bg-base-mult))
143
315
  var(--ty-brand-hue)
144
316
  );
145
317
  --ty-bg-primary-bold: oklch(
146
- var(--ty-l-bg-bold) calc(var(--ty-brand-chroma) * var(--ty-c-bg-bold-mult))
318
+ calc(var(--ty-l-bg-bold) * var(--ty-primary-l-factor))
319
+ calc(var(--ty-brand-chroma) * var(--ty-c-bg-bold-mult))
147
320
  var(--ty-brand-hue)
148
321
  );
149
322
  --ty-bg-primary-soft: oklch(
150
- var(--ty-l-bg-soft) calc(var(--ty-brand-chroma) * var(--ty-c-bg-soft-mult))
323
+ calc(var(--ty-l-bg-soft) * var(--ty-primary-l-factor))
324
+ calc(var(--ty-brand-chroma) * var(--ty-c-bg-soft-mult))
151
325
  var(--ty-brand-hue)
152
326
  );
153
327
  --ty-border-primary: var(--ty-color-primary-soft);
154
328
 
155
329
  /* Secondary */
156
330
  --ty-color-secondary-strong: oklch(
157
- var(--ty-l-strong)
331
+ calc(var(--ty-l-strong) * var(--ty-secondary-l-factor))
158
332
  calc(var(--ty-secondary-chroma) * var(--ty-c-strong-mult))
159
333
  var(--ty-secondary-hue)
160
334
  );
161
335
  --ty-color-secondary-bold: oklch(
162
- var(--ty-l-bold) calc(var(--ty-secondary-chroma) * var(--ty-c-bold-mult))
336
+ calc(var(--ty-l-bold) * var(--ty-secondary-l-factor))
337
+ calc(var(--ty-secondary-chroma) * var(--ty-c-bold-mult))
163
338
  var(--ty-secondary-hue)
164
339
  );
165
340
  --ty-color-secondary: oklch(
166
- var(--ty-l-base) calc(var(--ty-secondary-chroma) * var(--ty-c-base-mult))
341
+ calc(var(--ty-l-base) * var(--ty-secondary-l-factor))
342
+ calc(var(--ty-secondary-chroma) * var(--ty-c-base-mult))
167
343
  var(--ty-secondary-hue)
168
344
  );
169
345
  --ty-color-secondary-soft: oklch(
170
- var(--ty-l-soft) calc(var(--ty-secondary-chroma) * var(--ty-c-soft-mult))
346
+ calc(var(--ty-l-soft) * var(--ty-secondary-l-factor))
347
+ calc(var(--ty-secondary-chroma) * var(--ty-c-soft-mult))
171
348
  var(--ty-secondary-hue)
172
349
  );
173
350
  --ty-color-secondary-faint: oklch(
174
- var(--ty-l-faint) calc(var(--ty-secondary-chroma) * var(--ty-c-faint-mult))
351
+ calc(var(--ty-l-faint) * var(--ty-secondary-l-factor))
352
+ calc(var(--ty-secondary-chroma) * var(--ty-c-faint-mult))
175
353
  var(--ty-secondary-hue)
176
354
  );
177
355
  --ty-bg-secondary: oklch(
178
- var(--ty-l-bg-base)
356
+ calc(var(--ty-l-bg-base) * var(--ty-secondary-l-factor))
179
357
  calc(var(--ty-secondary-chroma) * var(--ty-c-bg-base-mult))
180
358
  var(--ty-secondary-hue)
181
359
  );
182
360
  --ty-bg-secondary-bold: oklch(
183
- var(--ty-l-bg-bold)
361
+ calc(var(--ty-l-bg-bold) * var(--ty-secondary-l-factor))
184
362
  calc(var(--ty-secondary-chroma) * var(--ty-c-bg-bold-mult))
185
363
  var(--ty-secondary-hue)
186
364
  );
187
365
  --ty-bg-secondary-soft: oklch(
188
- var(--ty-l-bg-soft)
366
+ calc(var(--ty-l-bg-soft) * var(--ty-secondary-l-factor))
189
367
  calc(var(--ty-secondary-chroma) * var(--ty-c-bg-soft-mult))
190
368
  var(--ty-secondary-hue)
191
369
  );
@@ -193,37 +371,42 @@
193
371
 
194
372
  /* Success */
195
373
  --ty-color-success-strong: oklch(
196
- var(--ty-l-strong) calc(var(--ty-success-chroma) * var(--ty-c-strong-mult))
374
+ calc(var(--ty-l-strong) * var(--ty-success-l-factor))
375
+ calc(var(--ty-success-chroma) * var(--ty-c-strong-mult))
197
376
  var(--ty-success-hue)
198
377
  );
199
378
  --ty-color-success-bold: oklch(
200
- var(--ty-l-bold) calc(var(--ty-success-chroma) * var(--ty-c-bold-mult))
379
+ calc(var(--ty-l-bold) * var(--ty-success-l-factor))
380
+ calc(var(--ty-success-chroma) * var(--ty-c-bold-mult))
201
381
  var(--ty-success-hue)
202
382
  );
203
383
  --ty-color-success: oklch(
204
- var(--ty-l-base) calc(var(--ty-success-chroma) * var(--ty-c-base-mult))
384
+ calc(var(--ty-l-base) * var(--ty-success-l-factor))
385
+ calc(var(--ty-success-chroma) * var(--ty-c-base-mult))
205
386
  var(--ty-success-hue)
206
387
  );
207
388
  --ty-color-success-soft: oklch(
208
- var(--ty-l-soft) calc(var(--ty-success-chroma) * var(--ty-c-soft-mult))
389
+ calc(var(--ty-l-soft) * var(--ty-success-l-factor))
390
+ calc(var(--ty-success-chroma) * var(--ty-c-soft-mult))
209
391
  var(--ty-success-hue)
210
392
  );
211
393
  --ty-color-success-faint: oklch(
212
- var(--ty-l-faint) calc(var(--ty-success-chroma) * var(--ty-c-faint-mult))
394
+ calc(var(--ty-l-faint) * var(--ty-success-l-factor))
395
+ calc(var(--ty-success-chroma) * var(--ty-c-faint-mult))
213
396
  var(--ty-success-hue)
214
397
  );
215
398
  --ty-bg-success: oklch(
216
- var(--ty-l-bg-base)
399
+ calc(var(--ty-l-bg-base) * var(--ty-success-l-factor))
217
400
  calc(var(--ty-success-chroma) * var(--ty-c-bg-base-mult))
218
401
  var(--ty-success-hue)
219
402
  );
220
403
  --ty-bg-success-bold: oklch(
221
- var(--ty-l-bg-bold)
404
+ calc(var(--ty-l-bg-bold) * var(--ty-success-l-factor))
222
405
  calc(var(--ty-success-chroma) * var(--ty-c-bg-bold-mult))
223
406
  var(--ty-success-hue)
224
407
  );
225
408
  --ty-bg-success-soft: oklch(
226
- var(--ty-l-bg-soft)
409
+ calc(var(--ty-l-bg-soft) * var(--ty-success-l-factor))
227
410
  calc(var(--ty-success-chroma) * var(--ty-c-bg-soft-mult))
228
411
  var(--ty-success-hue)
229
412
  );
@@ -231,72 +414,82 @@
231
414
 
232
415
  /* Danger */
233
416
  --ty-color-danger-strong: oklch(
234
- var(--ty-l-strong) calc(var(--ty-danger-chroma) * var(--ty-c-strong-mult))
417
+ calc(var(--ty-l-strong) * var(--ty-danger-l-factor))
418
+ calc(var(--ty-danger-chroma) * var(--ty-c-strong-mult))
235
419
  var(--ty-danger-hue)
236
420
  );
237
421
  --ty-color-danger-bold: oklch(
238
- var(--ty-l-bold) calc(var(--ty-danger-chroma) * var(--ty-c-bold-mult))
239
- var(--ty-danger-hue)
422
+ calc(var(--ty-l-bold) * var(--ty-danger-l-factor))
423
+ calc(var(--ty-danger-chroma) * var(--ty-c-bold-mult)) var(--ty-danger-hue)
240
424
  );
241
425
  --ty-color-danger: oklch(
242
- var(--ty-l-base) calc(var(--ty-danger-chroma) * var(--ty-c-base-mult))
243
- var(--ty-danger-hue)
426
+ calc(var(--ty-l-base) * var(--ty-danger-l-factor))
427
+ calc(var(--ty-danger-chroma) * var(--ty-c-base-mult)) var(--ty-danger-hue)
244
428
  );
245
429
  --ty-color-danger-soft: oklch(
246
- var(--ty-l-soft) calc(var(--ty-danger-chroma) * var(--ty-c-soft-mult))
247
- var(--ty-danger-hue)
430
+ calc(var(--ty-l-soft) * var(--ty-danger-l-factor))
431
+ calc(var(--ty-danger-chroma) * var(--ty-c-soft-mult)) var(--ty-danger-hue)
248
432
  );
249
433
  --ty-color-danger-faint: oklch(
250
- var(--ty-l-faint) calc(var(--ty-danger-chroma) * var(--ty-c-faint-mult))
434
+ calc(var(--ty-l-faint) * var(--ty-danger-l-factor))
435
+ calc(var(--ty-danger-chroma) * var(--ty-c-faint-mult))
251
436
  var(--ty-danger-hue)
252
437
  );
253
438
  --ty-bg-danger: oklch(
254
- var(--ty-l-bg-base) calc(var(--ty-danger-chroma) * var(--ty-c-bg-base-mult))
439
+ calc(var(--ty-l-bg-base) * var(--ty-danger-l-factor))
440
+ calc(var(--ty-danger-chroma) * var(--ty-c-bg-base-mult))
255
441
  var(--ty-danger-hue)
256
442
  );
257
443
  --ty-bg-danger-bold: oklch(
258
- var(--ty-l-bg-bold) calc(var(--ty-danger-chroma) * var(--ty-c-bg-bold-mult))
444
+ calc(var(--ty-l-bg-bold) * var(--ty-danger-l-factor))
445
+ calc(var(--ty-danger-chroma) * var(--ty-c-bg-bold-mult))
259
446
  var(--ty-danger-hue)
260
447
  );
261
448
  --ty-bg-danger-soft: oklch(
262
- var(--ty-l-bg-soft) calc(var(--ty-danger-chroma) * var(--ty-c-bg-soft-mult))
449
+ calc(var(--ty-l-bg-soft) * var(--ty-danger-l-factor))
450
+ calc(var(--ty-danger-chroma) * var(--ty-c-bg-soft-mult))
263
451
  var(--ty-danger-hue)
264
452
  );
265
453
  --ty-border-danger: var(--ty-color-danger-soft);
266
454
 
267
455
  /* Warning */
268
456
  --ty-color-warning-strong: oklch(
269
- var(--ty-l-strong) calc(var(--ty-warning-chroma) * var(--ty-c-strong-mult))
457
+ calc(var(--ty-l-strong) * var(--ty-warning-l-factor))
458
+ calc(var(--ty-warning-chroma) * var(--ty-c-strong-mult))
270
459
  var(--ty-warning-hue)
271
460
  );
272
461
  --ty-color-warning-bold: oklch(
273
- var(--ty-l-bold) calc(var(--ty-warning-chroma) * var(--ty-c-bold-mult))
462
+ calc(var(--ty-l-bold) * var(--ty-warning-l-factor))
463
+ calc(var(--ty-warning-chroma) * var(--ty-c-bold-mult))
274
464
  var(--ty-warning-hue)
275
465
  );
276
466
  --ty-color-warning: oklch(
277
- var(--ty-l-base) calc(var(--ty-warning-chroma) * var(--ty-c-base-mult))
467
+ calc(var(--ty-l-base) * var(--ty-warning-l-factor))
468
+ calc(var(--ty-warning-chroma) * var(--ty-c-base-mult))
278
469
  var(--ty-warning-hue)
279
470
  );
280
471
  --ty-color-warning-soft: oklch(
281
- var(--ty-l-soft) calc(var(--ty-warning-chroma) * var(--ty-c-soft-mult))
472
+ calc(var(--ty-l-soft) * var(--ty-warning-l-factor))
473
+ calc(var(--ty-warning-chroma) * var(--ty-c-soft-mult))
282
474
  var(--ty-warning-hue)
283
475
  );
284
476
  --ty-color-warning-faint: oklch(
285
- var(--ty-l-faint) calc(var(--ty-warning-chroma) * var(--ty-c-faint-mult))
477
+ calc(var(--ty-l-faint) * var(--ty-warning-l-factor))
478
+ calc(var(--ty-warning-chroma) * var(--ty-c-faint-mult))
286
479
  var(--ty-warning-hue)
287
480
  );
288
481
  --ty-bg-warning: oklch(
289
- var(--ty-l-bg-base)
482
+ calc(var(--ty-l-bg-base) * var(--ty-warning-l-factor))
290
483
  calc(var(--ty-warning-chroma) * var(--ty-c-bg-base-mult))
291
484
  var(--ty-warning-hue)
292
485
  );
293
486
  --ty-bg-warning-bold: oklch(
294
- var(--ty-l-bg-bold)
487
+ calc(var(--ty-l-bg-bold) * var(--ty-warning-l-factor))
295
488
  calc(var(--ty-warning-chroma) * var(--ty-c-bg-bold-mult))
296
489
  var(--ty-warning-hue)
297
490
  );
298
491
  --ty-bg-warning-soft: oklch(
299
- var(--ty-l-bg-soft)
492
+ calc(var(--ty-l-bg-soft) * var(--ty-warning-l-factor))
300
493
  calc(var(--ty-warning-chroma) * var(--ty-c-bg-soft-mult))
301
494
  var(--ty-warning-hue)
302
495
  );
@@ -304,37 +497,42 @@
304
497
 
305
498
  /* Neutral — same L curve, near-zero chroma so the grey scale stays grey. */
306
499
  --ty-color-neutral-strong: oklch(
307
- var(--ty-l-strong) calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
500
+ calc(var(--ty-l-strong) * var(--ty-neutral-l-factor))
501
+ calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
308
502
  var(--ty-neutral-hue)
309
503
  );
310
504
  --ty-color-neutral-bold: oklch(
311
- var(--ty-l-bold) calc(var(--ty-neutral-chroma) * var(--ty-c-bold-mult))
505
+ calc(var(--ty-l-bold) * var(--ty-neutral-l-factor))
506
+ calc(var(--ty-neutral-chroma) * var(--ty-c-bold-mult))
312
507
  var(--ty-neutral-hue)
313
508
  );
314
509
  --ty-color-neutral: oklch(
315
- var(--ty-l-base) calc(var(--ty-neutral-chroma) * var(--ty-c-base-mult))
510
+ calc(var(--ty-l-base) * var(--ty-neutral-l-factor))
511
+ calc(var(--ty-neutral-chroma) * var(--ty-c-base-mult))
316
512
  var(--ty-neutral-hue)
317
513
  );
318
514
  --ty-color-neutral-soft: oklch(
319
- var(--ty-l-soft) calc(var(--ty-neutral-chroma) * var(--ty-c-soft-mult))
515
+ calc(var(--ty-l-soft) * var(--ty-neutral-l-factor))
516
+ calc(var(--ty-neutral-chroma) * var(--ty-c-soft-mult))
320
517
  var(--ty-neutral-hue)
321
518
  );
322
519
  --ty-color-neutral-faint: oklch(
323
- var(--ty-l-faint) calc(var(--ty-neutral-chroma) * var(--ty-c-faint-mult))
520
+ calc(var(--ty-l-faint) * var(--ty-neutral-l-factor))
521
+ calc(var(--ty-neutral-chroma) * var(--ty-c-faint-mult))
324
522
  var(--ty-neutral-hue)
325
523
  );
326
524
  --ty-bg-neutral: oklch(
327
- var(--ty-l-bg-base)
525
+ calc(var(--ty-l-bg-base) * var(--ty-neutral-l-factor))
328
526
  calc(var(--ty-neutral-chroma) * var(--ty-c-bg-base-mult))
329
527
  var(--ty-neutral-hue)
330
528
  );
331
529
  --ty-bg-neutral-bold: oklch(
332
- var(--ty-l-bg-bold)
530
+ calc(var(--ty-l-bg-bold) * var(--ty-neutral-l-factor))
333
531
  calc(var(--ty-neutral-chroma) * var(--ty-c-bg-bold-mult))
334
532
  var(--ty-neutral-hue)
335
533
  );
336
534
  --ty-bg-neutral-soft: oklch(
337
- var(--ty-l-bg-soft)
535
+ calc(var(--ty-l-bg-soft) * var(--ty-neutral-l-factor))
338
536
  calc(var(--ty-neutral-chroma) * var(--ty-c-bg-soft-mult))
339
537
  var(--ty-neutral-hue)
340
538
  );
@@ -345,25 +543,31 @@
345
543
  0.99 calc(var(--ty-neutral-chroma) * 0.4) var(--ty-neutral-hue)
346
544
  );
347
545
 
348
- /* Global neutral borders — read off the neutral color ramp. */
546
+ /* ----------------------------------------------------------------
547
+ * Global neutral borders — read off the neutral color ramp.
548
+ * --------------------------------------------------------------*/
349
549
  --ty-border-strong: var(--ty-color-neutral-bold);
350
550
  --ty-border: var(--ty-color-neutral-soft);
351
551
  --ty-border-bold: var(--ty-color-neutral-soft);
352
552
  --ty-border-soft: var(--ty-color-neutral-faint);
353
553
  --ty-border-faint: var(--ty-color-neutral-faint);
354
554
 
355
- /* Surfaces — canvas tinted slightly toward brand for warmth. */
356
- --ty-surface-canvas: oklch(0.985 0.005 var(--ty-brand-hue));
555
+ /* ----------------------------------------------------------------
556
+ * Surfaces — monochrome by default; --ty-surface-chroma warms them.
557
+ * --------------------------------------------------------------*/
558
+ --ty-surface-canvas: oklch(0.985 var(--ty-surface-chroma) var(--ty-brand-hue));
357
559
  --ty-surface-content: oklch(1 0 0);
358
560
  --ty-surface-elevated: oklch(1 0 0);
359
561
  --ty-surface-floating: oklch(1 0 0);
360
562
  --ty-surface-input: oklch(1 0 0);
361
563
 
362
- /* Inputs — tied to neutral ramp so form controls retint with brand. */
564
+ /* ----------------------------------------------------------------
565
+ * Inputs — tied to neutral ramp so form controls retint with brand.
566
+ * --------------------------------------------------------------*/
363
567
  --ty-input-bg: var(--ty-surface-input);
364
568
  --ty-input-color: var(--ty-color-neutral-strong);
365
- --ty-input-border: var(--ty-color-neutral-soft);
366
- --ty-input-border-hover: var(--ty-color-neutral-bold);
569
+ --ty-input-border: var(--ty-color-neutral-faint);
570
+ --ty-input-border-hover: var(--ty-color-neutral-soft);
367
571
  --ty-input-border-focus: var(--ty-color-primary);
368
572
  --ty-input-placeholder: var(--ty-color-neutral-soft);
369
573
  --ty-input-disabled-bg: var(--ty-color-neutral-faint);
@@ -374,161 +578,225 @@
374
578
  var(--ty-color-primary) 5%,
375
579
  transparent
376
580
  );
581
+ }
582
+
583
+ /* ----------------------------------------------------------------
584
+ * Tier 6 — SOLID (implementation)
585
+ * Solid is its OWN system, NOT the text/emphasis ramp. The dials
586
+ * (--ty-solid-hover-l / -active-l / -strong-l / -soft-l and
587
+ * --ty-solid-l / -c / -h) live in SECTION 1, Tier 6. Below is the
588
+ * derivation only: base fill bakes in the per-theme adjust (Axis B);
589
+ * hover/active/strong/soft offset the base by Axis A. Override any
590
+ * single --ty-solid-{flavor}-{state} to recolor just that segment.
591
+ *
592
+ * Declared at `html:root` (specificity 0,1,1) — NOT plain `:root` (0,1,0) —
593
+ * on purpose: it must out-rank tyrell.css's hardcoded dark solids at
594
+ * `html.dark` (0,1,1). It wins light by specificity over base's `html{}`,
595
+ * and wins dark by source order over base's `html.dark` (brand loads after).
596
+ * That's what lets dark solids re-tint with --ty-brand-hue. Declared ONCE —
597
+ * the oklch(from var(--ty-color-*)) formulas resolve per-mode automatically,
598
+ * so no dark duplicate is needed.
599
+ * --------------------------------------------------------------*/
600
+ html:root {
601
+ /* base fill per flavor (= flavor color, theme-adjusted by Axis B) */
602
+ --ty-solid-primary: oklch(
603
+ from var(--ty-color-primary) calc(l + var(--ty-solid-l))
604
+ calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
605
+ );
606
+ --ty-solid-secondary: oklch(
607
+ from var(--ty-color-secondary) calc(l + var(--ty-solid-l))
608
+ calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
609
+ );
610
+ --ty-solid-success: oklch(
611
+ from var(--ty-color-success) calc(l + var(--ty-solid-l))
612
+ calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
613
+ );
614
+ --ty-solid-danger: oklch(
615
+ from var(--ty-color-danger) calc(l + var(--ty-solid-l))
616
+ calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
617
+ );
618
+ --ty-solid-warning: oklch(
619
+ from var(--ty-color-warning) calc(l + var(--ty-solid-l))
620
+ calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
621
+ );
622
+ /* neutral is a deliberate dark grey fill, not the neutral text color */
623
+ --ty-solid-neutral: oklch(
624
+ 0.4 calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
625
+ var(--ty-neutral-hue)
626
+ );
377
627
 
378
- /* Solid buttons — re-route through --ty-color-*. */
379
- --ty-solid-primary: var(--ty-color-primary);
380
- --ty-solid-primary-strong: var(--ty-color-primary-bold);
381
- --ty-solid-primary-soft: var(--ty-color-primary-soft);
382
628
  --ty-solid-primary-fg: white;
383
-
384
- --ty-solid-secondary: var(--ty-color-secondary);
385
- --ty-solid-secondary-strong: var(--ty-color-secondary-bold);
386
- --ty-solid-secondary-soft: var(--ty-color-secondary-soft);
387
629
  --ty-solid-secondary-fg: white;
388
-
389
- --ty-solid-success: var(--ty-color-success);
390
- --ty-solid-success-strong: var(--ty-color-success-bold);
391
- --ty-solid-success-soft: var(--ty-color-success-soft);
392
630
  --ty-solid-success-fg: white;
393
-
394
- --ty-solid-danger: var(--ty-color-danger);
395
- --ty-solid-danger-strong: var(--ty-color-danger-bold);
396
- --ty-solid-danger-soft: var(--ty-color-danger-soft);
397
631
  --ty-solid-danger-fg: white;
398
-
399
- --ty-solid-warning: var(--ty-color-warning);
400
- --ty-solid-warning-strong: var(--ty-color-warning-bold);
401
- --ty-solid-warning-soft: var(--ty-color-warning-soft);
402
632
  --ty-solid-warning-fg: white;
633
+ --ty-solid-neutral-fg: white;
403
634
 
404
- /* Solid neutral routes to neutral-strong rather than neutral-base.
405
- * Neutral-base (L_base) reads as a washy mid-grey on white surfaces;
406
- * neutral-strong gives the dark-grey "default action" weight that
407
- * design systems typically use for neutral buttons. The "strong"
408
- * solid variant clamps higher emphasis (same shade, kept for the
409
- * solid-* API shape); "soft" softens to neutral-bold for inactive
410
- * states. */
635
+ /* derived states axis 2 offsets on each base fill */
636
+ --ty-solid-primary-hover: oklch(
637
+ from var(--ty-solid-primary) calc(l + var(--ty-solid-hover-l)) c h
638
+ );
639
+ --ty-solid-primary-active: oklch(
640
+ from var(--ty-solid-primary) calc(l + var(--ty-solid-active-l)) c h
641
+ );
642
+ --ty-solid-primary-strong: oklch(
643
+ from var(--ty-solid-primary) calc(l + var(--ty-solid-strong-l)) c h
644
+ );
645
+ --ty-solid-primary-soft: oklch(
646
+ from var(--ty-solid-primary) calc(l + var(--ty-solid-soft-l)) c h
647
+ );
411
648
 
412
- --ty-solid-neutral-soft: oklch(
413
- 0.6 calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
414
- var(--ty-neutral-hue)
649
+ --ty-solid-secondary-hover: oklch(
650
+ from var(--ty-solid-secondary) calc(l + var(--ty-solid-hover-l)) c h
415
651
  );
416
- --ty-solid-neutral: oklch(
417
- 0.4 calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
418
- var(--ty-neutral-hue)
652
+ --ty-solid-secondary-active: oklch(
653
+ from var(--ty-solid-secondary) calc(l + var(--ty-solid-active-l)) c h
654
+ );
655
+ --ty-solid-secondary-strong: oklch(
656
+ from var(--ty-solid-secondary) calc(l + var(--ty-solid-strong-l)) c h
657
+ );
658
+ --ty-solid-secondary-soft: oklch(
659
+ from var(--ty-solid-secondary) calc(l + var(--ty-solid-soft-l)) c h
419
660
  );
420
661
 
662
+ --ty-solid-success-hover: oklch(
663
+ from var(--ty-solid-success) calc(l + var(--ty-solid-hover-l)) c h
664
+ );
665
+ --ty-solid-success-active: oklch(
666
+ from var(--ty-solid-success) calc(l + var(--ty-solid-active-l)) c h
667
+ );
668
+ --ty-solid-success-strong: oklch(
669
+ from var(--ty-solid-success) calc(l + var(--ty-solid-strong-l)) c h
670
+ );
671
+ --ty-solid-success-soft: oklch(
672
+ from var(--ty-solid-success) calc(l + var(--ty-solid-soft-l)) c h
673
+ );
674
+
675
+ --ty-solid-danger-hover: oklch(
676
+ from var(--ty-solid-danger) calc(l + var(--ty-solid-hover-l)) c h
677
+ );
678
+ --ty-solid-danger-active: oklch(
679
+ from var(--ty-solid-danger) calc(l + var(--ty-solid-active-l)) c h
680
+ );
681
+ --ty-solid-danger-strong: oklch(
682
+ from var(--ty-solid-danger) calc(l + var(--ty-solid-strong-l)) c h
683
+ );
684
+ --ty-solid-danger-soft: oklch(
685
+ from var(--ty-solid-danger) calc(l + var(--ty-solid-soft-l)) c h
686
+ );
687
+
688
+ --ty-solid-warning-hover: oklch(
689
+ from var(--ty-solid-warning) calc(l + var(--ty-solid-hover-l)) c h
690
+ );
691
+ --ty-solid-warning-active: oklch(
692
+ from var(--ty-solid-warning) calc(l + var(--ty-solid-active-l)) c h
693
+ );
694
+ --ty-solid-warning-strong: oklch(
695
+ from var(--ty-solid-warning) calc(l + var(--ty-solid-strong-l)) c h
696
+ );
697
+ --ty-solid-warning-soft: oklch(
698
+ from var(--ty-solid-warning) calc(l + var(--ty-solid-soft-l)) c h
699
+ );
700
+
701
+ --ty-solid-neutral-hover: oklch(
702
+ from var(--ty-solid-neutral) calc(l + var(--ty-solid-hover-l)) c h
703
+ );
704
+ --ty-solid-neutral-active: oklch(
705
+ from var(--ty-solid-neutral) calc(l + var(--ty-solid-active-l)) c h
706
+ );
421
707
  --ty-solid-neutral-strong: oklch(
422
- 0.2 calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
423
- var(--ty-neutral-hue)
708
+ from var(--ty-solid-neutral) calc(l + var(--ty-solid-strong-l)) c h
709
+ );
710
+ --ty-solid-neutral-soft: oklch(
711
+ from var(--ty-solid-neutral) calc(l + var(--ty-solid-soft-l)) c h
424
712
  );
425
713
  }
426
714
 
427
715
  /* =====================================================================
428
- * DARK MODE L-curve and saturation-curve overridden. Same flavor
429
- * seeds drive both modes; only the L and chroma multipliers change.
716
+ * SECTION 2 DARK — same computations re-declared so html.dark (0,1,1)
717
+ * matches tyrell.css's hardcoded dark-mode hexes at source-order
718
+ * specificity. The math is identical to the :root block above; only
719
+ * the L/C inputs differ (from html.dark's Tier 3/4 overrides).
430
720
  * ===================================================================== */
431
721
 
432
722
  html.dark,
433
723
  html[data-theme="dark"] {
434
- --ty-l-strong: 0.86; /* ++ max emphasis in dark = brightest */
435
- --ty-l-bold: 0.74;
436
- --ty-l-base: 0.62;
437
- --ty-l-soft: 0.46;
438
- --ty-l-faint: 0.3; /* -- min emphasis = darkest */
439
-
440
- --ty-l-bg-base: 0.22;
441
- --ty-l-bg-bold: 0.26;
442
- --ty-l-bg-soft: 0.19;
443
-
444
- /* Saturation curve — dark pushes faint chroma up so dim shades don't
445
- * collapse into grey, and trims strong so bright tones don't over-pop. */
446
- --ty-c-strong-mult: 0.77;
447
- --ty-c-bold-mult: 1;
448
- --ty-c-base-mult: 0.92;
449
- --ty-c-soft-mult: 0.77;
450
- --ty-c-faint-mult: 0.5;
451
-
452
- --ty-c-bg-base-mult: 0.38;
453
- --ty-c-bg-bold-mult: 0.54;
454
- --ty-c-bg-soft-mult: 0.23;
455
-
456
- /* Color tokens re-declared here so we match tyrell.css's `html.dark` block
457
- * at the same selector specificity (0,1,1). Without these, tyrell.css's
458
- * hardcoded dark-mode hexes out-rank the brand-layer ':root' definitions
459
- * and the brand-hue slider does nothing in dark mode. The math is the
460
- * same as the light block — just uses the dark L-curve / chroma curve
461
- * defined above. */
462
-
463
724
  /* Primary */
464
725
  --ty-color-primary-strong: oklch(
465
- var(--ty-l-strong) calc(var(--ty-brand-chroma) * var(--ty-c-strong-mult))
466
- var(--ty-brand-hue)
726
+ calc(var(--ty-l-strong) * var(--ty-primary-l-factor))
727
+ calc(var(--ty-brand-chroma) * var(--ty-c-strong-mult)) var(--ty-brand-hue)
467
728
  );
468
729
  --ty-color-primary-bold: oklch(
469
- var(--ty-l-bold) calc(var(--ty-brand-chroma) * var(--ty-c-bold-mult))
470
- var(--ty-brand-hue)
730
+ calc(var(--ty-l-bold) * var(--ty-primary-l-factor))
731
+ calc(var(--ty-brand-chroma) * var(--ty-c-bold-mult)) var(--ty-brand-hue)
471
732
  );
472
733
  --ty-color-primary: oklch(
473
- var(--ty-l-base) calc(var(--ty-brand-chroma) * var(--ty-c-base-mult))
474
- var(--ty-brand-hue)
734
+ calc(var(--ty-l-base) * var(--ty-primary-l-factor))
735
+ calc(var(--ty-brand-chroma) * var(--ty-c-base-mult)) var(--ty-brand-hue)
475
736
  );
476
737
  --ty-color-primary-soft: oklch(
477
- var(--ty-l-soft) calc(var(--ty-brand-chroma) * var(--ty-c-soft-mult))
478
- var(--ty-brand-hue)
738
+ calc(var(--ty-l-soft) * var(--ty-primary-l-factor))
739
+ calc(var(--ty-brand-chroma) * var(--ty-c-soft-mult)) var(--ty-brand-hue)
479
740
  );
480
741
  --ty-color-primary-faint: oklch(
481
- var(--ty-l-faint) calc(var(--ty-brand-chroma) * var(--ty-c-faint-mult))
482
- var(--ty-brand-hue)
742
+ calc(var(--ty-l-faint) * var(--ty-primary-l-factor))
743
+ calc(var(--ty-brand-chroma) * var(--ty-c-faint-mult)) var(--ty-brand-hue)
483
744
  );
484
745
  --ty-bg-primary: oklch(
485
- var(--ty-l-bg-base) calc(var(--ty-brand-chroma) * var(--ty-c-bg-base-mult))
746
+ calc(var(--ty-l-bg-base) * var(--ty-primary-l-factor))
747
+ calc(var(--ty-brand-chroma) * var(--ty-c-bg-base-mult))
486
748
  var(--ty-brand-hue)
487
749
  );
488
750
  --ty-bg-primary-bold: oklch(
489
- var(--ty-l-bg-bold) calc(var(--ty-brand-chroma) * var(--ty-c-bg-bold-mult))
751
+ calc(var(--ty-l-bg-bold) * var(--ty-primary-l-factor))
752
+ calc(var(--ty-brand-chroma) * var(--ty-c-bg-bold-mult))
490
753
  var(--ty-brand-hue)
491
754
  );
492
755
  --ty-bg-primary-soft: oklch(
493
- var(--ty-l-bg-soft) calc(var(--ty-brand-chroma) * var(--ty-c-bg-soft-mult))
756
+ calc(var(--ty-l-bg-soft) * var(--ty-primary-l-factor))
757
+ calc(var(--ty-brand-chroma) * var(--ty-c-bg-soft-mult))
494
758
  var(--ty-brand-hue)
495
759
  );
496
760
  --ty-border-primary: var(--ty-color-primary-soft);
497
761
 
498
762
  /* Secondary */
499
763
  --ty-color-secondary-strong: oklch(
500
- var(--ty-l-strong)
764
+ calc(var(--ty-l-strong) * var(--ty-secondary-l-factor))
501
765
  calc(var(--ty-secondary-chroma) * var(--ty-c-strong-mult))
502
766
  var(--ty-secondary-hue)
503
767
  );
504
768
  --ty-color-secondary-bold: oklch(
505
- var(--ty-l-bold) calc(var(--ty-secondary-chroma) * var(--ty-c-bold-mult))
769
+ calc(var(--ty-l-bold) * var(--ty-secondary-l-factor))
770
+ calc(var(--ty-secondary-chroma) * var(--ty-c-bold-mult))
506
771
  var(--ty-secondary-hue)
507
772
  );
508
773
  --ty-color-secondary: oklch(
509
- var(--ty-l-base) calc(var(--ty-secondary-chroma) * var(--ty-c-base-mult))
774
+ calc(var(--ty-l-base) * var(--ty-secondary-l-factor))
775
+ calc(var(--ty-secondary-chroma) * var(--ty-c-base-mult))
510
776
  var(--ty-secondary-hue)
511
777
  );
512
778
  --ty-color-secondary-soft: oklch(
513
- var(--ty-l-soft) calc(var(--ty-secondary-chroma) * var(--ty-c-soft-mult))
779
+ calc(var(--ty-l-soft) * var(--ty-secondary-l-factor))
780
+ calc(var(--ty-secondary-chroma) * var(--ty-c-soft-mult))
514
781
  var(--ty-secondary-hue)
515
782
  );
516
783
  --ty-color-secondary-faint: oklch(
517
- var(--ty-l-faint) calc(var(--ty-secondary-chroma) * var(--ty-c-faint-mult))
784
+ calc(var(--ty-l-faint) * var(--ty-secondary-l-factor))
785
+ calc(var(--ty-secondary-chroma) * var(--ty-c-faint-mult))
518
786
  var(--ty-secondary-hue)
519
787
  );
520
788
  --ty-bg-secondary: oklch(
521
- var(--ty-l-bg-base)
789
+ calc(var(--ty-l-bg-base) * var(--ty-secondary-l-factor))
522
790
  calc(var(--ty-secondary-chroma) * var(--ty-c-bg-base-mult))
523
791
  var(--ty-secondary-hue)
524
792
  );
525
793
  --ty-bg-secondary-bold: oklch(
526
- var(--ty-l-bg-bold)
794
+ calc(var(--ty-l-bg-bold) * var(--ty-secondary-l-factor))
527
795
  calc(var(--ty-secondary-chroma) * var(--ty-c-bg-bold-mult))
528
796
  var(--ty-secondary-hue)
529
797
  );
530
798
  --ty-bg-secondary-soft: oklch(
531
- var(--ty-l-bg-soft)
799
+ calc(var(--ty-l-bg-soft) * var(--ty-secondary-l-factor))
532
800
  calc(var(--ty-secondary-chroma) * var(--ty-c-bg-soft-mult))
533
801
  var(--ty-secondary-hue)
534
802
  );
@@ -536,37 +804,42 @@ html[data-theme="dark"] {
536
804
 
537
805
  /* Success */
538
806
  --ty-color-success-strong: oklch(
539
- var(--ty-l-strong) calc(var(--ty-success-chroma) * var(--ty-c-strong-mult))
807
+ calc(var(--ty-l-strong) * var(--ty-success-l-factor))
808
+ calc(var(--ty-success-chroma) * var(--ty-c-strong-mult))
540
809
  var(--ty-success-hue)
541
810
  );
542
811
  --ty-color-success-bold: oklch(
543
- var(--ty-l-bold) calc(var(--ty-success-chroma) * var(--ty-c-bold-mult))
812
+ calc(var(--ty-l-bold) * var(--ty-success-l-factor))
813
+ calc(var(--ty-success-chroma) * var(--ty-c-bold-mult))
544
814
  var(--ty-success-hue)
545
815
  );
546
816
  --ty-color-success: oklch(
547
- var(--ty-l-base) calc(var(--ty-success-chroma) * var(--ty-c-base-mult))
817
+ calc(var(--ty-l-base) * var(--ty-success-l-factor))
818
+ calc(var(--ty-success-chroma) * var(--ty-c-base-mult))
548
819
  var(--ty-success-hue)
549
820
  );
550
821
  --ty-color-success-soft: oklch(
551
- var(--ty-l-soft) calc(var(--ty-success-chroma) * var(--ty-c-soft-mult))
822
+ calc(var(--ty-l-soft) * var(--ty-success-l-factor))
823
+ calc(var(--ty-success-chroma) * var(--ty-c-soft-mult))
552
824
  var(--ty-success-hue)
553
825
  );
554
826
  --ty-color-success-faint: oklch(
555
- var(--ty-l-faint) calc(var(--ty-success-chroma) * var(--ty-c-faint-mult))
827
+ calc(var(--ty-l-faint) * var(--ty-success-l-factor))
828
+ calc(var(--ty-success-chroma) * var(--ty-c-faint-mult))
556
829
  var(--ty-success-hue)
557
830
  );
558
831
  --ty-bg-success: oklch(
559
- var(--ty-l-bg-base)
832
+ calc(var(--ty-l-bg-base) * var(--ty-success-l-factor))
560
833
  calc(var(--ty-success-chroma) * var(--ty-c-bg-base-mult))
561
834
  var(--ty-success-hue)
562
835
  );
563
836
  --ty-bg-success-bold: oklch(
564
- var(--ty-l-bg-bold)
837
+ calc(var(--ty-l-bg-bold) * var(--ty-success-l-factor))
565
838
  calc(var(--ty-success-chroma) * var(--ty-c-bg-bold-mult))
566
839
  var(--ty-success-hue)
567
840
  );
568
841
  --ty-bg-success-soft: oklch(
569
- var(--ty-l-bg-soft)
842
+ calc(var(--ty-l-bg-soft) * var(--ty-success-l-factor))
570
843
  calc(var(--ty-success-chroma) * var(--ty-c-bg-soft-mult))
571
844
  var(--ty-success-hue)
572
845
  );
@@ -574,72 +847,82 @@ html[data-theme="dark"] {
574
847
 
575
848
  /* Danger */
576
849
  --ty-color-danger-strong: oklch(
577
- var(--ty-l-strong) calc(var(--ty-danger-chroma) * var(--ty-c-strong-mult))
850
+ calc(var(--ty-l-strong) * var(--ty-danger-l-factor))
851
+ calc(var(--ty-danger-chroma) * var(--ty-c-strong-mult))
578
852
  var(--ty-danger-hue)
579
853
  );
580
854
  --ty-color-danger-bold: oklch(
581
- var(--ty-l-bold) calc(var(--ty-danger-chroma) * var(--ty-c-bold-mult))
582
- var(--ty-danger-hue)
855
+ calc(var(--ty-l-bold) * var(--ty-danger-l-factor))
856
+ calc(var(--ty-danger-chroma) * var(--ty-c-bold-mult)) var(--ty-danger-hue)
583
857
  );
584
858
  --ty-color-danger: oklch(
585
- var(--ty-l-base) calc(var(--ty-danger-chroma) * var(--ty-c-base-mult))
586
- var(--ty-danger-hue)
859
+ calc(var(--ty-l-base) * var(--ty-danger-l-factor))
860
+ calc(var(--ty-danger-chroma) * var(--ty-c-base-mult)) var(--ty-danger-hue)
587
861
  );
588
862
  --ty-color-danger-soft: oklch(
589
- var(--ty-l-soft) calc(var(--ty-danger-chroma) * var(--ty-c-soft-mult))
590
- var(--ty-danger-hue)
863
+ calc(var(--ty-l-soft) * var(--ty-danger-l-factor))
864
+ calc(var(--ty-danger-chroma) * var(--ty-c-soft-mult)) var(--ty-danger-hue)
591
865
  );
592
866
  --ty-color-danger-faint: oklch(
593
- var(--ty-l-faint) calc(var(--ty-danger-chroma) * var(--ty-c-faint-mult))
867
+ calc(var(--ty-l-faint) * var(--ty-danger-l-factor))
868
+ calc(var(--ty-danger-chroma) * var(--ty-c-faint-mult))
594
869
  var(--ty-danger-hue)
595
870
  );
596
871
  --ty-bg-danger: oklch(
597
- var(--ty-l-bg-base) calc(var(--ty-danger-chroma) * var(--ty-c-bg-base-mult))
872
+ calc(var(--ty-l-bg-base) * var(--ty-danger-l-factor))
873
+ calc(var(--ty-danger-chroma) * var(--ty-c-bg-base-mult))
598
874
  var(--ty-danger-hue)
599
875
  );
600
876
  --ty-bg-danger-bold: oklch(
601
- var(--ty-l-bg-bold) calc(var(--ty-danger-chroma) * var(--ty-c-bg-bold-mult))
877
+ calc(var(--ty-l-bg-bold) * var(--ty-danger-l-factor))
878
+ calc(var(--ty-danger-chroma) * var(--ty-c-bg-bold-mult))
602
879
  var(--ty-danger-hue)
603
880
  );
604
881
  --ty-bg-danger-soft: oklch(
605
- var(--ty-l-bg-soft) calc(var(--ty-danger-chroma) * var(--ty-c-bg-soft-mult))
882
+ calc(var(--ty-l-bg-soft) * var(--ty-danger-l-factor))
883
+ calc(var(--ty-danger-chroma) * var(--ty-c-bg-soft-mult))
606
884
  var(--ty-danger-hue)
607
885
  );
608
886
  --ty-border-danger: var(--ty-color-danger-soft);
609
887
 
610
888
  /* Warning */
611
889
  --ty-color-warning-strong: oklch(
612
- var(--ty-l-strong) calc(var(--ty-warning-chroma) * var(--ty-c-strong-mult))
890
+ calc(var(--ty-l-strong) * var(--ty-warning-l-factor))
891
+ calc(var(--ty-warning-chroma) * var(--ty-c-strong-mult))
613
892
  var(--ty-warning-hue)
614
893
  );
615
894
  --ty-color-warning-bold: oklch(
616
- var(--ty-l-bold) calc(var(--ty-warning-chroma) * var(--ty-c-bold-mult))
895
+ calc(var(--ty-l-bold) * var(--ty-warning-l-factor))
896
+ calc(var(--ty-warning-chroma) * var(--ty-c-bold-mult))
617
897
  var(--ty-warning-hue)
618
898
  );
619
899
  --ty-color-warning: oklch(
620
- var(--ty-l-base) calc(var(--ty-warning-chroma) * var(--ty-c-base-mult))
900
+ calc(var(--ty-l-base) * var(--ty-warning-l-factor))
901
+ calc(var(--ty-warning-chroma) * var(--ty-c-base-mult))
621
902
  var(--ty-warning-hue)
622
903
  );
623
904
  --ty-color-warning-soft: oklch(
624
- var(--ty-l-soft) calc(var(--ty-warning-chroma) * var(--ty-c-soft-mult))
905
+ calc(var(--ty-l-soft) * var(--ty-warning-l-factor))
906
+ calc(var(--ty-warning-chroma) * var(--ty-c-soft-mult))
625
907
  var(--ty-warning-hue)
626
908
  );
627
909
  --ty-color-warning-faint: oklch(
628
- var(--ty-l-faint) calc(var(--ty-warning-chroma) * var(--ty-c-faint-mult))
910
+ calc(var(--ty-l-faint) * var(--ty-warning-l-factor))
911
+ calc(var(--ty-warning-chroma) * var(--ty-c-faint-mult))
629
912
  var(--ty-warning-hue)
630
913
  );
631
914
  --ty-bg-warning: oklch(
632
- var(--ty-l-bg-base)
915
+ calc(var(--ty-l-bg-base) * var(--ty-warning-l-factor))
633
916
  calc(var(--ty-warning-chroma) * var(--ty-c-bg-base-mult))
634
917
  var(--ty-warning-hue)
635
918
  );
636
919
  --ty-bg-warning-bold: oklch(
637
- var(--ty-l-bg-bold)
920
+ calc(var(--ty-l-bg-bold) * var(--ty-warning-l-factor))
638
921
  calc(var(--ty-warning-chroma) * var(--ty-c-bg-bold-mult))
639
922
  var(--ty-warning-hue)
640
923
  );
641
924
  --ty-bg-warning-soft: oklch(
642
- var(--ty-l-bg-soft)
925
+ calc(var(--ty-l-bg-soft) * var(--ty-warning-l-factor))
643
926
  calc(var(--ty-warning-chroma) * var(--ty-c-bg-soft-mult))
644
927
  var(--ty-warning-hue)
645
928
  );
@@ -647,37 +930,42 @@ html[data-theme="dark"] {
647
930
 
648
931
  /* Neutral */
649
932
  --ty-color-neutral-strong: oklch(
650
- var(--ty-l-strong) calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
933
+ calc(var(--ty-l-strong) * var(--ty-neutral-l-factor))
934
+ calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
651
935
  var(--ty-neutral-hue)
652
936
  );
653
937
  --ty-color-neutral-bold: oklch(
654
- var(--ty-l-bold) calc(var(--ty-neutral-chroma) * var(--ty-c-bold-mult))
938
+ calc(var(--ty-l-bold) * var(--ty-neutral-l-factor))
939
+ calc(var(--ty-neutral-chroma) * var(--ty-c-bold-mult))
655
940
  var(--ty-neutral-hue)
656
941
  );
657
942
  --ty-color-neutral: oklch(
658
- var(--ty-l-base) calc(var(--ty-neutral-chroma) * var(--ty-c-base-mult))
943
+ calc(var(--ty-l-base) * var(--ty-neutral-l-factor))
944
+ calc(var(--ty-neutral-chroma) * var(--ty-c-base-mult))
659
945
  var(--ty-neutral-hue)
660
946
  );
661
947
  --ty-color-neutral-soft: oklch(
662
- var(--ty-l-soft) calc(var(--ty-neutral-chroma) * var(--ty-c-soft-mult))
948
+ calc(var(--ty-l-soft) * var(--ty-neutral-l-factor))
949
+ calc(var(--ty-neutral-chroma) * var(--ty-c-soft-mult))
663
950
  var(--ty-neutral-hue)
664
951
  );
665
952
  --ty-color-neutral-faint: oklch(
666
- var(--ty-l-faint) calc(var(--ty-neutral-chroma) * var(--ty-c-faint-mult))
953
+ calc(var(--ty-l-faint) * var(--ty-neutral-l-factor))
954
+ calc(var(--ty-neutral-chroma) * var(--ty-c-faint-mult))
667
955
  var(--ty-neutral-hue)
668
956
  );
669
957
  --ty-bg-neutral: oklch(
670
- var(--ty-l-bg-base)
958
+ calc(var(--ty-l-bg-base) * var(--ty-neutral-l-factor))
671
959
  calc(var(--ty-neutral-chroma) * var(--ty-c-bg-base-mult))
672
960
  var(--ty-neutral-hue)
673
961
  );
674
962
  --ty-bg-neutral-bold: oklch(
675
- var(--ty-l-bg-bold)
963
+ calc(var(--ty-l-bg-bold) * var(--ty-neutral-l-factor))
676
964
  calc(var(--ty-neutral-chroma) * var(--ty-c-bg-bold-mult))
677
965
  var(--ty-neutral-hue)
678
966
  );
679
967
  --ty-bg-neutral-soft: oklch(
680
- var(--ty-l-bg-soft)
968
+ calc(var(--ty-l-bg-soft) * var(--ty-neutral-l-factor))
681
969
  calc(var(--ty-neutral-chroma) * var(--ty-c-bg-soft-mult))
682
970
  var(--ty-neutral-hue)
683
971
  );
@@ -695,20 +983,18 @@ html[data-theme="dark"] {
695
983
  --ty-border-soft: var(--ty-color-neutral-faint);
696
984
  --ty-border-faint: var(--ty-color-neutral-faint);
697
985
 
698
- /* Surfaces — flip dark with a hint of brand chroma. */
699
- --ty-surface-canvas: oklch(0.12 0.012 var(--ty-brand-hue));
700
- --ty-surface-content: oklch(0.16 0.012 var(--ty-brand-hue));
701
- --ty-surface-elevated: oklch(0.19 0.013 var(--ty-brand-hue));
702
- --ty-surface-floating: oklch(0.22 0.015 var(--ty-brand-hue));
703
- --ty-surface-input: oklch(0.18 0.012 var(--ty-brand-hue));
986
+ /* Surfaces — monochrome by default; --ty-surface-chroma warms them. */
987
+ --ty-surface-canvas: oklch(0.12 var(--ty-surface-chroma) var(--ty-brand-hue));
988
+ --ty-surface-content: oklch(0.16 var(--ty-surface-chroma) var(--ty-brand-hue));
989
+ --ty-surface-elevated: oklch(0.19 var(--ty-surface-chroma) var(--ty-brand-hue));
990
+ --ty-surface-floating: oklch(0.22 var(--ty-surface-chroma) var(--ty-brand-hue));
991
+ --ty-surface-input: oklch(0.18 var(--ty-surface-chroma) var(--ty-brand-hue));
704
992
 
705
- /* Inputs — re-declared so tyrell.css's hardcoded dark values don't
706
- * out-rank our brand-derived ones (same selector specificity, source
707
- * order wins). */
993
+ /* Inputs — re-declared at html.dark specificity. */
708
994
  --ty-input-bg: var(--ty-surface-input);
709
995
  --ty-input-color: var(--ty-color-neutral-strong);
710
996
  --ty-input-border: var(--ty-color-neutral-faint);
711
- --ty-input-border-hover: var(--ty-color-neutral-bold);
997
+ --ty-input-border-hover: var(--ty-color-neutral-soft);
712
998
  --ty-input-border-focus: var(--ty-color-primary);
713
999
  --ty-input-placeholder: var(--ty-color-neutral-soft);
714
1000
  --ty-input-disabled-bg: var(--ty-color-neutral-faint);
@@ -720,48 +1006,10 @@ html[data-theme="dark"] {
720
1006
  transparent
721
1007
  );
722
1008
 
723
- /* Solid buttonssame reason. */
724
- --ty-solid-primary: var(--ty-color-primary);
725
- --ty-solid-primary-strong: var(--ty-color-primary-bold);
726
- --ty-solid-primary-soft: var(--ty-color-primary-soft);
727
- --ty-solid-primary-fg: white;
728
-
729
- --ty-solid-secondary: var(--ty-color-secondary);
730
- --ty-solid-secondary-strong: var(--ty-color-secondary-bold);
731
- --ty-solid-secondary-soft: var(--ty-color-secondary-soft);
732
- --ty-solid-secondary-fg: white;
733
-
734
- --ty-solid-success: var(--ty-color-success);
735
- --ty-solid-success-strong: var(--ty-color-success-bold);
736
- --ty-solid-success-soft: var(--ty-color-success-soft);
737
- --ty-solid-success-fg: white;
738
-
739
- --ty-solid-danger: var(--ty-color-danger);
740
- --ty-solid-danger-strong: var(--ty-color-danger-bold);
741
- --ty-solid-danger-soft: var(--ty-color-danger-soft);
742
- --ty-solid-danger-fg: white;
743
-
744
- --ty-solid-warning: var(--ty-color-warning);
745
- --ty-solid-warning-strong: var(--ty-color-warning-bold);
746
- --ty-solid-warning-soft: var(--ty-color-warning-soft);
747
- --ty-solid-warning-fg: white;
748
-
749
- /* Solid neutral — see comment in the :root block. In dark mode the
750
- * "dark grey" position lives at the OTHER end of the ramp (faint),
751
- * because the L-curve inverts. Both modes get "a darker shade than
752
- * the page surface" for a punchy default action. */
753
- --ty-solid-neutral-soft: oklch(
754
- 0.2 calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
755
- var(--ty-neutral-hue)
756
- );
1009
+ /* Tier 6 dark solid dials live in SECTION 1's html.dark block.
1010
+ * neutral is hand-pinned (it ignores Axis B); dim it per theme here. */
757
1011
  --ty-solid-neutral: oklch(
758
1012
  0.3 calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
759
1013
  var(--ty-neutral-hue)
760
1014
  );
761
-
762
- --ty-solid-neutral-strong: oklch(
763
- 0.4 calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
764
- var(--ty-neutral-hue)
765
- );
766
- --ty-solid-neutral-fg: white;
767
1015
  }