@vielzeug/refine 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/dist/button.cjs +1 -1
  2. package/dist/button.cjs.map +1 -1
  3. package/dist/button.js +3 -3
  4. package/dist/button.js.map +1 -1
  5. package/dist/checkbox-group.cjs +7 -7
  6. package/dist/checkbox-group.cjs.map +1 -1
  7. package/dist/checkbox-group.js +35 -26
  8. package/dist/checkbox-group.js.map +1 -1
  9. package/dist/checkbox.cjs +3 -3
  10. package/dist/checkbox.cjs.map +1 -1
  11. package/dist/checkbox.js +24 -19
  12. package/dist/checkbox.js.map +1 -1
  13. package/dist/combobox.cjs +24 -24
  14. package/dist/combobox.cjs.map +1 -1
  15. package/dist/combobox.js +133 -129
  16. package/dist/combobox.js.map +1 -1
  17. package/dist/content/card/card.css.cjs +1 -1
  18. package/dist/content/card/card.css.cjs.map +1 -1
  19. package/dist/content/card/card.css.js +1 -1
  20. package/dist/content/card/card.css.js.map +1 -1
  21. package/dist/content/icon/icon.css.cjs +1 -1
  22. package/dist/content/icon/icon.css.cjs.map +1 -1
  23. package/dist/content/icon/icon.css.js +1 -1
  24. package/dist/content/icon/icon.css.js.map +1 -1
  25. package/dist/custom-elements.json +4711 -4209
  26. package/dist/feedback/toast/toast.css.cjs +1 -1
  27. package/dist/feedback/toast/toast.css.cjs.map +1 -1
  28. package/dist/feedback/toast/toast.css.js +1 -1
  29. package/dist/feedback/toast/toast.css.js.map +1 -1
  30. package/dist/headless/auto-resize.cjs +2 -0
  31. package/dist/headless/auto-resize.cjs.map +1 -0
  32. package/dist/headless/auto-resize.d.ts +29 -0
  33. package/dist/headless/auto-resize.d.ts.map +1 -0
  34. package/dist/headless/auto-resize.js +16 -0
  35. package/dist/headless/auto-resize.js.map +1 -0
  36. package/dist/headless/checkable.cjs +1 -1
  37. package/dist/headless/checkable.cjs.map +1 -1
  38. package/dist/headless/checkable.d.ts +25 -7
  39. package/dist/headless/checkable.d.ts.map +1 -1
  40. package/dist/headless/checkable.js +19 -14
  41. package/dist/headless/checkable.js.map +1 -1
  42. package/dist/headless/choice-field.cjs +1 -1
  43. package/dist/headless/choice-field.cjs.map +1 -1
  44. package/dist/headless/choice-field.d.ts +21 -0
  45. package/dist/headless/choice-field.d.ts.map +1 -1
  46. package/dist/headless/choice-field.js +27 -19
  47. package/dist/headless/choice-field.js.map +1 -1
  48. package/dist/headless/composer.cjs +2 -0
  49. package/dist/headless/composer.cjs.map +1 -0
  50. package/dist/headless/composer.d.ts +44 -0
  51. package/dist/headless/composer.d.ts.map +1 -0
  52. package/dist/headless/composer.js +21 -0
  53. package/dist/headless/composer.js.map +1 -0
  54. package/dist/headless/field-base.cjs +1 -1
  55. package/dist/headless/field-base.cjs.map +1 -1
  56. package/dist/headless/field-base.d.ts +97 -84
  57. package/dist/headless/field-base.d.ts.map +1 -1
  58. package/dist/headless/field-base.js +43 -32
  59. package/dist/headless/field-base.js.map +1 -1
  60. package/dist/headless/index.d.ts +3 -1
  61. package/dist/headless/index.d.ts.map +1 -1
  62. package/dist/headless/text-field.cjs +1 -1
  63. package/dist/headless/text-field.cjs.map +1 -1
  64. package/dist/headless/text-field.d.ts +40 -0
  65. package/dist/headless/text-field.d.ts.map +1 -1
  66. package/dist/headless/text-field.js +30 -25
  67. package/dist/headless/text-field.js.map +1 -1
  68. package/dist/headless.cjs +1 -1
  69. package/dist/headless.js +27 -25
  70. package/dist/index.cjs +1 -1
  71. package/dist/index.js +61 -60
  72. package/dist/input.cjs +9 -9
  73. package/dist/input.cjs.map +1 -1
  74. package/dist/input.js +49 -44
  75. package/dist/input.js.map +1 -1
  76. package/dist/inputs/button/button.css.cjs +1 -1
  77. package/dist/inputs/button/button.css.cjs.map +1 -1
  78. package/dist/inputs/button/button.css.js +1 -1
  79. package/dist/inputs/button/button.css.js.map +1 -1
  80. package/dist/inputs/checkbox/checkbox.css.cjs +1 -1
  81. package/dist/inputs/checkbox/checkbox.css.cjs.map +1 -1
  82. package/dist/inputs/checkbox/checkbox.css.js +1 -1
  83. package/dist/inputs/checkbox/checkbox.css.js.map +1 -1
  84. package/dist/inputs/checkbox/checkbox.d.ts +3 -0
  85. package/dist/inputs/checkbox/checkbox.d.ts.map +1 -1
  86. package/dist/inputs/checkbox-group/checkbox-group.css.cjs +1 -1
  87. package/dist/inputs/checkbox-group/checkbox-group.css.cjs.map +1 -1
  88. package/dist/inputs/checkbox-group/checkbox-group.css.js +1 -1
  89. package/dist/inputs/checkbox-group/checkbox-group.css.js.map +1 -1
  90. package/dist/inputs/combobox/combobox.d.ts +1 -0
  91. package/dist/inputs/combobox/combobox.d.ts.map +1 -1
  92. package/dist/inputs/combobox/combobox.types.d.ts +2 -0
  93. package/dist/inputs/combobox/combobox.types.d.ts.map +1 -1
  94. package/dist/inputs/file-input/file-input.css.cjs +1 -1
  95. package/dist/inputs/file-input/file-input.css.cjs.map +1 -1
  96. package/dist/inputs/file-input/file-input.css.js +1 -1
  97. package/dist/inputs/file-input/file-input.css.js.map +1 -1
  98. package/dist/inputs/index.d.ts +2 -0
  99. package/dist/inputs/index.d.ts.map +1 -1
  100. package/dist/inputs/input/input.css.cjs +1 -1
  101. package/dist/inputs/input/input.css.cjs.map +1 -1
  102. package/dist/inputs/input/input.css.js +1 -1
  103. package/dist/inputs/input/input.css.js.map +1 -1
  104. package/dist/inputs/input/input.d.ts.map +1 -1
  105. package/dist/inputs/message-composer/message-composer.css.cjs +2 -0
  106. package/dist/inputs/message-composer/message-composer.css.cjs.map +1 -0
  107. package/dist/inputs/message-composer/message-composer.css.js +6 -0
  108. package/dist/inputs/message-composer/message-composer.css.js.map +1 -0
  109. package/dist/inputs/message-composer/message-composer.d.ts +139 -0
  110. package/dist/inputs/message-composer/message-composer.d.ts.map +1 -0
  111. package/dist/inputs/otp-input/otp-input.css.cjs +1 -1
  112. package/dist/inputs/otp-input/otp-input.css.cjs.map +1 -1
  113. package/dist/inputs/otp-input/otp-input.css.js +1 -1
  114. package/dist/inputs/otp-input/otp-input.css.js.map +1 -1
  115. package/dist/inputs/radio/radio.css.cjs +1 -1
  116. package/dist/inputs/radio/radio.css.cjs.map +1 -1
  117. package/dist/inputs/radio/radio.css.js +1 -1
  118. package/dist/inputs/radio/radio.css.js.map +1 -1
  119. package/dist/inputs/radio-group/radio-group.css.cjs +1 -1
  120. package/dist/inputs/radio-group/radio-group.css.cjs.map +1 -1
  121. package/dist/inputs/radio-group/radio-group.css.js +1 -1
  122. package/dist/inputs/radio-group/radio-group.css.js.map +1 -1
  123. package/dist/inputs/rating/rating.css.cjs +1 -1
  124. package/dist/inputs/rating/rating.css.cjs.map +1 -1
  125. package/dist/inputs/rating/rating.css.js +1 -1
  126. package/dist/inputs/rating/rating.css.js.map +1 -1
  127. package/dist/inputs/shared/field-binding.cjs +1 -1
  128. package/dist/inputs/shared/field-binding.cjs.map +1 -1
  129. package/dist/inputs/shared/field-binding.d.ts +15 -0
  130. package/dist/inputs/shared/field-binding.d.ts.map +1 -1
  131. package/dist/inputs/shared/field-binding.js +4 -3
  132. package/dist/inputs/shared/field-binding.js.map +1 -1
  133. package/dist/inputs/shared/form-context.cjs.map +1 -1
  134. package/dist/inputs/shared/form-context.d.ts +6 -0
  135. package/dist/inputs/shared/form-context.d.ts.map +1 -1
  136. package/dist/inputs/shared/form-context.js.map +1 -1
  137. package/dist/inputs/slider/slider.css.cjs +1 -1
  138. package/dist/inputs/slider/slider.css.cjs.map +1 -1
  139. package/dist/inputs/slider/slider.css.js +1 -1
  140. package/dist/inputs/slider/slider.css.js.map +1 -1
  141. package/dist/inputs/switch/switch.css.cjs +1 -1
  142. package/dist/inputs/switch/switch.css.cjs.map +1 -1
  143. package/dist/inputs/switch/switch.css.js +1 -1
  144. package/dist/inputs/switch/switch.css.js.map +1 -1
  145. package/dist/inputs/textarea/textarea.css.cjs +1 -1
  146. package/dist/inputs/textarea/textarea.css.cjs.map +1 -1
  147. package/dist/inputs/textarea/textarea.css.js +1 -1
  148. package/dist/inputs/textarea/textarea.css.js.map +1 -1
  149. package/dist/inputs/textarea/textarea.d.ts.map +1 -1
  150. package/dist/layout/navbar/navbar.css.cjs +1 -1
  151. package/dist/layout/navbar/navbar.css.cjs.map +1 -1
  152. package/dist/layout/navbar/navbar.css.js +1 -1
  153. package/dist/layout/navbar/navbar.css.js.map +1 -1
  154. package/dist/layout/sidebar/sidebar.css.cjs +1 -1
  155. package/dist/layout/sidebar/sidebar.css.cjs.map +1 -1
  156. package/dist/layout/sidebar/sidebar.css.js +1 -1
  157. package/dist/layout/sidebar/sidebar.css.js.map +1 -1
  158. package/dist/message-composer.cjs +52 -0
  159. package/dist/message-composer.cjs.map +1 -0
  160. package/dist/message-composer.js +168 -0
  161. package/dist/message-composer.js.map +1 -0
  162. package/dist/ore/dist/base-element.cjs +1 -1
  163. package/dist/ore/dist/base-element.cjs.map +1 -1
  164. package/dist/ore/dist/base-element.js +13 -3
  165. package/dist/ore/dist/base-element.js.map +1 -1
  166. package/dist/ore/dist/forms/field.cjs +1 -1
  167. package/dist/ore/dist/forms/field.cjs.map +1 -1
  168. package/dist/ore/dist/forms/field.js +29 -22
  169. package/dist/ore/dist/forms/field.js.map +1 -1
  170. package/dist/ore/dist/runtime.cjs +1 -1
  171. package/dist/ore/dist/runtime.cjs.map +1 -1
  172. package/dist/ore/dist/runtime.js +3 -1
  173. package/dist/ore/dist/runtime.js.map +1 -1
  174. package/dist/overlay/menu/menu.css.cjs +1 -1
  175. package/dist/overlay/menu/menu.css.cjs.map +1 -1
  176. package/dist/overlay/menu/menu.css.js +1 -1
  177. package/dist/overlay/menu/menu.css.js.map +1 -1
  178. package/dist/radio-group.cjs +9 -9
  179. package/dist/radio-group.cjs.map +1 -1
  180. package/dist/radio-group.js +44 -38
  181. package/dist/radio-group.js.map +1 -1
  182. package/dist/radio.cjs +3 -3
  183. package/dist/radio.cjs.map +1 -1
  184. package/dist/radio.js +23 -24
  185. package/dist/radio.js.map +1 -1
  186. package/dist/refine.cjs +228 -181
  187. package/dist/refine.cjs.map +1 -1
  188. package/dist/refine.iife.js +228 -181
  189. package/dist/refine.iife.js.map +1 -1
  190. package/dist/refine.js +251 -204
  191. package/dist/refine.js.map +1 -1
  192. package/dist/select.cjs +31 -31
  193. package/dist/select.cjs.map +1 -1
  194. package/dist/select.js +125 -122
  195. package/dist/select.js.map +1 -1
  196. package/dist/shared/size-presets.cjs +1 -1
  197. package/dist/shared/size-presets.cjs.map +1 -1
  198. package/dist/shared/size-presets.d.ts +23 -0
  199. package/dist/shared/size-presets.d.ts.map +1 -1
  200. package/dist/shared/size-presets.js +17 -1
  201. package/dist/shared/size-presets.js.map +1 -1
  202. package/dist/styles/mixins/animation.css.cjs +0 -3
  203. package/dist/styles/mixins/animation.css.cjs.map +1 -1
  204. package/dist/styles/mixins/animation.css.d.ts +12 -4
  205. package/dist/styles/mixins/animation.css.d.ts.map +1 -1
  206. package/dist/styles/mixins/animation.css.js +0 -3
  207. package/dist/styles/mixins/animation.css.js.map +1 -1
  208. package/dist/styles/mixins/variants.css.cjs.map +1 -1
  209. package/dist/styles/mixins/variants.css.d.ts +7 -2
  210. package/dist/styles/mixins/variants.css.d.ts.map +1 -1
  211. package/dist/styles/mixins/variants.css.js.map +1 -1
  212. package/dist/styles/theme.css +341 -132
  213. package/dist/switch.cjs +3 -3
  214. package/dist/switch.cjs.map +1 -1
  215. package/dist/switch.js +17 -18
  216. package/dist/switch.js.map +1 -1
  217. package/dist/textarea.cjs +15 -15
  218. package/dist/textarea.cjs.map +1 -1
  219. package/dist/textarea.js +64 -60
  220. package/dist/textarea.js.map +1 -1
  221. package/package.json +21 -9
@@ -113,6 +113,23 @@
113
113
  --grid-11: repeat(11, minmax(0, 1fr));
114
114
  --grid-12: repeat(12, minmax(0, 1fr));
115
115
 
116
+ /* ========================================
117
+ Z-Index Scale
118
+ A page only has one stacking context to reason about — every layer
119
+ (sticky headers, dropdowns, overlays, modals, popovers, tooltips,
120
+ toasts) needs one shared, monotonic scale, not ad-hoc literals
121
+ scattered across components and page code alike.
122
+ ======================================== */
123
+ --z-base: 0;
124
+ --z-sticky: 40;
125
+ --z-dropdown: 100;
126
+ --z-fixed: 300;
127
+ --z-overlay: 500;
128
+ --z-modal: 600;
129
+ --z-popover: 1000;
130
+ --z-tooltip: 1100;
131
+ --z-toast: 9999;
132
+
116
133
  /* ========================================
117
134
  Border Widths
118
135
  ======================================== */
@@ -161,21 +178,30 @@
161
178
  All shadows use light-dark() to remain visible in dark mode.
162
179
  ======================================== */
163
180
  --shadow-none: 0 0 transparent;
164
- --shadow-2xs: light-dark(0 1px 2px rgb(0 0 0 / 3%), 0 1px 2px rgb(0 0 0 / 20%));
165
- --shadow-xs: light-dark(0 2px 4px rgb(0 0 0 / 3%), 0 2px 4px rgb(0 0 0 / 22%));
166
- --shadow-sm: light-dark(0 4px 10px -1px rgb(0 0 0 / 5%), 0 4px 10px -1px rgb(0 0 0 / 28%));
167
- --shadow: light-dark(0 8px 16px -2px rgb(0 0 0 / 6%), 0 8px 16px -2px rgb(0 0 0 / 32%));
168
- --shadow-md: light-dark(0 12px 24px -4px rgb(0 0 0 / 6%), 0 12px 24px -4px rgb(0 0 0 / 34%));
169
- --shadow-lg: light-dark(0 24px 32px -8px rgb(0 0 0 / 8%), 0 24px 32px -8px rgb(0 0 0 / 38%));
170
- --shadow-xl: light-dark(0 32px 64px -16px rgb(0 0 0 / 12%), 0 32px 64px -16px rgb(0 0 0 / 44%));
171
- --shadow-2xl: light-dark(0 48px 80px -20px rgb(0 0 0 / 20%), 0 48px 80px -20px rgb(0 0 0 / 52%));
172
-
173
- /* Inset Shadows — also light-dark() for dark mode depth */
181
+
182
+ /* light-dark() only accepts <color> arguments (spec: CSS Color 5) — these used
183
+ to wrap the *entire* shadow (offset + blur + color), which is invalid CSS.
184
+ Custom properties store any token soup, so the declaration itself never
185
+ errored, but every consumer substituting it into an actual `box-shadow`
186
+ got an unparseable value and silently computed to `none` in spec-compliant
187
+ browsers. Fixed by keeping offset/blur outside and wrapping only the color
188
+ — offset/blur are identical between light and dark here anyway, only the
189
+ alpha differs. */
190
+ --shadow-2xs: 0 1px 2px light-dark(rgb(0 0 0 / 3%), rgb(0 0 0 / 20%));
191
+ --shadow-xs: 0 2px 4px light-dark(rgb(0 0 0 / 3%), rgb(0 0 0 / 22%));
192
+ --shadow-sm: 0 4px 10px -1px light-dark(rgb(0 0 0 / 5%), rgb(0 0 0 / 28%));
193
+ --shadow: 0 8px 16px -2px light-dark(rgb(0 0 0 / 6%), rgb(0 0 0 / 32%));
194
+ --shadow-md: 0 12px 24px -4px light-dark(rgb(0 0 0 / 6%), rgb(0 0 0 / 34%));
195
+ --shadow-lg: 0 24px 32px -8px light-dark(rgb(0 0 0 / 8%), rgb(0 0 0 / 38%));
196
+ --shadow-xl: 0 32px 64px -16px light-dark(rgb(0 0 0 / 12%), rgb(0 0 0 / 44%));
197
+ --shadow-2xl: 0 48px 80px -20px light-dark(rgb(0 0 0 / 20%), rgb(0 0 0 / 52%));
198
+
199
+ /* Inset Shadows — same light-dark()-color-only fix as above. */
174
200
  --inset-shadow-none: inset 0 0 transparent;
175
- --inset-shadow-2xs: light-dark(inset 0 1px rgb(0 0 0 / 5%), inset 0 1px rgb(255 255 255 / 4%));
176
- --inset-shadow-xs: light-dark(inset 0 1px 1px rgb(0 0 0 / 5%), inset 0 1px 1px rgb(255 255 255 / 4%));
177
- --inset-shadow-sm: light-dark(inset 0 2px 4px rgb(0 0 0 / 5%), inset 0 2px 4px rgb(0 0 0 / 25%));
178
- --inset-shadow: light-dark(inset 0 2px 4px rgb(0 0 0 / 6%), inset 0 2px 4px rgb(0 0 0 / 28%));
201
+ --inset-shadow-2xs: inset 0 1px light-dark(rgb(0 0 0 / 5%), rgb(255 255 255 / 4%));
202
+ --inset-shadow-xs: inset 0 1px 1px light-dark(rgb(0 0 0 / 5%), rgb(255 255 255 / 4%));
203
+ --inset-shadow-sm: inset 0 2px 4px light-dark(rgb(0 0 0 / 5%), rgb(0 0 0 / 25%));
204
+ --inset-shadow: inset 0 2px 4px light-dark(rgb(0 0 0 / 6%), rgb(0 0 0 / 28%));
179
205
 
180
206
  /* Drop Shadows (for filters) */
181
207
  --drop-shadow-none: 0 0 transparent;
@@ -319,7 +345,9 @@
319
345
  ======================================== */
320
346
  color-scheme: light dark;
321
347
 
322
- /* Contrast scale — Neutral OKLCH with a lifted, non-pure-black Dark Mode baseline */
348
+ /* ── theme-tokens:generated:begin — run `pnpm run sync:theme`, do not hand-edit ── */
349
+
350
+ /* ── Contrast scale — Neutral OKLCH with a lifted, non-pure-black Dark Mode baseline ── */
323
351
  --color-contrast-50: light-dark(oklch(99% 0.001 264deg), oklch(17% 0.001 250deg)); /* Canvas, page background */
324
352
  --color-contrast-100: light-dark(oklch(97% 0.001 264deg), oklch(21% 0.001 250deg)); /* Cards, elevated surfaces */
325
353
  --color-contrast-150: light-dark(
@@ -337,7 +365,7 @@
337
365
  --color-contrast-500: light-dark(
338
366
  oklch(49% 0.002 264deg),
339
367
  oklch(58% 0.001 250deg)
340
- ); /* Tertiary text - AA compliant */
368
+ ); /* Tertiary text - AA large-text compliant */
341
369
 
342
370
  --color-contrast-600: light-dark(
343
371
  oklch(40% 0.002 264deg),
@@ -355,166 +383,336 @@
355
383
  --color-divider: color-mix(in oklch, var(--color-contrast-300) 85%, transparent);
356
384
  --color-contrast: color-mix(in oklch, var(--color-contrast-900) 85%, transparent);
357
385
 
358
- /* Halo Shadows */
386
+ /* ── Shade ramp — shared derivation recipe for every color family below ──── */
387
+
388
+ /* Every family only authors a `base` (+ content/contrast ink pair); every */
389
+
390
+ /* other sub-token is `oklch(from var(--color-x) ...)`, derived from that */
391
+
392
+ /* single base using the deltas below. Tune a family by editing its base; */
393
+
394
+ /* tune the ramp shape itself (e.g. how much lighter "-lighter" is) here, */
395
+
396
+ /* once, for all 7 families at once. */
397
+ --shade-lighter-l: 0.3;
398
+ --shade-lighter-c: 0.35;
399
+ --shade-light-l: 0.14;
400
+ --shade-light-c: 0.8;
401
+ --shade-dark-l: -0.14;
402
+ --shade-darker-l: -0.26;
403
+ --shade-darker-c: 0.85;
404
+ --shade-darker-h: -12;
405
+ --shade-focus-l: 0.06;
406
+ --shade-border-alpha: 60%;
407
+ --shade-focus-ring-strength: 40%;
408
+ --shade-backdrop-l-light: 93%;
409
+ --shade-backdrop-l-dark: 24%;
410
+ --shade-backdrop-c-light: 0.3;
411
+ --shade-backdrop-c-dark: 0.5;
412
+ --shade-backdrop-alpha-light: 83%;
413
+ --shade-backdrop-alpha-dark: 50%;
414
+ --shade-halo-glow: 15%;
415
+ --shade-halo-glow-soft: 8%;
416
+
417
+ /* ── Halo shadows — branded glow per color family ───────────────────────── */
359
418
  --halo-shadow-neutral:
360
419
  inset 0 1px 1px light-dark(rgb(0 0 0 / 5%), rgb(0 0 0 / 15%)),
361
420
  0 0 var(--size-1) light-dark(rgb(255 255 255 / 10%), rgb(0 0 0 / 20%)) inset,
362
- 0 var(--size-2) var(--size-6) light-dark(oklch(58% 0 264deg / 15%), oklch(72% 0 250deg / 15%)),
363
- 0 var(--size-1) var(--size-3) light-dark(oklch(58% 0 264deg / 8%), oklch(72% 0 250deg / 8%));
421
+ 0 var(--size-2) var(--size-6) color-mix(in oklch, var(--color-neutral) var(--shade-halo-glow), transparent),
422
+ 0 var(--size-1) var(--size-3) color-mix(in oklch, var(--color-neutral) var(--shade-halo-glow-soft), transparent);
364
423
  --halo-shadow-primary:
365
424
  inset 0 1px 1px light-dark(rgb(0 0 0 / 5%), rgb(255 255 255 / 3%)),
366
425
  0 0 var(--size-1) light-dark(rgb(255 255 255 / 10%), rgb(255 255 255 / 12%)) inset,
367
- 0 var(--size-2) var(--size-6) color-mix(in oklch, var(--color-primary) 15%, transparent),
368
- 0 var(--size-1) var(--size-3) color-mix(in oklch, var(--color-primary) 8%, transparent);
426
+ 0 var(--size-2) var(--size-6) color-mix(in oklch, var(--color-primary) var(--shade-halo-glow), transparent),
427
+ 0 var(--size-1) var(--size-3) color-mix(in oklch, var(--color-primary) var(--shade-halo-glow-soft), transparent);
369
428
  --halo-shadow-secondary:
370
429
  inset 0 1px 1px light-dark(rgb(0 0 0 / 5%), rgb(255 255 255 / 3%)),
371
430
  0 0 var(--size-1) light-dark(rgb(255 255 255 / 10%), rgb(255 255 255 / 12%)) inset,
372
- 0 var(--size-2) var(--size-6) color-mix(in oklch, var(--color-secondary) 12%, transparent),
373
- 0 var(--size-1) var(--size-3) color-mix(in oklch, var(--color-secondary) 7%, transparent);
431
+ 0 var(--size-2) var(--size-6) color-mix(in oklch, var(--color-secondary) var(--shade-halo-glow), transparent),
432
+ 0 var(--size-1) var(--size-3) color-mix(in oklch, var(--color-secondary) var(--shade-halo-glow-soft), transparent);
374
433
  --halo-shadow-info:
375
434
  inset 0 1px 1px light-dark(rgb(0 0 0 / 5%), rgb(255 255 255 / 3%)),
376
435
  0 0 var(--size-1) light-dark(rgb(255 255 255 / 10%), rgb(255 255 255 / 12%)) inset,
377
- 0 var(--size-2) var(--size-6) light-dark(oklch(60% 0.18 230deg / 15%), oklch(74% 0.16 230deg / 15%)),
378
- 0 var(--size-1) var(--size-3) light-dark(oklch(60% 0.18 230deg / 8%), oklch(74% 0.16 230deg / 8%));
436
+ 0 var(--size-2) var(--size-6) color-mix(in oklch, var(--color-info) var(--shade-halo-glow), transparent),
437
+ 0 var(--size-1) var(--size-3) color-mix(in oklch, var(--color-info) var(--shade-halo-glow-soft), transparent);
379
438
  --halo-shadow-success:
380
439
  inset 0 1px 1px light-dark(rgb(0 0 0 / 5%), rgb(255 255 255 / 3%)),
381
440
  0 0 var(--size-1) light-dark(rgb(255 255 255 / 10%), rgb(255 255 255 / 12%)) inset,
382
- 0 var(--size-2) var(--size-6) light-dark(oklch(62% 0.15 160deg / 15%), oklch(78% 0.14 160deg / 15%)),
383
- 0 var(--size-1) var(--size-3) light-dark(oklch(62% 0.15 160deg / 8%), oklch(78% 0.14 160deg / 8%));
441
+ 0 var(--size-2) var(--size-6) color-mix(in oklch, var(--color-success) var(--shade-halo-glow), transparent),
442
+ 0 var(--size-1) var(--size-3) color-mix(in oklch, var(--color-success) var(--shade-halo-glow-soft), transparent);
384
443
  --halo-shadow-warning:
385
444
  inset 0 1px 1px light-dark(rgb(0 0 0 / 5%), rgb(255 255 255 / 3%)),
386
445
  0 0 var(--size-1) light-dark(rgb(255 255 255 / 10%), rgb(255 255 255 / 12%)) inset,
387
- 0 var(--size-2) var(--size-6) light-dark(oklch(74% 0.18 70deg / 15%), oklch(84% 0.16 70deg / 15%)),
388
- 0 var(--size-1) var(--size-3) light-dark(oklch(74% 0.18 70deg / 8%), oklch(84% 0.16 70deg / 8%));
446
+ 0 var(--size-2) var(--size-6) color-mix(in oklch, var(--color-warning) var(--shade-halo-glow), transparent),
447
+ 0 var(--size-1) var(--size-3) color-mix(in oklch, var(--color-warning) var(--shade-halo-glow-soft), transparent);
389
448
  --halo-shadow-error:
390
449
  inset 0 1px 1px light-dark(rgb(0 0 0 / 5%), rgb(255 255 255 / 3%)),
391
450
  0 0 var(--size-1) light-dark(rgb(255 255 255 / 10%), rgb(255 255 255 / 12%)) inset,
392
- 0 var(--size-2) var(--size-6) light-dark(oklch(54% 0.2 29deg / 15%), oklch(66% 0.18 29deg / 15%)),
393
- 0 var(--size-1) var(--size-3) light-dark(oklch(54% 0.2 29deg / 8%), oklch(66% 0.18 29deg / 8%));
394
-
395
- /* ── Neutral ─────────────────────────────────────────────────────────────── */
396
- --color-neutral: light-dark(oklch(56% 0 264deg), oklch(72% 0 250deg));
397
- --color-neutral-backdrop: light-dark(oklch(97% 0 264deg / 83%), oklch(27% 0 250deg / 60%));
398
- --color-neutral-content: light-dark(oklch(98% 0 264deg), oklch(15% 0 250deg));
399
- --color-neutral-contrast: light-dark(oklch(99% 0 264deg), oklch(13% 0 250deg));
400
- --color-neutral-focus: light-dark(oklch(62% 0 264deg), oklch(78% 0 250deg));
401
- --color-neutral-border: light-dark(oklch(86% 0 264deg / 75%), oklch(72% 0 250deg / 40%));
451
+ 0 var(--size-2) var(--size-6) color-mix(in oklch, var(--color-error) var(--shade-halo-glow), transparent),
452
+ 0 var(--size-1) var(--size-3) color-mix(in oklch, var(--color-error) var(--shade-halo-glow-soft), transparent);
453
+
454
+ /* ── Neutral — True gray — neutral UI surfaces ── */
455
+ --color-neutral: light-dark(oklch(52% 0 264deg), oklch(72% 0 250deg));
456
+ --color-neutral-backdrop: light-dark(
457
+ oklch(
458
+ from var(--color-neutral) var(--shade-backdrop-l-light) calc(c * var(--shade-backdrop-c-light)) h /
459
+ var(--shade-backdrop-alpha-light)
460
+ ),
461
+ oklch(
462
+ from var(--color-neutral) var(--shade-backdrop-l-dark) calc(c * var(--shade-backdrop-c-dark)) h /
463
+ var(--shade-backdrop-alpha-dark)
464
+ )
465
+ );
466
+ --color-neutral-content: light-dark(
467
+ oklch(from var(--color-neutral) 99% calc(c * 0) h),
468
+ oklch(from var(--color-neutral) 22% calc(c * 0) h)
469
+ );
470
+ --color-neutral-contrast: light-dark(
471
+ oklch(from var(--color-neutral) 99% calc(c * 0) h),
472
+ oklch(from var(--color-neutral) 13% calc(c * 0) h)
473
+ );
474
+ --color-neutral-lighter: oklch(
475
+ from var(--color-neutral) clamp(0, calc(l + var(--shade-lighter-l)), 1) calc(c * var(--shade-lighter-c)) h
476
+ );
477
+ --color-neutral-light: oklch(
478
+ from var(--color-neutral) clamp(0, calc(l + var(--shade-light-l)), 1) calc(c * var(--shade-light-c)) h
479
+ );
480
+ --color-neutral-dark: oklch(from var(--color-neutral) clamp(0, calc(l + var(--shade-dark-l)), 1) c h);
481
+ --color-neutral-darker: oklch(
482
+ from var(--color-neutral) clamp(0, calc(l + var(--shade-darker-l)), 1) calc(c * var(--shade-darker-c))
483
+ calc(h + var(--shade-darker-h))
484
+ );
485
+ --color-neutral-focus: oklch(from var(--color-neutral) clamp(0, calc(l + var(--shade-focus-l)), 1) c h);
486
+ --color-neutral-border: oklch(from var(--color-neutral) l c h / var(--shade-border-alpha));
402
487
  --color-neutral-focus-shadow:
403
- 0 0 0 4px color-mix(in oklch, var(--color-neutral) 40%, transparent), var(--shadow-sm);
488
+ 0 0 0 4px color-mix(in oklch, var(--color-neutral) var(--shade-focus-ring-strength), transparent),
489
+ var(--shadow-sm);
404
490
 
405
- /* ── Primary hue — the single knob that themes both primary and secondary ──── */
406
-
407
- /* Override this one variable (e.g. 220deg for blue, 160deg for teal) to */
408
-
409
- /* shift the entire primary palette and have secondary auto-derive from it. */
491
+ /* ── Primary — Periwinkle violet — primary brand color ── */
410
492
  --color-primary-hue: 293deg;
411
-
412
- /* ── Primary (violet) ────────────────────────────────────────────────────── */
413
- --color-primary: light-dark(
414
- oklch(56% 0.22 var(--color-primary-hue)),
415
- oklch(72% 0.2 var(--color-primary-hue))
416
- ); /* Bright enough to read on dark canvas */
417
-
493
+ --color-primary: light-dark(oklch(56% 0.22 var(--color-primary-hue)), oklch(72% 0.148 var(--color-primary-hue)));
418
494
  --color-primary-backdrop: light-dark(
419
- oklch(93% 0.04 var(--color-primary-hue)),
420
- oklch(24% 0.1 var(--color-primary-hue) / 40%)
495
+ oklch(
496
+ from var(--color-primary) var(--shade-backdrop-l-light) calc(c * var(--shade-backdrop-c-light)) h /
497
+ var(--shade-backdrop-alpha-light)
498
+ ),
499
+ oklch(
500
+ from var(--color-primary) var(--shade-backdrop-l-dark) calc(c * var(--shade-backdrop-c-dark)) h /
501
+ var(--shade-backdrop-alpha-dark)
502
+ )
421
503
  );
422
504
  --color-primary-content: light-dark(
423
- oklch(98% 0.01 var(--color-primary-hue)),
424
- oklch(15% 0.08 var(--color-primary-hue))
425
- ); /* Dark ink on bright dark-mode button */
426
-
505
+ oklch(from var(--color-primary) 97% calc(c * 0.05) h),
506
+ oklch(from var(--color-primary) 22% calc(c * 0.3) h)
507
+ );
427
508
  --color-primary-contrast: light-dark(
428
- oklch(98% 0.01 var(--color-primary-hue)),
429
- oklch(14% 0.06 var(--color-primary-hue))
509
+ oklch(from var(--color-primary) 98% calc(c * 0.045) h),
510
+ oklch(from var(--color-primary) 14% calc(c * 0.3) h)
511
+ );
512
+ --color-primary-lighter: oklch(
513
+ from var(--color-primary) clamp(0, calc(l + var(--shade-lighter-l)), 1) calc(c * var(--shade-lighter-c)) h
430
514
  );
431
- --color-primary-focus: light-dark(
432
- oklch(62% 0.22 var(--color-primary-hue)),
433
- oklch(78% 0.2 var(--color-primary-hue))
515
+ --color-primary-light: oklch(
516
+ from var(--color-primary) clamp(0, calc(l + var(--shade-light-l)), 1) calc(c * var(--shade-light-c)) h
434
517
  );
435
- --color-primary-border: light-dark(
436
- oklch(56% 0.22 var(--color-primary-hue) / 60%),
437
- oklch(72% 0.2 var(--color-primary-hue) / 60%)
518
+ --color-primary-dark: oklch(from var(--color-primary) clamp(0, calc(l + var(--shade-dark-l)), 1) c h);
519
+ --color-primary-darker: oklch(
520
+ from var(--color-primary) clamp(0, calc(l + var(--shade-darker-l)), 1) calc(c * var(--shade-darker-c))
521
+ calc(h + var(--shade-darker-h))
438
522
  );
523
+ --color-primary-focus: oklch(from var(--color-primary) clamp(0, calc(l + var(--shade-focus-l)), 1) c h);
524
+ --color-primary-border: oklch(from var(--color-primary) l c h / var(--shade-border-alpha));
439
525
  --color-primary-focus-shadow:
440
- 0 0 0 4px color-mix(in oklch, var(--color-primary) 40%, transparent), var(--shadow-sm);
441
-
442
- /* ── Secondary — auto-derived from --color-primary-hue ─────────────────────── */
443
-
444
- /* Near-black (light) / near-white (dark) with a subtle tint of the primary */
445
-
446
- /* hue. Mixing 7 % of the primary chroma/hue into an achromatic near-black or */
526
+ 0 0 0 4px color-mix(in oklch, var(--color-primary) var(--shade-focus-ring-strength), transparent),
527
+ var(--shadow-sm);
447
528
 
448
- /* near-white base gives a visually grounded dark that breathes with the brand. */
529
+ /* ── Secondary — Ink/charcoal (light) · silver (dark) — auto-derived from --color-primary-hue ── */
449
530
  --color-secondary: light-dark(
450
- color-mix(in oklch, oklch(20% 0 none) 93%, oklch(56% 0.22 var(--color-primary-hue))),
451
- color-mix(in oklch, oklch(83% 0 none) 93%, oklch(72% 0.2 var(--color-primary-hue)))
531
+ color-mix(in oklch, oklch(20% 0 none) 86%, var(--color-primary)),
532
+ color-mix(in oklch, oklch(83% 0 none) 86%, var(--color-primary))
452
533
  );
453
534
  --color-secondary-backdrop: light-dark(
454
- color-mix(in oklch, oklch(95% 0 none / 83%) 97%, oklch(56% 0.22 var(--color-primary-hue) / 83%)),
455
- color-mix(in oklch, oklch(20% 0 none / 60%) 97%, oklch(72% 0.2 var(--color-primary-hue) / 60%))
535
+ oklch(
536
+ from var(--color-secondary) var(--shade-backdrop-l-light) calc(c * var(--shade-backdrop-c-light)) h /
537
+ var(--shade-backdrop-alpha-light)
538
+ ),
539
+ oklch(
540
+ from var(--color-secondary) var(--shade-backdrop-l-dark) calc(c * var(--shade-backdrop-c-dark)) h /
541
+ var(--shade-backdrop-alpha-dark)
542
+ )
456
543
  );
457
544
  --color-secondary-content: light-dark(
458
- oklch(98% 0.002 var(--color-primary-hue)),
459
- oklch(15% 0.003 var(--color-primary-hue))
545
+ oklch(from var(--color-secondary) 97% 0.0015 h),
546
+ oklch(from var(--color-secondary) 22% 0.002 h)
460
547
  );
461
548
  --color-secondary-contrast: light-dark(
462
- oklch(98% 0.002 var(--color-primary-hue)),
463
- oklch(13% 0.003 var(--color-primary-hue))
549
+ oklch(from var(--color-secondary) 98% 0.002 h),
550
+ oklch(from var(--color-secondary) 13% 0.003 h)
464
551
  );
465
- --color-secondary-focus: light-dark(
466
- color-mix(in oklch, oklch(28% 0 none) 93%, oklch(56% 0.22 var(--color-primary-hue))),
467
- color-mix(in oklch, oklch(90% 0 none) 93%, oklch(72% 0.2 var(--color-primary-hue)))
552
+ --color-secondary-lighter: oklch(
553
+ from var(--color-secondary) clamp(0, calc(l + var(--shade-lighter-l)), 1) calc(c * var(--shade-lighter-c)) h
468
554
  );
469
- --color-secondary-border: color-mix(in oklch, var(--color-secondary) 60%, transparent);
555
+ --color-secondary-light: oklch(
556
+ from var(--color-secondary) clamp(0, calc(l + var(--shade-light-l)), 1) calc(c * var(--shade-light-c)) h
557
+ );
558
+ --color-secondary-dark: oklch(from var(--color-secondary) clamp(0, calc(l + var(--shade-dark-l)), 1) c h);
559
+ --color-secondary-darker: oklch(
560
+ from var(--color-secondary) clamp(0, calc(l + var(--shade-darker-l)), 1) calc(c * var(--shade-darker-c))
561
+ calc(h + var(--shade-darker-h))
562
+ );
563
+ --color-secondary-focus: oklch(from var(--color-secondary) clamp(0, calc(l + var(--shade-focus-l)), 1) c h);
564
+ --color-secondary-border: oklch(from var(--color-secondary) l c h / var(--shade-border-alpha));
470
565
  --color-secondary-focus-shadow:
471
- 0 0 0 4px color-mix(in oklch, var(--color-secondary) 40%, transparent), var(--shadow-sm);
472
-
473
- /* ── Info (cyan-blue) ────────────────────────────────────────────────────── */
474
- --color-info: light-dark(oklch(60% 0.18 230deg), oklch(74% 0.16 230deg));
475
- --color-info-backdrop: light-dark(oklch(92% 0.06 230deg / 83%), oklch(24% 0.08 230deg / 50%));
566
+ 0 0 0 4px color-mix(in oklch, var(--color-secondary) var(--shade-focus-ring-strength), transparent),
567
+ var(--shadow-sm);
568
+
569
+ /* ── Info — Blue (light mode) · cyan-blue (dark mode) — informational messages ── */
570
+ --color-info: light-dark(oklch(54% 0.169 255deg), oklch(74% 0.133 230deg));
571
+ --color-info-backdrop: light-dark(
572
+ oklch(
573
+ from var(--color-info) var(--shade-backdrop-l-light) calc(c * var(--shade-backdrop-c-light)) h /
574
+ var(--shade-backdrop-alpha-light)
575
+ ),
576
+ oklch(
577
+ from var(--color-info) var(--shade-backdrop-l-dark) calc(c * var(--shade-backdrop-c-dark)) h /
578
+ var(--shade-backdrop-alpha-dark)
579
+ )
580
+ );
476
581
  --color-info-content: light-dark(
477
- oklch(15% 0.08 230deg),
478
- oklch(15% 0.08 230deg)
479
- ); /* Base is bright in both modes, content stays dark */
480
-
481
- --color-info-contrast: light-dark(oklch(97% 0.02 230deg), oklch(18% 0.06 230deg));
482
- --color-info-focus: light-dark(oklch(66% 0.18 230deg), oklch(80% 0.16 230deg));
483
- --color-info-border: light-dark(oklch(60% 0.18 230deg / 60%), oklch(74% 0.16 230deg / 60%));
484
- --color-info-focus-shadow: 0 0 0 4px color-mix(in oklch, var(--color-info) 40%, transparent), var(--shadow-sm);
485
-
486
- /* ── Success (teal-green) ────────────────────────────────────────────────── */
487
- --color-success: light-dark(
488
- oklch(62% 0.15 160deg),
489
- oklch(78% 0.14 160deg)
490
- ); /* Kept brighter than error for colorblindness */
491
-
492
- --color-success-backdrop: light-dark(oklch(93% 0.04 160deg / 83%), oklch(22% 0.07 160deg / 50%));
493
- --color-success-content: light-dark(oklch(15% 0.06 160deg), oklch(15% 0.06 160deg));
494
- --color-success-contrast: light-dark(oklch(97% 0.02 160deg), oklch(17% 0.06 160deg));
495
- --color-success-focus: light-dark(oklch(66% 0.15 160deg), oklch(84% 0.14 160deg));
496
- --color-success-border: light-dark(oklch(62% 0.15 160deg / 60%), oklch(78% 0.14 160deg / 60%));
582
+ oklch(from var(--color-info) 97% 0.0122 h),
583
+ oklch(from var(--color-info) 15% 0.024 h)
584
+ );
585
+ --color-info-contrast: light-dark(
586
+ oklch(from var(--color-info) 98% 0.0081 h),
587
+ oklch(from var(--color-info) 12% 0.019 h)
588
+ );
589
+ --color-info-lighter: oklch(
590
+ from var(--color-info) clamp(0, calc(l + var(--shade-lighter-l)), 1) calc(c * var(--shade-lighter-c)) h
591
+ );
592
+ --color-info-light: oklch(
593
+ from var(--color-info) clamp(0, calc(l + var(--shade-light-l)), 1) calc(c * var(--shade-light-c)) h
594
+ );
595
+ --color-info-dark: oklch(from var(--color-info) clamp(0, calc(l + var(--shade-dark-l)), 1) c h);
596
+ --color-info-darker: oklch(
597
+ from var(--color-info) clamp(0, calc(l + var(--shade-darker-l)), 1) calc(c * var(--shade-darker-c))
598
+ calc(h + var(--shade-darker-h))
599
+ );
600
+ --color-info-focus: oklch(from var(--color-info) clamp(0, calc(l + var(--shade-focus-l)), 1) c h);
601
+ --color-info-border: oklch(from var(--color-info) l c h / var(--shade-border-alpha));
602
+ --color-info-focus-shadow:
603
+ 0 0 0 4px color-mix(in oklch, var(--color-info) var(--shade-focus-ring-strength), transparent), var(--shadow-sm);
604
+
605
+ /* ── Success — Green (light mode) · teal (dark mode) — positive outcomes & confirmations ── */
606
+ --color-success: light-dark(oklch(53% 0.145 137deg), oklch(78% 0.14 160deg));
607
+ --color-success-backdrop: light-dark(
608
+ oklch(
609
+ from var(--color-success) var(--shade-backdrop-l-light) calc(c * var(--shade-backdrop-c-light)) h /
610
+ var(--shade-backdrop-alpha-light)
611
+ ),
612
+ oklch(
613
+ from var(--color-success) var(--shade-backdrop-l-dark) calc(c * var(--shade-backdrop-c-dark)) h /
614
+ var(--shade-backdrop-alpha-dark)
615
+ )
616
+ );
617
+ --color-success-content: light-dark(
618
+ oklch(from var(--color-success) 97% 0.0494 h),
619
+ oklch(from var(--color-success) 15% 0.027 h)
620
+ );
621
+ --color-success-contrast: light-dark(
622
+ oklch(from var(--color-success) 98% 0.0323 h),
623
+ oklch(from var(--color-success) 12% 0.022 h)
624
+ );
625
+ --color-success-lighter: oklch(
626
+ from var(--color-success) clamp(0, calc(l + var(--shade-lighter-l)), 1) calc(c * var(--shade-lighter-c)) h
627
+ );
628
+ --color-success-light: oklch(
629
+ from var(--color-success) clamp(0, calc(l + var(--shade-light-l)), 1) calc(c * var(--shade-light-c)) h
630
+ );
631
+ --color-success-dark: oklch(from var(--color-success) clamp(0, calc(l + var(--shade-dark-l)), 1) c h);
632
+ --color-success-darker: oklch(
633
+ from var(--color-success) clamp(0, calc(l + var(--shade-darker-l)), 1) calc(c * var(--shade-darker-c))
634
+ calc(h + var(--shade-darker-h))
635
+ );
636
+ --color-success-focus: oklch(from var(--color-success) clamp(0, calc(l + var(--shade-focus-l)), 1) c h);
637
+ --color-success-border: oklch(from var(--color-success) l c h / var(--shade-border-alpha));
497
638
  --color-success-focus-shadow:
498
- 0 0 0 4px color-mix(in oklch, var(--color-success) 40%, transparent), var(--shadow-sm);
499
-
500
- /* ── Warning (amber) ─────────────────────────────────────────────────────── */
501
- --color-warning: light-dark(oklch(74% 0.18 70deg), oklch(84% 0.16 70deg));
502
- --color-warning-backdrop: light-dark(oklch(93% 0.07 70deg / 83%), oklch(26% 0.08 70deg / 50%));
503
- --color-warning-content: light-dark(oklch(15% 0.08 70deg), oklch(15% 0.08 70deg));
504
- --color-warning-contrast: light-dark(oklch(96% 0.03 70deg), oklch(22% 0.06 70deg));
505
- --color-warning-focus: light-dark(oklch(79% 0.18 70deg), oklch(90% 0.16 70deg));
506
- --color-warning-border: light-dark(oklch(74% 0.18 70deg / 60%), oklch(84% 0.16 70deg / 60%));
639
+ 0 0 0 4px color-mix(in oklch, var(--color-success) var(--shade-focus-ring-strength), transparent),
640
+ var(--shadow-sm);
641
+
642
+ /* ── Warning — Amber — cautionary states & alerts ── */
643
+ --color-warning: light-dark(oklch(54% 0.111 70deg), oklch(84% 0.113 70deg));
644
+ --color-warning-backdrop: light-dark(
645
+ oklch(
646
+ from var(--color-warning) var(--shade-backdrop-l-light) calc(c * var(--shade-backdrop-c-light)) h /
647
+ var(--shade-backdrop-alpha-light)
648
+ ),
649
+ oklch(
650
+ from var(--color-warning) var(--shade-backdrop-l-dark) calc(c * var(--shade-backdrop-c-dark)) h /
651
+ var(--shade-backdrop-alpha-dark)
652
+ )
653
+ );
654
+ --color-warning-content: light-dark(
655
+ oklch(from var(--color-warning) 97% 0.0184 h),
656
+ oklch(from var(--color-warning) 15% 0.026 h)
657
+ );
658
+ --color-warning-contrast: light-dark(
659
+ oklch(from var(--color-warning) 98% 0.0122 h),
660
+ oklch(from var(--color-warning) 12% 0.021 h)
661
+ );
662
+ --color-warning-lighter: oklch(
663
+ from var(--color-warning) clamp(0, calc(l + var(--shade-lighter-l)), 1) calc(c * var(--shade-lighter-c)) h
664
+ );
665
+ --color-warning-light: oklch(
666
+ from var(--color-warning) clamp(0, calc(l + var(--shade-light-l)), 1) calc(c * var(--shade-light-c)) h
667
+ );
668
+ --color-warning-dark: oklch(from var(--color-warning) clamp(0, calc(l + var(--shade-dark-l)), 1) c h);
669
+ --color-warning-darker: oklch(
670
+ from var(--color-warning) clamp(0, calc(l + var(--shade-darker-l)), 1) calc(c * var(--shade-darker-c))
671
+ calc(h + var(--shade-darker-h))
672
+ );
673
+ --color-warning-focus: oklch(from var(--color-warning) clamp(0, calc(l + var(--shade-focus-l)), 1) c h);
674
+ --color-warning-border: oklch(from var(--color-warning) l c h / var(--shade-border-alpha));
507
675
  --color-warning-focus-shadow:
508
- 0 0 0 4px color-mix(in oklch, var(--color-warning) 40%, transparent), var(--shadow-sm);
509
-
510
- /* ── Error (red-orange) ──────────────────────────────────────────────────── */
511
- --color-error: light-dark(oklch(54% 0.2 29deg), oklch(66% 0.18 29deg)); /* Deeper than success for colorblindness */
512
- --color-error-backdrop: light-dark(oklch(92% 0.06 29deg / 83%), oklch(20% 0.08 29deg / 50%));
513
- --color-error-content: light-dark(oklch(98% 0.03 29deg), oklch(15% 0.06 29deg));
514
- --color-error-contrast: light-dark(oklch(97% 0.02 29deg), oklch(16% 0.06 29deg));
515
- --color-error-focus: light-dark(oklch(60% 0.2 29deg), oklch(72% 0.18 29deg));
516
- --color-error-border: light-dark(oklch(54% 0.2 29deg / 60%), oklch(66% 0.18 29deg / 60%));
517
- --color-error-focus-shadow: 0 0 0 4px color-mix(in oklch, var(--color-error) 40%, transparent), var(--shadow-sm);
676
+ 0 0 0 4px color-mix(in oklch, var(--color-warning) var(--shade-focus-ring-strength), transparent),
677
+ var(--shadow-sm);
678
+
679
+ /* ── Error — Vermilion — destructive actions & errors ── */
680
+ --color-error: light-dark(oklch(54% 0.2 29deg), oklch(66% 0.18 29deg));
681
+ --color-error-backdrop: light-dark(
682
+ oklch(
683
+ from var(--color-error) var(--shade-backdrop-l-light) calc(c * var(--shade-backdrop-c-light)) h /
684
+ var(--shade-backdrop-alpha-light)
685
+ ),
686
+ oklch(
687
+ from var(--color-error) var(--shade-backdrop-l-dark) calc(c * var(--shade-backdrop-c-dark)) h /
688
+ var(--shade-backdrop-alpha-dark)
689
+ )
690
+ );
691
+ --color-error-content: light-dark(
692
+ oklch(from var(--color-error) 97% 0.0125 h),
693
+ oklch(from var(--color-error) 22% 0.077 h)
694
+ );
695
+ --color-error-contrast: light-dark(
696
+ oklch(from var(--color-error) 98% 0.0088 h),
697
+ oklch(from var(--color-error) 14% 0.052 h)
698
+ );
699
+ --color-error-lighter: oklch(
700
+ from var(--color-error) clamp(0, calc(l + var(--shade-lighter-l)), 1) calc(c * var(--shade-lighter-c)) h
701
+ );
702
+ --color-error-light: oklch(
703
+ from var(--color-error) clamp(0, calc(l + var(--shade-light-l)), 1) calc(c * var(--shade-light-c)) h
704
+ );
705
+ --color-error-dark: oklch(from var(--color-error) clamp(0, calc(l + var(--shade-dark-l)), 1) c h);
706
+ --color-error-darker: oklch(
707
+ from var(--color-error) clamp(0, calc(l + var(--shade-darker-l)), 1) calc(c * var(--shade-darker-c))
708
+ calc(h + var(--shade-darker-h))
709
+ );
710
+ --color-error-focus: oklch(from var(--color-error) clamp(0, calc(l + var(--shade-focus-l)), 1) c h);
711
+ --color-error-border: oklch(from var(--color-error) l c h / var(--shade-border-alpha));
712
+ --color-error-focus-shadow:
713
+ 0 0 0 4px color-mix(in oklch, var(--color-error) var(--shade-focus-ring-strength), transparent), var(--shadow-sm);
714
+
715
+ /* ── theme-tokens:generated:end ── */
518
716
  }
519
717
 
520
718
  /* ========================================
@@ -541,12 +739,23 @@
541
739
  }
542
740
  }
543
741
 
544
- /* VitePress dark theme: force dark color-scheme so light-dark() resolves to dark values */
742
+ /* Refine's dark-mode contract: toggle `classList.add/remove('dark')` on */
743
+
744
+ /* `<html>`, nothing else. Forcing `color-scheme` here (rather than only */
745
+
746
+ /* relying on `prefers-color-scheme`) is what makes every `light-dark()` */
747
+
748
+ /* token in this file resolve to the right branch once `.dark` is present, */
749
+
750
+ /* overriding the OS preference. See docs/refine/theming.md "Toggle dark */
751
+
752
+ /* mode" — any consumer, not just this repo's own docs site, can rely on */
753
+
754
+ /* this class toggle. */
545
755
  html.dark {
546
756
  color-scheme: dark;
547
757
  }
548
758
 
549
- /* VitePress light theme: force light color-scheme so light-dark() resolves to light values */
550
759
  html:not(.dark) {
551
760
  color-scheme: light;
552
761
  }
package/dist/switch.cjs CHANGED
@@ -1,10 +1,10 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./styles/mixins/states.css.cjs"),n=require("./styles/mixins/theme.css.cjs"),r=require("./shared/prop-bundles.cjs"),i=require("./shared/size-presets.cjs"),a=require("./headless/ore.cjs"),o=require("./headless/checkable.cjs"),s=require("./ore/dist/forms/field.cjs");require("./ore/dist/forms.cjs");const c=require("./inputs/shared/field-binding.cjs"),l=require("./inputs/shared/form-context.cjs"),u=require("./inputs/shared/templates.cjs"),d=require("./inputs/switch/switch.css.cjs");let f=require("@vielzeug/ore");var p=`ore-switch`;(0,f.define)(p,{formAssociated:!0,props:{...r.themableBundle,...r.sizableBundle,...r.disablableBundle,checked:f.prop.bool(!1),error:f.prop.string(),helper:f.prop.string(),name:f.prop.string(),value:f.prop.string(`on`)},setup(e){let t=(0,f.useEmit)(),n=(0,f.inject)(l.FORM_CTX),r=l.useFormContext(e,n),i=null,d=o.createCheckable({checked:e.checked,clearIndeterminateFirst:!1,disabled:r.disabled,error:e.error,getFormField:()=>i,helper:e.helper,onToggle:e=>{d.triggerValidation(`change`),t(`change`,e)},prefix:`switch`,signal:a.lifecycleSignal(f.onCleanup),validateOn:n?.validateOn,value:e.value});i=s.useField({disabled:d.disabled,toFormValue:e=>e,value:d.checkableFormValue});let{assistiveId:p,checked:m,disabled:h,errorText:g,handleClick:_,handleKeydown:v,helperText:y,labelId:b}=d;return c.applyCheckableBinding(r.size,{assistiveId:p,checked:m,disabled:h,errorText:g,handleClick:_,handleKeydown:v,helperText:y,labelId:b},`switch`),f.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./styles/mixins/states.css.cjs"),n=require("./styles/mixins/theme.css.cjs"),r=require("./shared/prop-bundles.cjs"),i=require("./shared/size-presets.cjs"),a=require("./headless/ore.cjs"),o=require("./headless/checkable.cjs"),s=require("./ore/dist/forms/field.cjs");require("./ore/dist/forms.cjs");const c=require("./inputs/shared/field-binding.cjs"),l=require("./inputs/shared/form-context.cjs"),u=require("./inputs/shared/templates.cjs"),d=require("./inputs/switch/switch.css.cjs");let f=require("@vielzeug/ore");var p=`ore-switch`;(0,f.define)(p,{formAssociated:!0,props:{...r.themableBundle,...r.sizableBundle,...r.disablableBundle,checked:f.prop.bool(!1),error:f.prop.string(),helper:f.prop.string(),name:f.prop.string(),value:f.prop.string(`on`)},setup(e){let t=(0,f.useEmit)(),n=(0,f.inject)(l.FORM_CTX),r=l.useFormContext(e,n),i=o.createCheckable({checked:e.checked,clearIndeterminateFirst:!1,disabled:r.disabled,error:e.error,helper:e.helper,onToggle:e=>{i.triggerValidation(`change`),t(`change`,e)},prefix:`switch`,signal:a.lifecycleSignal(f.onCleanup),validateOn:n?.validateOn,value:e.value});i.attachFormField(s.useField({disabled:i.disabled,toFormValue:e=>e,value:i.checkableFormValue}));let{assistiveId:d,checked:p,disabled:m,errorText:h,handleClick:g,handleKeydown:_,helperText:v,labelId:y}=i;return c.applyCheckableBinding(r.size,{assistiveId:d,checked:p,disabled:m,errorText:h,handleClick:g,handleKeydown:_,helperText:v,labelId:y},`switch`),f.html`
2
2
  <div class="switch-wrapper" part="switch">
3
3
  <div class="switch-track" part="track">
4
4
  <div class="switch-thumb" part="thumb"></div>
5
5
  </div>
6
6
  </div>
7
- <span class="label" part="label" id="${b}"><slot></slot></span>
8
- ${u.renderHelperRegion(p,g,y)}
7
+ <span class="label" part="label" id="${y}"><slot></slot></span>
8
+ ${u.renderHelperRegion(d,h,v)}
9
9
  `},styles:[n.colorThemeMixin,n.forcedColorsFormControlMixin,t.disabledStateMixin,e.sizeVariantMixin(i.SWITCH_SIZE_PRESET),d.default]}),exports.SWITCH_TAG=p;
10
10
  //# sourceMappingURL=switch.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"switch.cjs","names":[],"sources":["../src/inputs/switch/switch.ts"],"sourcesContent":["import { define, html, inject, prop, onCleanup, useEmit } from '@vielzeug/ore';\nimport { useField } from '@vielzeug/ore/forms';\n\nimport type { CheckableProps, ComponentSize, ThemeColor } from '../../types';\n\nimport { type CheckableChangePayload, lifecycleSignal, createCheckable } from '../../headless';\nimport { disablableBundle, sizableBundle, SWITCH_SIZE_PRESET, themableBundle } from '../../shared';\nimport { colorThemeMixin, disabledStateMixin, forcedColorsFormControlMixin, sizeVariantMixin } from '../../styles';\nimport { applyCheckableBinding } from '../shared/field-binding';\nimport { FORM_CTX, useFormContext } from '../shared/form-context';\nimport { renderHelperRegion } from '../shared/templates';\nimport componentStyles from './switch.css?inline';\n\nexport type OreSwitchEvents = {\n change: CheckableChangePayload;\n};\n\nexport type OreSwitchProps = CheckableProps & {\n /** Theme color */\n color?: ThemeColor;\n /** Disable interaction */\n disabled?: boolean;\n /** Error message (marks field as invalid) */\n error?: string;\n /** Helper text displayed below the switch */\n helper?: string;\n /** Component size */\n size?: ComponentSize;\n};\n\n/**\n * A toggle switch component for binary on/off states.\n *\n * @element ore-switch\n *\n * @attr {boolean} checked - Checked/on state\n * @attr {boolean} disabled - Disable switch interaction\n * @attr {string} value - Field value\n * @attr {string} name - Form field name\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} size - Switch size: 'sm' | 'md' | 'lg'\n * @attr {string} error - Error message (marks field as invalid)\n * @attr {string} helper - Helper text displayed below the switch\n *\n * @fires change - Emitted when switch is toggled. detail: { checked: boolean, value: string, originalEvent?: Event }\n *\n * @slot - Switch label text\n *\n * @cssprop --switch-width - Track width\n * @cssprop --switch-height - Track height\n * @cssprop --switch-track-bg - Inactive track background color\n * @cssprop --switch-checked-bg - Active/checked track background color\n * @cssprop --switch-thumb-bg - Thumb background color\n * @cssprop --switch-font-size - Label font size\n * @part switch - The switch wrapper element\n * @part track - The switch track element\n * @part thumb - The switch thumb element\n * @part label - The label element\n * @part helper-text - The helper/error text element\n *\n * @example\n * ```html\n * <ore-switch name=\"notifications\" checked color=\"primary\">Enable notifications</ore-switch>\n * <ore-switch name=\"darkMode\" size=\"sm\">Dark mode</ore-switch>\n * <ore-switch disabled helper=\"Contact admin to change\">Admin only</ore-switch>\n * ```\n */\nexport const SWITCH_TAG = 'ore-switch' as const;\ndefine<OreSwitchProps>(SWITCH_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n checked: prop.bool(false),\n error: prop.string(),\n helper: prop.string(),\n name: prop.string(),\n value: prop.string('on'),\n },\n setup(props) {\n const emit = useEmit<OreSwitchEvents>();\n\n const formCtx = inject(FORM_CTX);\n const fCtxProps = useFormContext(props, formCtx);\n\n let _formField: { reportValidity(): void } | null = null;\n const checkable = createCheckable({\n checked: props.checked,\n clearIndeterminateFirst: false,\n disabled: fCtxProps.disabled,\n error: props.error,\n getFormField: () => _formField,\n helper: props.helper,\n onToggle: (payload) => {\n checkable.triggerValidation('change');\n emit('change', payload);\n },\n prefix: 'switch',\n signal: lifecycleSignal(onCleanup),\n validateOn: formCtx?.validateOn,\n value: props.value,\n });\n\n _formField = useField<string | null>({\n disabled: checkable.disabled,\n toFormValue: (v) => v,\n value: checkable.checkableFormValue,\n });\n\n const { assistiveId, checked, disabled, errorText, handleClick, handleKeydown, helperText, labelId } = checkable;\n\n applyCheckableBinding(\n fCtxProps.size,\n { assistiveId, checked, disabled, errorText, handleClick, handleKeydown, helperText, labelId },\n 'switch',\n );\n\n return html`\n <div class=\"switch-wrapper\" part=\"switch\">\n <div class=\"switch-track\" part=\"track\">\n <div class=\"switch-thumb\" part=\"thumb\"></div>\n </div>\n </div>\n <span class=\"label\" part=\"label\" id=\"${labelId}\"><slot></slot></span>\n ${renderHelperRegion(assistiveId, errorText, helperText)}\n `;\n },\n styles: [\n colorThemeMixin,\n forcedColorsFormControlMixin,\n disabledStateMixin,\n sizeVariantMixin(SWITCH_SIZE_PRESET),\n componentStyles,\n ],\n});\n"],"mappings":"goBAmEA,IAAa,EAAa,0BACH,EAAY,CACjC,eAAgB,GAChB,MAAO,CACL,GAAG,EAAA,eACH,GAAG,EAAA,cACH,GAAG,EAAA,iBACH,QAAS,EAAA,KAAK,KAAK,EAAK,EACxB,MAAO,EAAA,KAAK,OAAO,EACnB,OAAQ,EAAA,KAAK,OAAO,EACpB,KAAM,EAAA,KAAK,OAAO,EAClB,MAAO,EAAA,KAAK,OAAO,IAAI,CACzB,EACA,MAAM,EAAO,CACX,IAAM,GAAA,EAAA,EAAA,QAAA,CAAgC,EAEhC,GAAA,EAAA,EAAA,OAAA,CAAiB,EAAA,QAAQ,EACzB,EAAY,EAAA,eAAe,EAAO,CAAO,EAE3C,EAAgD,KAC9C,EAAY,EAAA,gBAAgB,CAChC,QAAS,EAAM,QACf,wBAAyB,GACzB,SAAU,EAAU,SACpB,MAAO,EAAM,MACb,iBAAoB,EACpB,OAAQ,EAAM,OACd,SAAW,GAAY,CACrB,EAAU,kBAAkB,QAAQ,EACpC,EAAK,SAAU,CAAO,CACxB,EACA,OAAQ,SACR,OAAQ,EAAA,gBAAgB,EAAA,SAAS,EACjC,WAAY,GAAS,WACrB,MAAO,EAAM,KACf,CAAC,EAED,EAAa,EAAA,SAAwB,CACnC,SAAU,EAAU,SACpB,YAAc,GAAM,EACpB,MAAO,EAAU,kBACnB,CAAC,EAED,GAAM,CAAE,cAAa,UAAS,WAAU,YAAW,cAAa,gBAAe,aAAY,WAAY,EAQvG,OANA,EAAA,sBACE,EAAU,KACV,CAAE,cAAa,UAAS,WAAU,YAAW,cAAa,gBAAe,aAAY,SAAQ,EAC7F,QACF,EAEO,EAAA,IAAI;;;;;;6CAM8B,EAAQ;QAC7C,EAAA,mBAAmB,EAAa,EAAW,CAAU,EAAE;KAE7D,EACA,OAAQ,CACN,EAAA,gBACA,EAAA,6BACA,EAAA,mBACA,EAAA,iBAAiB,EAAA,kBAAkB,EACnC,EAAA,OACF,CACF,CAAC"}
1
+ {"version":3,"file":"switch.cjs","names":[],"sources":["../src/inputs/switch/switch.ts"],"sourcesContent":["import { define, html, inject, prop, onCleanup, useEmit } from '@vielzeug/ore';\nimport { useField } from '@vielzeug/ore/forms';\n\nimport type { CheckableProps, ComponentSize, ThemeColor } from '../../types';\n\nimport { type CheckableChangePayload, lifecycleSignal, createCheckable } from '../../headless';\nimport { disablableBundle, sizableBundle, SWITCH_SIZE_PRESET, themableBundle } from '../../shared';\nimport { colorThemeMixin, disabledStateMixin, forcedColorsFormControlMixin, sizeVariantMixin } from '../../styles';\nimport { applyCheckableBinding } from '../shared/field-binding';\nimport { FORM_CTX, useFormContext } from '../shared/form-context';\nimport { renderHelperRegion } from '../shared/templates';\nimport componentStyles from './switch.css?inline';\n\nexport type OreSwitchEvents = {\n change: CheckableChangePayload;\n};\n\nexport type OreSwitchProps = CheckableProps & {\n /** Theme color */\n color?: ThemeColor;\n /** Disable interaction */\n disabled?: boolean;\n /** Error message (marks field as invalid) */\n error?: string;\n /** Helper text displayed below the switch */\n helper?: string;\n /** Component size */\n size?: ComponentSize;\n};\n\n/**\n * A toggle switch component for binary on/off states.\n *\n * @element ore-switch\n *\n * @attr {boolean} checked - Checked/on state\n * @attr {boolean} disabled - Disable switch interaction\n * @attr {string} value - Field value\n * @attr {string} name - Form field name\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} size - Switch size: 'sm' | 'md' | 'lg'\n * @attr {string} error - Error message (marks field as invalid)\n * @attr {string} helper - Helper text displayed below the switch\n *\n * @fires change - Emitted when switch is toggled. detail: { checked: boolean, value: string, originalEvent?: Event }\n *\n * @slot - Switch label text\n *\n * @cssprop --switch-width - Track width\n * @cssprop --switch-height - Track height\n * @cssprop --switch-track-bg - Inactive track background color\n * @cssprop --switch-checked-bg - Active/checked track background color\n * @cssprop --switch-thumb-bg - Thumb background color\n * @cssprop --switch-font-size - Label font size\n * @part switch - The switch wrapper element\n * @part track - The switch track element\n * @part thumb - The switch thumb element\n * @part label - The label element\n * @part helper-text - The helper/error text element\n *\n * @example\n * ```html\n * <ore-switch name=\"notifications\" checked color=\"primary\">Enable notifications</ore-switch>\n * <ore-switch name=\"darkMode\" size=\"sm\">Dark mode</ore-switch>\n * <ore-switch disabled helper=\"Contact admin to change\">Admin only</ore-switch>\n * ```\n */\nexport const SWITCH_TAG = 'ore-switch' as const;\ndefine<OreSwitchProps>(SWITCH_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n checked: prop.bool(false),\n error: prop.string(),\n helper: prop.string(),\n name: prop.string(),\n value: prop.string('on'),\n },\n setup(props) {\n const emit = useEmit<OreSwitchEvents>();\n\n const formCtx = inject(FORM_CTX);\n const fCtxProps = useFormContext(props, formCtx);\n\n const checkable = createCheckable({\n checked: props.checked,\n clearIndeterminateFirst: false,\n disabled: fCtxProps.disabled,\n error: props.error,\n helper: props.helper,\n onToggle: (payload) => {\n checkable.triggerValidation('change');\n emit('change', payload);\n },\n prefix: 'switch',\n signal: lifecycleSignal(onCleanup),\n validateOn: formCtx?.validateOn,\n value: props.value,\n });\n\n checkable.attachFormField(\n useField<string | null>({\n disabled: checkable.disabled,\n toFormValue: (v) => v,\n value: checkable.checkableFormValue,\n }),\n );\n\n const { assistiveId, checked, disabled, errorText, handleClick, handleKeydown, helperText, labelId } = checkable;\n\n applyCheckableBinding(\n fCtxProps.size,\n { assistiveId, checked, disabled, errorText, handleClick, handleKeydown, helperText, labelId },\n 'switch',\n );\n\n return html`\n <div class=\"switch-wrapper\" part=\"switch\">\n <div class=\"switch-track\" part=\"track\">\n <div class=\"switch-thumb\" part=\"thumb\"></div>\n </div>\n </div>\n <span class=\"label\" part=\"label\" id=\"${labelId}\"><slot></slot></span>\n ${renderHelperRegion(assistiveId, errorText, helperText)}\n `;\n },\n styles: [\n colorThemeMixin,\n forcedColorsFormControlMixin,\n disabledStateMixin,\n sizeVariantMixin(SWITCH_SIZE_PRESET),\n componentStyles,\n ],\n});\n"],"mappings":"goBAmEA,IAAa,EAAa,0BACH,EAAY,CACjC,eAAgB,GAChB,MAAO,CACL,GAAG,EAAA,eACH,GAAG,EAAA,cACH,GAAG,EAAA,iBACH,QAAS,EAAA,KAAK,KAAK,EAAK,EACxB,MAAO,EAAA,KAAK,OAAO,EACnB,OAAQ,EAAA,KAAK,OAAO,EACpB,KAAM,EAAA,KAAK,OAAO,EAClB,MAAO,EAAA,KAAK,OAAO,IAAI,CACzB,EACA,MAAM,EAAO,CACX,IAAM,GAAA,EAAA,EAAA,QAAA,CAAgC,EAEhC,GAAA,EAAA,EAAA,OAAA,CAAiB,EAAA,QAAQ,EACzB,EAAY,EAAA,eAAe,EAAO,CAAO,EAEzC,EAAY,EAAA,gBAAgB,CAChC,QAAS,EAAM,QACf,wBAAyB,GACzB,SAAU,EAAU,SACpB,MAAO,EAAM,MACb,OAAQ,EAAM,OACd,SAAW,GAAY,CACrB,EAAU,kBAAkB,QAAQ,EACpC,EAAK,SAAU,CAAO,CACxB,EACA,OAAQ,SACR,OAAQ,EAAA,gBAAgB,EAAA,SAAS,EACjC,WAAY,GAAS,WACrB,MAAO,EAAM,KACf,CAAC,EAED,EAAU,gBACR,EAAA,SAAwB,CACtB,SAAU,EAAU,SACpB,YAAc,GAAM,EACpB,MAAO,EAAU,kBACnB,CAAC,CACH,EAEA,GAAM,CAAE,cAAa,UAAS,WAAU,YAAW,cAAa,gBAAe,aAAY,WAAY,EAQvG,OANA,EAAA,sBACE,EAAU,KACV,CAAE,cAAa,UAAS,WAAU,YAAW,cAAa,gBAAe,aAAY,SAAQ,EAC7F,QACF,EAEO,EAAA,IAAI;;;;;;6CAM8B,EAAQ;QAC7C,EAAA,mBAAmB,EAAa,EAAW,CAAU,EAAE;KAE7D,EACA,OAAQ,CACN,EAAA,gBACA,EAAA,6BACA,EAAA,mBACA,EAAA,iBAAiB,EAAA,kBAAkB,EACnC,EAAA,OACF,CACF,CAAC"}