luxen-ui 0.1.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 (201) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +98 -0
  3. package/dist/css/elements/avatar.css +20 -0
  4. package/dist/css/elements/badge.css +159 -0
  5. package/dist/css/elements/button.css +171 -0
  6. package/dist/css/elements/close-button/circle.css +66 -0
  7. package/dist/css/elements/close-button/ring.css +71 -0
  8. package/dist/css/elements/close-button/square.css +70 -0
  9. package/dist/css/elements/disclosure.css +137 -0
  10. package/dist/css/elements/divider.css +75 -0
  11. package/dist/css/elements/input-otp.css +164 -0
  12. package/dist/css/elements/input-stepper/default.css +245 -0
  13. package/dist/css/elements/input-stepper/rounded.css +238 -0
  14. package/dist/css/elements/kbd.css +21 -0
  15. package/dist/css/elements/progress.css +114 -0
  16. package/dist/css/elements/select.css +71 -0
  17. package/dist/css/elements/skeleton.css +89 -0
  18. package/dist/css/elements/tabs/enclosed.css +148 -0
  19. package/dist/css/elements/tabs/line.css +138 -0
  20. package/dist/css/elements/toast.css +260 -0
  21. package/dist/css/index.css +885 -0
  22. package/dist/custom-elements.json +14424 -0
  23. package/dist/define.d.ts +9 -0
  24. package/dist/define.d.ts.map +1 -0
  25. package/dist/define.js +16 -0
  26. package/dist/elements/avatar/avatar.css +128 -0
  27. package/dist/elements/avatar/avatar.d.ts +21 -0
  28. package/dist/elements/avatar/avatar.d.ts.map +1 -0
  29. package/dist/elements/avatar/avatar.js +106 -0
  30. package/dist/elements/avatar/index.d.ts +8 -0
  31. package/dist/elements/avatar/index.d.ts.map +1 -0
  32. package/dist/elements/avatar/index.js +4 -0
  33. package/dist/elements/badge/badge.d.ts +17 -0
  34. package/dist/elements/badge/badge.d.ts.map +1 -0
  35. package/dist/elements/badge/badge.js +34 -0
  36. package/dist/elements/badge/index.d.ts +8 -0
  37. package/dist/elements/badge/index.d.ts.map +1 -0
  38. package/dist/elements/badge/index.js +4 -0
  39. package/dist/elements/carousel/carousel.css +205 -0
  40. package/dist/elements/carousel/carousel.d.ts +148 -0
  41. package/dist/elements/carousel/carousel.d.ts.map +1 -0
  42. package/dist/elements/carousel/carousel.js +473 -0
  43. package/dist/elements/carousel/index.d.ts +8 -0
  44. package/dist/elements/carousel/index.d.ts.map +1 -0
  45. package/dist/elements/carousel/index.js +4 -0
  46. package/dist/elements/carousel-item/carousel-item.css +11 -0
  47. package/dist/elements/carousel-item/carousel-item.d.ts +13 -0
  48. package/dist/elements/carousel-item/carousel-item.d.ts.map +1 -0
  49. package/dist/elements/carousel-item/carousel-item.js +20 -0
  50. package/dist/elements/carousel-item/index.d.ts +8 -0
  51. package/dist/elements/carousel-item/index.d.ts.map +1 -0
  52. package/dist/elements/carousel-item/index.js +4 -0
  53. package/dist/elements/dialog/dialog.css +92 -0
  54. package/dist/elements/dialog/dialog.d.ts +56 -0
  55. package/dist/elements/dialog/dialog.d.ts.map +1 -0
  56. package/dist/elements/dialog/dialog.js +204 -0
  57. package/dist/elements/dialog/dialog.styles.d.ts +8 -0
  58. package/dist/elements/dialog/dialog.styles.d.ts.map +1 -0
  59. package/dist/elements/dialog/dialog.styles.js +8 -0
  60. package/dist/elements/dialog/index.d.ts +8 -0
  61. package/dist/elements/dialog/index.d.ts.map +1 -0
  62. package/dist/elements/dialog/index.js +4 -0
  63. package/dist/elements/divider/divider.d.ts +23 -0
  64. package/dist/elements/divider/divider.d.ts.map +1 -0
  65. package/dist/elements/divider/divider.js +49 -0
  66. package/dist/elements/divider/index.d.ts +8 -0
  67. package/dist/elements/divider/index.d.ts.map +1 -0
  68. package/dist/elements/divider/index.js +4 -0
  69. package/dist/elements/drawer/drawer.css +66 -0
  70. package/dist/elements/drawer/drawer.d.ts +34 -0
  71. package/dist/elements/drawer/drawer.d.ts.map +1 -0
  72. package/dist/elements/drawer/drawer.js +46 -0
  73. package/dist/elements/drawer/index.d.ts +8 -0
  74. package/dist/elements/drawer/index.d.ts.map +1 -0
  75. package/dist/elements/drawer/index.js +4 -0
  76. package/dist/elements/dropdown/dropdown.css +31 -0
  77. package/dist/elements/dropdown/dropdown.d.ts +64 -0
  78. package/dist/elements/dropdown/dropdown.d.ts.map +1 -0
  79. package/dist/elements/dropdown/dropdown.js +322 -0
  80. package/dist/elements/dropdown/index.d.ts +8 -0
  81. package/dist/elements/dropdown/index.d.ts.map +1 -0
  82. package/dist/elements/dropdown/index.js +4 -0
  83. package/dist/elements/dropdown-item/dropdown-item.css +51 -0
  84. package/dist/elements/dropdown-item/dropdown-item.d.ts +25 -0
  85. package/dist/elements/dropdown-item/dropdown-item.d.ts.map +1 -0
  86. package/dist/elements/dropdown-item/dropdown-item.js +110 -0
  87. package/dist/elements/dropdown-item/index.d.ts +8 -0
  88. package/dist/elements/dropdown-item/index.d.ts.map +1 -0
  89. package/dist/elements/dropdown-item/index.js +4 -0
  90. package/dist/elements/icon/icon.css +10 -0
  91. package/dist/elements/icon/icon.d.ts +19 -0
  92. package/dist/elements/icon/icon.d.ts.map +1 -0
  93. package/dist/elements/icon/icon.js +53 -0
  94. package/dist/elements/icon/index.d.ts +8 -0
  95. package/dist/elements/icon/index.d.ts.map +1 -0
  96. package/dist/elements/icon/index.js +4 -0
  97. package/dist/elements/input-otp/index.d.ts +8 -0
  98. package/dist/elements/input-otp/index.d.ts.map +1 -0
  99. package/dist/elements/input-otp/index.js +4 -0
  100. package/dist/elements/input-otp/input-otp.d.ts +31 -0
  101. package/dist/elements/input-otp/input-otp.d.ts.map +1 -0
  102. package/dist/elements/input-otp/input-otp.js +139 -0
  103. package/dist/elements/input-stepper/index.d.ts +8 -0
  104. package/dist/elements/input-stepper/index.d.ts.map +1 -0
  105. package/dist/elements/input-stepper/index.js +4 -0
  106. package/dist/elements/input-stepper/input-stepper.d.ts +63 -0
  107. package/dist/elements/input-stepper/input-stepper.d.ts.map +1 -0
  108. package/dist/elements/input-stepper/input-stepper.js +249 -0
  109. package/dist/elements/popover/index.d.ts +8 -0
  110. package/dist/elements/popover/index.d.ts.map +1 -0
  111. package/dist/elements/popover/index.js +4 -0
  112. package/dist/elements/popover/popover.css +61 -0
  113. package/dist/elements/popover/popover.d.ts +62 -0
  114. package/dist/elements/popover/popover.d.ts.map +1 -0
  115. package/dist/elements/popover/popover.js +244 -0
  116. package/dist/elements/rating/index.d.ts +8 -0
  117. package/dist/elements/rating/index.d.ts.map +1 -0
  118. package/dist/elements/rating/index.js +4 -0
  119. package/dist/elements/rating/rating.css +102 -0
  120. package/dist/elements/rating/rating.d.ts +38 -0
  121. package/dist/elements/rating/rating.d.ts.map +1 -0
  122. package/dist/elements/rating/rating.js +193 -0
  123. package/dist/elements/skeleton/index.d.ts +8 -0
  124. package/dist/elements/skeleton/index.d.ts.map +1 -0
  125. package/dist/elements/skeleton/index.js +4 -0
  126. package/dist/elements/skeleton/skeleton.d.ts +12 -0
  127. package/dist/elements/skeleton/skeleton.d.ts.map +1 -0
  128. package/dist/elements/skeleton/skeleton.js +13 -0
  129. package/dist/elements/spinner/index.d.ts +8 -0
  130. package/dist/elements/spinner/index.d.ts.map +1 -0
  131. package/dist/elements/spinner/index.js +4 -0
  132. package/dist/elements/spinner/spinner.css +28 -0
  133. package/dist/elements/spinner/spinner.d.ts +16 -0
  134. package/dist/elements/spinner/spinner.d.ts.map +1 -0
  135. package/dist/elements/spinner/spinner.js +37 -0
  136. package/dist/elements/tabs/index.d.ts +8 -0
  137. package/dist/elements/tabs/index.d.ts.map +1 -0
  138. package/dist/elements/tabs/index.js +4 -0
  139. package/dist/elements/tabs/tabs.d.ts +48 -0
  140. package/dist/elements/tabs/tabs.d.ts.map +1 -0
  141. package/dist/elements/tabs/tabs.js +210 -0
  142. package/dist/elements/toast/index.d.ts +9 -0
  143. package/dist/elements/toast/index.d.ts.map +1 -0
  144. package/dist/elements/toast/index.js +5 -0
  145. package/dist/elements/toast/toast.d.ts +72 -0
  146. package/dist/elements/toast/toast.d.ts.map +1 -0
  147. package/dist/elements/toast/toast.js +375 -0
  148. package/dist/elements/tooltip/index.d.ts +8 -0
  149. package/dist/elements/tooltip/index.d.ts.map +1 -0
  150. package/dist/elements/tooltip/index.js +4 -0
  151. package/dist/elements/tooltip/tooltip.css +37 -0
  152. package/dist/elements/tooltip/tooltip.d.ts +59 -0
  153. package/dist/elements/tooltip/tooltip.d.ts.map +1 -0
  154. package/dist/elements/tooltip/tooltip.js +231 -0
  155. package/dist/elements/tree/index.d.ts +8 -0
  156. package/dist/elements/tree/index.d.ts.map +1 -0
  157. package/dist/elements/tree/index.js +4 -0
  158. package/dist/elements/tree/tree.css +26 -0
  159. package/dist/elements/tree/tree.d.ts +76 -0
  160. package/dist/elements/tree/tree.d.ts.map +1 -0
  161. package/dist/elements/tree/tree.js +432 -0
  162. package/dist/elements/tree-item/index.d.ts +8 -0
  163. package/dist/elements/tree-item/index.d.ts.map +1 -0
  164. package/dist/elements/tree-item/index.js +4 -0
  165. package/dist/elements/tree-item/tree-item.css +172 -0
  166. package/dist/elements/tree-item/tree-item.d.ts +74 -0
  167. package/dist/elements/tree-item/tree-item.d.ts.map +1 -0
  168. package/dist/elements/tree-item/tree-item.js +301 -0
  169. package/dist/index.d.ts +6 -0
  170. package/dist/index.d.ts.map +1 -0
  171. package/dist/index.js +4 -0
  172. package/dist/registry.d.ts +22 -0
  173. package/dist/registry.d.ts.map +1 -0
  174. package/dist/registry.js +33 -0
  175. package/dist/shared/controllers/popover.d.ts +44 -0
  176. package/dist/shared/controllers/popover.d.ts.map +1 -0
  177. package/dist/shared/controllers/popover.js +359 -0
  178. package/dist/shared/luxen-element.d.ts +20 -0
  179. package/dist/shared/luxen-element.d.ts.map +1 -0
  180. package/dist/shared/luxen-element.js +23 -0
  181. package/dist/shared/luxen-form-associated-element.d.ts +49 -0
  182. package/dist/shared/luxen-form-associated-element.d.ts.map +1 -0
  183. package/dist/shared/luxen-form-associated-element.js +123 -0
  184. package/dist/shared/styles/host.css +13 -0
  185. package/dist/shared/styles/host.styles.d.ts +9 -0
  186. package/dist/shared/styles/host.styles.d.ts.map +1 -0
  187. package/dist/shared/styles/host.styles.js +9 -0
  188. package/dist/skills/luxen-ui/SKILL.md +82 -0
  189. package/dist/skills/luxen-ui/references/avatar.md +259 -0
  190. package/dist/skills/luxen-ui/references/badge.md +289 -0
  191. package/dist/skills/luxen-ui/references/button.md +309 -0
  192. package/dist/skills/luxen-ui/references/close-button.md +104 -0
  193. package/dist/skills/luxen-ui/references/dialog.md +435 -0
  194. package/dist/skills/luxen-ui/references/drawer.md +400 -0
  195. package/dist/skills/luxen-ui/references/progress.md +133 -0
  196. package/dist/skills/luxen-ui/references/select.md +100 -0
  197. package/dist/skills/luxen-ui/references/toast.md +396 -0
  198. package/dist/skills/luxen-ui/references/tree.md +359 -0
  199. package/package.json +116 -0
  200. package/postcss-plugin-prefix.js +63 -0
  201. package/vite-plugin.ts +29 -0
@@ -0,0 +1,885 @@
1
+ /**
2
+ CSS Extras - A collection of useful CSS custom functions
3
+
4
+ @author Sindre Sorhus
5
+ @license (MIT OR CC0-1.0)
6
+ */
7
+
8
+ /* ===================================
9
+ Math & Number Functions
10
+ =================================== */
11
+
12
+ /**
13
+ Negates a value (returns the negative).
14
+
15
+ @param {Number} --value - The value to negate.
16
+ @returns {Number} The negated value.
17
+ @example padding: --negate(1em);
18
+ */
19
+
20
+ @function --negate(--value) {
21
+ result: calc(-1 * var(--value));
22
+ }
23
+
24
+ /**
25
+ Linear interpolation between two values.
26
+
27
+ @param {Number} --from - Start value.
28
+ @param {Number} --to - End value.
29
+ @param {Number} --progress - Progress between 0 and 1.
30
+ @returns {Number} Interpolated value.
31
+ @example width: --lerp(100px, 200px, 0.5);
32
+ */
33
+
34
+ @function --lerp(--from, --to, --progress) {
35
+ result: calc(var(--from) + (var(--to) - var(--from)) * var(--progress));
36
+ }
37
+
38
+ /**
39
+ Maps a value from one range to another.
40
+
41
+ @param {Number} --value - Input value.
42
+ @param {Number} --in-min - Input range minimum.
43
+ @param {Number} --in-max - Input range maximum.
44
+ @param {Number} --out-min - Output range minimum.
45
+ @param {Number} --out-max - Output range maximum.
46
+ @returns {Number} Mapped value.
47
+ @example font-size: --map-range(50vw, 320px, 1920px, 14px, 24px);
48
+ */
49
+
50
+ @function --map-range(--value, --in-min, --in-max, --out-min, --out-max) {
51
+ --progress: clamp(0, calc((var(--value) - var(--in-min)) / (var(--in-max) - var(--in-min))), 1);
52
+ result: calc(var(--out-min) + (var(--out-max) - var(--out-min)) * var(--progress));
53
+ }
54
+
55
+ /**
56
+ Returns the ratio of two values. Supports values with different units, unlike regular division.
57
+
58
+ @param {CalcSum} --value - Input value.
59
+ @param {CalcSum} --to-value - Another input value.
60
+ @returns {Number} The ratio between two values.
61
+ @example scale: --ratio(16px, 1em);
62
+ */
63
+
64
+ @function --ratio(--value, --to-value) {
65
+ result: tan(atan2(var(--value), var(--to-value)));
66
+ }
67
+
68
+ /* ===================================
69
+ Color Functions
70
+ =================================== */
71
+
72
+ /**
73
+ Returns a semi-transparent version of any color.
74
+
75
+ @param {Color} --color - The base color.
76
+ @param {Number} --opacity - Opacity value (0-100% or 0-1).
77
+ @returns {Color} Color with opacity.
78
+ @example background: --opacity(blue, 50%);
79
+ */
80
+
81
+ @function --opacity(--color, --opacity) {
82
+ result: rgb(from var(--color) r g b / var(--opacity));
83
+ }
84
+
85
+ /**
86
+ Lightens a color by mixing with white.
87
+
88
+ Uses OKLab color space for perceptually uniform mixing.
89
+
90
+ @param {Color} --color - The base color.
91
+ @param {Number} --amount - Amount to lighten (0-100%).
92
+ @returns {Color} Lightened color.
93
+ @example background: --tint(blue, 20%);
94
+ */
95
+
96
+ @function --tint(--color, --amount: 10%) {
97
+ result: color-mix(in oklab, var(--color), white var(--amount));
98
+ }
99
+
100
+ /**
101
+ Darkens a color by mixing with black.
102
+
103
+ Uses OKLab color space for perceptually uniform mixing.
104
+
105
+ @param {Color} --color - The base color.
106
+ @param {Number} --amount - Amount to darken (0-100%).
107
+ @returns {Color} Darkened color.
108
+ @example background: --shade(blue, 20%);
109
+ */
110
+
111
+ @function --shade(--color, --amount: 10%) {
112
+ result: color-mix(in oklab, var(--color), black var(--amount));
113
+ }
114
+
115
+ /**
116
+ Adjusts color saturation.
117
+
118
+ Uses OKLCH color space for perceptually uniform chroma adjustment. Chroma is clamped to 0.4 for safe display.
119
+
120
+ @param {Color} --color - The base color.
121
+ @param {Number} --amount - Chroma multiplier.
122
+ @returns {Color} Adjusted color.
123
+ @example color: --saturate(red, 1.5);
124
+ */
125
+
126
+ @function --saturate(--color, --amount: 1.2) {
127
+ result: oklch(from var(--color) l clamp(0, calc(c * var(--amount)), 0.4) h);
128
+ }
129
+
130
+ /**
131
+ Adjusts color lightness.
132
+
133
+ Uses OKLCH color space for perceptually uniform lightness adjustment. Maintains chroma independently.
134
+
135
+ @param {Color} --color - The base color.
136
+ @param {Number} --amount - Lightness adjustment (-100% to 100%).
137
+ @returns {Color} Adjusted color.
138
+ @example background: --lighten(blue, 20%);
139
+ */
140
+
141
+ @function --lighten(--color, --amount: 10%) {
142
+ result: oklch(from var(--color) clamp(0, calc(l + var(--amount) / 100%), 1) c h);
143
+ }
144
+
145
+ /**
146
+ Darkens a color by reducing lightness.
147
+
148
+ Uses OKLCH color space for perceptually uniform lightness adjustment. Unlike `--shade()` which mixes with black, this directly reduces the lightness value.
149
+
150
+ @param {Color} --color - The base color.
151
+ @param {Number} --amount - Lightness reduction (0-100%).
152
+ @returns {Color} Darkened color.
153
+ @example background: --darken(blue, 20%);
154
+ */
155
+
156
+ @function --darken(--color, --amount: 10%) {
157
+ result: oklch(from var(--color) clamp(0, calc(l - var(--amount) / 100%), 1) c h);
158
+ }
159
+
160
+ /**
161
+ Rotates the hue of a color.
162
+
163
+ Uses OKLCH color space for perceptually uniform hue rotation.
164
+
165
+ @param {Color} --color - The base color.
166
+ @param {Angle} --degrees - Degrees to rotate hue.
167
+ @returns {Color} Color with rotated hue.
168
+ @example background: --rotate-hue(blue, 180deg);
169
+ */
170
+
171
+ @function --rotate-hue(--color, --degrees: 30deg) {
172
+ result: oklch(from var(--color) l c calc(h + var(--degrees)));
173
+ }
174
+
175
+ /**
176
+ Returns the complementary color.
177
+
178
+ Uses OKLCH color space for perceptually accurate complementary colors.
179
+
180
+ @param {Color} --color - The base color.
181
+ @returns {Color} Complementary color.
182
+ @example border-color: --complement(blue);
183
+ */
184
+
185
+ @function --complement(--color) {
186
+ result: oklch(from var(--color) l c calc(h + 180deg));
187
+ }
188
+
189
+ /**
190
+ Inverts a color.
191
+
192
+ @param {Color} --color - The color to invert.
193
+ @returns {Color} Inverted color.
194
+ @example background: --invert(white);
195
+ */
196
+
197
+ @function --invert(--color) {
198
+ result: rgb(from var(--color) calc(255 - r) calc(255 - g) calc(255 - b) / alpha);
199
+ }
200
+
201
+ /**
202
+ Converts a color to grayscale.
203
+
204
+ Uses OKLCH color space by setting chroma to 0.
205
+
206
+ @param {Color} --color - The color to convert.
207
+ @returns {Color} Grayscale color.
208
+ @example filter: --grayscale(var(--brand-color));
209
+ */
210
+
211
+ @function --grayscale(--color) {
212
+ result: oklch(from var(--color) l 0 h);
213
+ }
214
+
215
+ /*
216
+ Uses HWB color space trick: converts to grayscale in OKLCH, then uses HWB's blackness/whiteness values amplified by a large multiplier to create a binary black/white decision based on brightness. This provides excellent contrast decisions without needing numeric luminance extraction.
217
+ */
218
+
219
+ /**
220
+ Returns black or white text color for optimal contrast on a background.
221
+
222
+ @param {Color} --bg - Background color.
223
+ @returns {Color} Black or white for optimal readability.
224
+ @example color: --text-on(var(--bg-color));
225
+ */
226
+
227
+ @function --text-on(--bg) {
228
+ result: hwb(from oklch(from var(--bg) l 0 0) h calc((b - 50) * 999) calc((w - 50) * 999));
229
+ }
230
+
231
+ /**
232
+ Removes transparency from a color, making it fully opaque.
233
+
234
+ @param {Color} --color - Color with alpha channel.
235
+ @returns {Color} Fully opaque version of the color.
236
+ @example background: --opaque(var(--semi-transparent-bg));
237
+ */
238
+
239
+ @function --opaque(--color) {
240
+ result: rgb(from var(--color) r g b / 1);
241
+ }
242
+
243
+ /**
244
+ Mixes two colors in OKLab color space.
245
+
246
+ Uses perceptually uniform OKLab color space for natural-looking color mixing.
247
+
248
+ @param {Color} --color1 - First color.
249
+ @param {Color} --color2 - Second color.
250
+ @param {Number} --amount - Amount of second color to mix (0-100%).
251
+ @returns {Color} Mixed color.
252
+ @example background: --mix(red, blue, 30%);
253
+ */
254
+
255
+ @function --mix(--color1, --color2, --amount: 50%) {
256
+ result: color-mix(in oklab, var(--color1), var(--color2) var(--amount));
257
+ }
258
+
259
+ /**
260
+ Returns a triadic color harmony.
261
+
262
+ Triadic colors are evenly spaced around the color wheel (120° apart).
263
+
264
+ @param {Color} --color - Base color.
265
+ @param {Number} --index - Which triadic color (1 or 2).
266
+ @returns {Color} Triadic color.
267
+ @example color: --triadic(blue, 1);
268
+ */
269
+
270
+ @function --triadic(--color, --index: 1) {
271
+ result: oklch(from var(--color) l c calc(h + 120deg * var(--index)));
272
+ }
273
+
274
+ /**
275
+ Returns a tetradic (square) color harmony.
276
+
277
+ Tetradic colors are evenly spaced around the color wheel (90° apart).
278
+
279
+ @param {Color} --color - Base color.
280
+ @param {Number} --index - Which tetradic color (1, 2, or 3).
281
+ @returns {Color} Tetradic color.
282
+ @example color: --tetradic(blue, 2);
283
+ */
284
+
285
+ @function --tetradic(--color, --index: 1) {
286
+ result: oklch(from var(--color) l c calc(h + 90deg * var(--index)));
287
+ }
288
+
289
+ /**
290
+ Creates a semi-transparent black.
291
+
292
+ @param {Number} --opacity - Opacity value (0-100% or 0-1).
293
+ @returns {Color} Semi-transparent black.
294
+ @example box-shadow: 0 2px 4px --black(20%);
295
+ */
296
+
297
+ @function --black(--opacity: 50%) {
298
+ result: rgb(0 0 0 / var(--opacity));
299
+ }
300
+
301
+ /**
302
+ Creates a semi-transparent white.
303
+
304
+ @param {Number} --opacity - Opacity value (0-100% or 0-1).
305
+ @returns {Color} Semi-transparent white.
306
+ @example background: --white(90%);
307
+ */
308
+
309
+ @function --white(--opacity: 50%) {
310
+ result: rgb(255 255 255 / var(--opacity));
311
+ }
312
+
313
+ /* ===================================
314
+ Typography Functions
315
+ =================================== */
316
+
317
+ /**
318
+ Creates fluid typography that scales with viewport.
319
+
320
+ NOTE: This function is mathematically equivalent to `--responsive-value()` but optimized for typography. Use this for `font-size`, `--responsive-value()` for other properties.
321
+
322
+ @param {Length} --min - Minimum font size.
323
+ @param {Length} --max - Maximum font size.
324
+ @param {Length} --min-viewport - Minimum viewport width.
325
+ @param {Length} --max-viewport - Maximum viewport width.
326
+ @returns {Length} Fluid font size.
327
+ @example font-size: --fluid-type(16px, 24px, 320px, 1280px);
328
+ */
329
+
330
+ @function --fluid-type(--min, --max, --min-viewport: 320px, --max-viewport: 1280px) {
331
+ --slope: calc((var(--max) - var(--min)) / (var(--max-viewport) - var(--min-viewport)));
332
+ --intercept: calc(var(--min) - var(--slope) * var(--min-viewport));
333
+ result: clamp(var(--min), calc(var(--intercept) + var(--slope) * 100vw), var(--max));
334
+ }
335
+
336
+ /**
337
+ Creates a modular scale value.
338
+
339
+ @param {Number} --base - Base size.
340
+ @param {Number} --ratio - Scale ratio.
341
+ @param {Number} --step - Step in the scale.
342
+ @returns {Length} Scaled value.
343
+ @example font-size: --modular-scale(1rem, 1.25, 3);
344
+ */
345
+
346
+ @function --modular-scale(--base: 1rem, --ratio: 1.25, --step: 0) {
347
+ result: calc(var(--base) * pow(var(--ratio), var(--step)));
348
+ }
349
+
350
+ /**
351
+ Calculates line height as a length value based on font size.
352
+
353
+ Returns a length (e.g., 24px) rather than a unitless ratio. Use this when you need an absolute line height value.
354
+
355
+ @param {Length} --font-size - The font size.
356
+ @param {Number} --multiplier - Line height multiplier.
357
+ @returns {Length} Line height as a length.
358
+ @example line-height: --line-height-length(16px, 1.6);
359
+ */
360
+
361
+ @function --line-height-length(--font-size, --multiplier: 1.5) {
362
+ result: calc(var(--font-size) * var(--multiplier));
363
+ }
364
+
365
+ /**
366
+ Calculates line height as a unitless ratio.
367
+
368
+ Returns a number (e.g., 1.5) which is recommended for better inheritance in CSS.
369
+
370
+ @param {Length} --line-height - The desired line height as a length.
371
+ @param {Length} --font-size - The font size.
372
+ @returns {Number} Unitless line height ratio.
373
+ @example line-height: --line-height-ratio(24px, 16px);
374
+ */
375
+
376
+ @function --line-height-ratio(--line-height, --font-size) {
377
+ result: calc(var(--line-height) / var(--font-size));
378
+ }
379
+
380
+ /**
381
+ Creates unitless line height from font size (recommended for better inheritance).
382
+
383
+ NOTE: Only works correctly with pixel font sizes. For rem/em values, use `--line-height-length()` or `--line-height-ratio()` instead.
384
+
385
+ @param {Length} --font-size - Font size in pixels.
386
+ @param {Number} --multiplier - Line height multiplier.
387
+ @returns {Number} Unitless line height.
388
+ @example line-height: --line-height-unitless(16px, 1.5);
389
+ */
390
+
391
+ @function --line-height-unitless(--font-size: 16px, --multiplier: 1.5) {
392
+ result: calc(var(--font-size) * var(--multiplier) / 1px);
393
+ }
394
+
395
+ /* ===================================
396
+ Layout Functions
397
+ =================================== */
398
+
399
+ /**
400
+ Creates responsive sidebar layout columns.
401
+
402
+ @param {Length} --sidebar-width - Width of sidebar.
403
+ @param {Length} --content-min - Minimum width of content area.
404
+ @returns {Length} Grid template columns value.
405
+ @example grid-template-columns: --sidebar-layout(250px, 20ch);
406
+ */
407
+
408
+ @function --sidebar-layout(--sidebar-width: 20ch, --content-min: 20ch) {
409
+ result: minmax(var(--sidebar-width), 1fr) minmax(var(--content-min), 3fr);
410
+ }
411
+
412
+ /**
413
+ Conditional border radius that removes at viewport edges.
414
+
415
+ @param {Length} --radius - Border radius value.
416
+ @param {Length} --edge-dist - Distance from viewport edge.
417
+ @returns {Length} Computed border radius.
418
+ @example border-radius: --conditional-radius(1rem, 8px);
419
+ */
420
+
421
+ @function --conditional-radius(--radius, --edge-dist: 4px) {
422
+ /* Multiply by large number to amplify small differences, creating binary 0/radius effect */
423
+ result: clamp(0px, ((100vw - var(--edge-dist)) - 100%) * 1e5, var(--radius));
424
+ }
425
+
426
+ /**
427
+ Creates a responsive value that scales between two sizes.
428
+
429
+ NOTE: This function is mathematically equivalent to `--fluid-type()` but uses a simpler lerp-based approach. Use this for spacing/sizing, `--fluid-type()` for typography.
430
+
431
+ @param {Length} --small - Minimum value.
432
+ @param {Length} --large - Maximum value.
433
+ @param {Length} --viewport-min - Minimum viewport width.
434
+ @param {Length} --viewport-max - Maximum viewport width.
435
+ @returns {Length} Responsive value.
436
+ @example padding: --responsive-value(1rem, 2rem, 320px, 1200px);
437
+ */
438
+
439
+ @function --responsive-value(--small, --large, --viewport-min: 320px, --viewport-max: 1200px) {
440
+ --progress: calc((100vw - var(--viewport-min)) / (var(--viewport-max) - var(--viewport-min)));
441
+ --clamped-progress: clamp(0, var(--progress), 1);
442
+ result: calc(var(--small) + (var(--large) - var(--small)) * var(--clamped-progress));
443
+ }
444
+
445
+ /**
446
+ Calculates height from aspect ratio and maximum constraints.
447
+
448
+ @param {Number} --ratio - Aspect ratio (e.g., 16/9).
449
+ @param {Length} --max-width - Maximum width.
450
+ @param {Length} --max-height - Maximum height.
451
+ @returns {Length} Computed height.
452
+ @example height: --aspect-height(16/9, 100vw, 100vh);
453
+ */
454
+
455
+ @function --aspect-height(--ratio: 1, --max-width: 100%, --max-height: 100%) {
456
+ --computed-height: calc(var(--max-width) / var(--ratio));
457
+ result: min(var(--computed-height), var(--max-height));
458
+ }
459
+
460
+ /**
461
+ Calculates width from aspect ratio and maximum constraints.
462
+
463
+ @param {Number} --ratio - Aspect ratio (e.g., 16/9).
464
+ @param {Length} --max-height - Maximum height.
465
+ @param {Length} --max-width - Maximum width.
466
+ @returns {Length} Computed width.
467
+ @example width: --aspect-width(16/9, 100vh, 100vw);
468
+ */
469
+
470
+ @function --aspect-width(--ratio: 1, --max-height: 100%, --max-width: 100%) {
471
+ --computed-width: calc(var(--max-height) * var(--ratio));
472
+ result: min(var(--computed-width), var(--max-width));
473
+ }
474
+
475
+ /* ===================================
476
+ Spacing Functions
477
+ =================================== */
478
+
479
+ /**
480
+ Creates consistent spacing based on a scale.
481
+
482
+ Recommended range: 0-10. Higher values create exponentially larger spacing.
483
+
484
+ @param {Number} --level - Spacing level (0-10).
485
+ @param {Length} --base - Base spacing unit.
486
+ @returns {Length} Computed spacing.
487
+ @example margin: --spacing(3);
488
+ */
489
+
490
+ @function --spacing(--level: 1, --base: 0.25rem) {
491
+ result: calc(var(--base) * pow(2, var(--level)));
492
+ }
493
+
494
+ /**
495
+ Creates inset spacing for containers.
496
+
497
+ @param {Length} --padding - Base padding.
498
+ @param {Length} --max-width - Maximum container width.
499
+ @returns {Length} Responsive padding.
500
+ @example padding: --container-padding(2rem, 1200px);
501
+ */
502
+
503
+ @function --container-padding(--padding: 1rem, --max-width: 1200px) {
504
+ --available: calc(100vw - var(--max-width));
505
+ --side-space: max(var(--padding), calc(var(--available) / 2));
506
+ result: var(--side-space);
507
+ }
508
+
509
+ /* ===================================
510
+ Animation Functions
511
+ =================================== */
512
+
513
+ /**
514
+ Creates a simple easing curve value.
515
+
516
+ @param {Number} --progress - Animation progress (0-1).
517
+ @returns {Number} Eased value.
518
+ @example transform: translateY(--ease-out(var(--progress)));
519
+ */
520
+
521
+ @function --ease-out(--progress) {
522
+ --inverse: calc(1 - var(--progress));
523
+ result: calc(1 - var(--inverse) * var(--inverse));
524
+ }
525
+
526
+ /**
527
+ Creates elastic easing.
528
+
529
+ @param {Number} --progress - Animation progress (0-1).
530
+ @param {Number} --amplitude - Amplitude of elasticity.
531
+ @returns {Number} Eased value.
532
+ @example transform: scale(--elastic-ease(var(--progress), 1.2));
533
+ */
534
+
535
+ @function --elastic-ease(--progress, --amplitude: 1) {
536
+ --p: calc(var(--progress) * 3.14159);
537
+ result: calc(var(--amplitude) * sin(var(--p) * 10) * exp(calc(-5 * var(--progress))));
538
+ }
539
+
540
+ /* ===================================
541
+ Utility Functions
542
+ =================================== */
543
+
544
+ /**
545
+ Converts pixels to rem.
546
+
547
+ @param {Length} --pixels - Pixel value.
548
+ @param {Length} --base - Base font size.
549
+ @returns {Length} Rem value.
550
+ @example font-size: --px-to-rem(24px);
551
+ */
552
+
553
+ @function --px-to-rem(--pixels, --base: 16px) {
554
+ result: calc(var(--pixels) / var(--base) * 1rem);
555
+ }
556
+
557
+ /**
558
+ Converts rem to pixels.
559
+
560
+ @param {Length} --rems - Rem value.
561
+ @param {Length} --base - Base font size.
562
+ @returns {Length} Pixel value.
563
+ @example width: --rem-to-px(2rem);
564
+ */
565
+
566
+ @function --rem-to-px(--rems, --base: 16px) {
567
+ result: calc(var(--rems) / 1rem * var(--base));
568
+ }
569
+
570
+ /* ===================================
571
+ Grid Functions
572
+ =================================== */
573
+
574
+ /**
575
+ Creates responsive grid columns.
576
+
577
+ @param {Number} --min-width - Minimum column width.
578
+ @param {Number} --max-cols - Maximum number of columns.
579
+ @returns {Grid} Grid template columns value.
580
+ @example grid-template-columns: --auto-grid(250px, 4);
581
+ */
582
+
583
+ @function --auto-grid(--min-width: 250px, --max-cols: 4) {
584
+ result: repeat(
585
+ auto-fit,
586
+ minmax(max(var(--min-width), calc(100% / var(--max-cols))), 1fr)
587
+ );
588
+ }
589
+
590
+ /**
591
+ Creates a CSS grid span value.
592
+
593
+ Ensures the span is an integer value.
594
+
595
+ @param {Number} --columns - Number of columns to span.
596
+ @param {Number} --total - Total columns in grid.
597
+ @returns {Span} Grid column span (rounded to integer).
598
+ @example grid-column: --grid-span(3, 12);
599
+ */
600
+
601
+ @function --grid-span(--columns: 1, --total: 12) {
602
+ result: span round(clamp(1, var(--columns), var(--total)));
603
+ }
604
+
605
+ /* ===================================
606
+ Filter Functions
607
+ =================================== */
608
+
609
+ /**
610
+ Creates a smooth shadow.
611
+
612
+ Generates three shadow layers. The spread-factor controls how distributed the shadows are.
613
+
614
+ @param {Color} --color - Shadow color.
615
+ @param {Length} --size - Shadow size.
616
+ @param {Number} --spread-factor - Controls shadow distribution (higher = tighter shadows).
617
+ @returns {Shadow} Layered box shadow.
618
+ @example box-shadow: --smooth-shadow(black, 20px, 3);
619
+ */
620
+
621
+ @function --smooth-shadow(--color: rgb(0 0 0 / 0.2), --size: 12px, --spread-factor: 3) {
622
+ --step: calc(var(--size) / var(--spread-factor));
623
+ result:
624
+ 0 var(--step) calc(var(--step) * 2) rgb(from var(--color) r g b / 0.25),
625
+ 0 calc(var(--step) * 2) calc(var(--step) * 3) rgb(from var(--color) r g b / 0.18),
626
+ 0 calc(var(--step) * 3) calc(var(--step) * 4) rgb(from var(--color) r g b / 0.12);
627
+ }
628
+
629
+ /**
630
+ Creates a glow effect.
631
+
632
+ @param {Color} --color - Glow color.
633
+ @param {Length} --size - Glow size.
634
+ @param {Number} --intensity - Glow intensity (0-1).
635
+ @returns {Shadow} Glow shadow.
636
+ @example box-shadow: --glow(cyan, 10px, 0.5);
637
+ */
638
+
639
+ @function --glow(--color: white, --size: 10px, --intensity: 0.5) {
640
+ result: 0 0 var(--size) rgb(from var(--color) r g b / var(--intensity));
641
+ }
642
+
643
+ /* ===================================
644
+ Theme Functions
645
+ =================================== */
646
+
647
+ /**
648
+ Theme-aware value switcher for light/dark mode.
649
+
650
+ Uses CSS `if()` with color-scheme query. Requires `color-scheme: light dark` on `:root`.
651
+ Works with ANY value type (colors, lengths, etc.), not just colors.
652
+
653
+ > [!NOTE]
654
+ > CSS has a native [`light-dark()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark) function for colors. The custom `--light-dark()` function is more powerful as it works with any value type, not just colors.
655
+
656
+ @param {Any} --light - Value for light mode.
657
+ @param {Any} --dark - Value for dark mode.
658
+ @returns {Any} Theme-appropriate value.
659
+ @example color: --light-dark(black, white);
660
+ @example background-image: --light-dark(url(light.svg), url(dark.svg));
661
+ @example padding: --light-dark(0.75rem, 1rem);
662
+ */
663
+
664
+ @function --light-dark(--light, --dark) {
665
+ result: if(color-scheme(dark): var(--dark); else: var(--light));
666
+ }
667
+
668
+ /**
669
+ Creates a theme-aware color with automatic adjustment.
670
+
671
+ Uses CSS `if()` with color-scheme query. Requires `color-scheme: light dark` on `:root`.
672
+
673
+ In light mode, mixes the base color with white (default 85% white).
674
+ In dark mode, mixes the base color with black (default 15% black).
675
+
676
+ @param {Color} --base - Base color.
677
+ @param {Number} --light-mix - Percentage of white to mix in light mode.
678
+ @param {Number} --dark-mix - Percentage of black to mix in dark mode.
679
+ @returns {Color} Theme-adjusted color.
680
+ @example background: --theme-color(blue, 80%, 20%);
681
+ */
682
+
683
+ @function --theme-color(--base, --light-mix: 85%, --dark-mix: 15%) {
684
+ --light-result: color-mix(in oklab, white var(--light-mix), var(--base));
685
+ --dark-result: color-mix(in oklab, black var(--dark-mix), var(--base));
686
+ result: if(color-scheme(dark): var(--dark-result); else: var(--light-result));
687
+ }
688
+
689
+ @layer base {
690
+ .l-visually-hidden {
691
+ /* Visually hide this, but keep it accessible to keyboard,
692
+ screen reader and other assistive technologies.
693
+
694
+ Also know as CSS helper: `.visually-hidden` / `.sr-only`
695
+
696
+ References:
697
+ - https://www.tpgi.com/the-anatomy-of-visually-hidden/
698
+ - https://youtu.be/ob_M_qXeDVE?t=677
699
+ */
700
+ position: absolute;
701
+ width: 1px;
702
+ height: 1px;
703
+ padding: 0;
704
+ margin: -1px;
705
+ overflow: hidden;
706
+ clip: rect(0, 0, 0, 0); /* for IE only */
707
+ white-space: nowrap;
708
+ border: 0;
709
+ }
710
+ }
711
+
712
+ /* https://github.com/tailwindlabs/tailwindcss/blob/main/packages/tailwindcss/theme.css */
713
+
714
+ @theme static {
715
+ /*
716
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
717
+ 🅲🅾🅻🅾🆁: text
718
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
719
+ */
720
+
721
+ /* Main body text, headings, and high-emphasis content. Use as the default text color throughout the UI. */
722
+ --l-color-text-primary: light-dark(var(--color-gray-700), var(--color-gray-200));
723
+
724
+ /* Supporting text, descriptions, captions, and medium-emphasis content like helper text beneath form fields. */
725
+ --l-color-text-secondary: light-dark(var(--color-gray-600), var(--color-gray-400));
726
+
727
+ /* Placeholder text, disabled labels, and low-emphasis content like timestamps or metadata. */
728
+ --l-color-text-tertiary: light-dark(var(--color-gray-500), var(--color-gray-500));
729
+
730
+ /* Neutral semantic text for default-state badges, tags, and status labels with no specific severity. */
731
+ --l-color-text-neutral: light-dark(var(--color-gray-700), var(--color-gray-300));
732
+
733
+ /* Informational semantic text for badges, alerts, banners, and status indicators conveying neutral information. */
734
+ --l-color-text-info: light-dark(var(--color-blue-700), var(--color-blue-300));
735
+
736
+ /* Warning semantic text for badges, alerts, and status indicators conveying caution or non-blocking issues. */
737
+ --l-color-text-warning: light-dark(var(--color-yellow-700), var(--color-yellow-300));
738
+
739
+ /* Danger/error semantic text for badges, alerts, validation messages, and destructive action labels. */
740
+ --l-color-text-danger: light-dark(var(--color-red-700), var(--color-red-300));
741
+
742
+ /* Success semantic text for badges, alerts, and status indicators conveying completion or positive outcomes. */
743
+ --l-color-text-success: light-dark(var(--color-green-700), var(--color-green-300));
744
+
745
+ /*
746
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
747
+ 🅲🅾🅻🅾🆁: surface
748
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
749
+ */
750
+
751
+ /* Default page-level background. Use on <body>, main content areas, and cards at the base layer. */
752
+ --l-color-surface: light-dark(white, var(--color-gray-900));
753
+
754
+ /* Elevated overlay background for modals, dialogs, drawers, popovers, and any surface that floats above the page with a backdrop. Slightly lighter than --l-color-surface in dark mode to create visual separation from the page beneath. */
755
+ --l-color-surface-overlay: light-dark(white, var(--color-gray-800));
756
+
757
+ /* Semi-transparent backdrop behind modals, dialogs, drawers, and any overlay that dims the page content. Darker in dark mode for better contrast against dark surfaces. */
758
+ --l-backdrop: light-dark(oklch(46% 0.01 260 / 33%), oklch(15% 0.01 260 / 60%));
759
+
760
+ /* Default border for form controls, secondary buttons, inputs, and selects. */
761
+ --l-color-border: light-dark(var(--color-gray-400), var(--color-gray-800));
762
+
763
+ /* Subtle divider line for separating content sections, list items, and card groups. Lighter than --l-color-border to avoid visual competition with interactive element borders. */
764
+ --l-color-divider: light-dark(var(--color-gray-200), var(--color-gray-700));
765
+
766
+ /* Subtle border or ring for interactive elements like close buttons, toggles, and icon buttons on hover. Provides low-contrast visual feedback without competing with primary content. */
767
+ --l-color-border-interactive: light-dark(var(--color-gray-300), var(--color-gray-600));
768
+
769
+ /* Border color for disabled form controls, buttons, and interactive elements. Faded to signal non-interactivity. */
770
+ --l-color-border-disabled: light-dark(var(--color-gray-300), var(--color-gray-700));
771
+
772
+ /* Text color for disabled labels, values, and icons in form controls, buttons, and interactive elements. */
773
+ --l-color-text-disabled: light-dark(var(--color-gray-400), var(--color-gray-500));
774
+
775
+ /* Background color for disabled form controls, buttons, and interactive elements. Subtle tint to reinforce non-interactivity. */
776
+ --l-color-bg-disabled: light-dark(var(--color-gray-100), var(--color-gray-800));
777
+
778
+ /* Focus ring color for :focus-visible outlines on interactive elements like buttons, inputs, and links. */
779
+ --l-focus-ring: #d9461f;
780
+
781
+ /* Translucent background tint for hovered rows in lists, menus, trees, tables, and similar roving collections. Alpha-based so underlying indent guides, borders, or zebra stripes stay visible. */
782
+ --l-color-bg-state-hover: light-dark(rgb(0 0 0 / 5%), rgb(255 255 255 / 6%));
783
+
784
+ /* Translucent background tint for the selected (persistent) row in lists, trees, menus, listboxes, and tables. Alpha-based so underlying indent guides, borders, or zebra stripes stay visible. Semantically paired with `aria-selected="true"` / `:state(selected)`. */
785
+ --l-color-bg-state-selected: light-dark(rgb(0 0 0 / 7%), rgb(255 255 255 / 9%));
786
+
787
+ /*
788
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
789
+ 🅲🅾🅻🅾🆁: fill
790
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
791
+ */
792
+
793
+ /* Primary brand fill for CTA buttons, active toggles, and primary action backgrounds. */
794
+ --l-color-bg-fill-brand: light-dark(var(--color-gray-900), var(--color-gray-50));
795
+
796
+ /* Hover state of brand-filled elements like primary buttons and active toggles. */
797
+ --l-color-bg-fill-brand-hover: light-dark(var(--color-gray-800), var(--color-gray-200));
798
+
799
+ /* Active/pressed state of brand-filled elements like primary buttons during click or tap. */
800
+ --l-color-bg-fill-brand-active: light-dark(var(--color-gray-700), var(--color-gray-300));
801
+
802
+ /* Secondary control fill for buttons, toggles, and non-primary interactive surfaces. */
803
+ --l-color-bg-fill-secondary: light-dark(var(--color-white), var(--color-gray-700));
804
+
805
+ /* Text on brand-filled surfaces like primary buttons. Maximum contrast against --l-color-bg-fill-brand. */
806
+ --l-color-text-on-fill-brand: light-dark(white, var(--color-gray-900));
807
+
808
+ /*
809
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
810
+ 🅲🅾🅻🅾🆁: fill (soft / subtle / strong)
811
+
812
+ Three-tier status fill scale ordered by visual weight:
813
+ soft → palest tint, barely colored. Use for large surface areas
814
+ like toast backgrounds, alert containers, and callout boxes
815
+ where color should not dominate.
816
+ subtle → noticeable tinted background with matching foreground.
817
+ Use for badges, tags, selected states, and secondary
818
+ highlights where the color needs to be clearly visible.
819
+ strong → full-intensity solid background with contrast foreground.
820
+ Use for solid badges, high-emphasis status indicators,
821
+ and primary status pills.
822
+
823
+ Future tier:
824
+ plain → no background, text color only.
825
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
826
+ */
827
+
828
+ /* Soft: palest tint for toast backgrounds, alert containers, and callout boxes. */
829
+ --l-color-bg-fill-neutral-soft: light-dark(var(--color-gray-50), var(--color-gray-800));
830
+ --l-color-bg-fill-info-soft: light-dark(var(--color-blue-50), var(--color-blue-950));
831
+ --l-color-bg-fill-warning-soft: light-dark(var(--color-yellow-50), var(--color-yellow-950));
832
+ --l-color-bg-fill-danger-soft: light-dark(var(--color-red-50), var(--color-red-950));
833
+ --l-color-bg-fill-success-soft: light-dark(var(--color-green-50), var(--color-green-950));
834
+
835
+ /* Subtle: tinted background for badges, tags, selected states, and secondary highlights. */
836
+ --l-color-bg-fill-neutral-subtle: light-dark(var(--color-gray-100), var(--color-gray-700));
837
+ --l-color-bg-fill-info-subtle: light-dark(var(--color-blue-100), var(--color-blue-900));
838
+ --l-color-bg-fill-warning-subtle: light-dark(var(--color-yellow-100), var(--color-yellow-900));
839
+ --l-color-bg-fill-danger-subtle: light-dark(var(--color-red-100), var(--color-red-900));
840
+ --l-color-bg-fill-success-subtle: light-dark(var(--color-green-100), var(--color-green-900));
841
+
842
+ /* Strong: solid background for solid badges and high-emphasis status indicators. Pair with --l-color-surface for foreground. */
843
+ --l-color-bg-fill-neutral-strong: light-dark(var(--color-gray-800), var(--color-gray-200));
844
+ --l-color-bg-fill-info-strong: light-dark(var(--color-blue-600), var(--color-blue-500));
845
+ --l-color-bg-fill-warning-strong: light-dark(var(--color-yellow-600), var(--color-yellow-500));
846
+ --l-color-bg-fill-danger-strong: light-dark(var(--color-red-600), var(--color-red-500));
847
+ --l-color-bg-fill-success-strong: light-dark(var(--color-green-600), var(--color-green-500));
848
+
849
+ /*
850
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
851
+ 🆂🅸🆉🅴
852
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
853
+ */
854
+
855
+ /* Standard interactive control height for extra-small elements like compact buttons, tags, and inline controls. */
856
+ --l-size-control-xs: 1.5rem;
857
+
858
+ /* Standard interactive control height for small elements like secondary buttons, small selects, and tight-layout controls. */
859
+ --l-size-control-sm: 1.75rem;
860
+
861
+ /* Standard interactive control height for medium (default) elements like buttons, inputs, selects, and form controls. */
862
+ --l-size-control-md: 2rem;
863
+
864
+ /* Standard interactive control height for large elements like prominent buttons, inputs in spacious layouts, and hero CTAs. */
865
+ --l-size-control-lg: 2.25rem;
866
+
867
+ /* Standard interactive control height for extra-large elements like oversized buttons, landing page CTAs, and touch-optimized controls. */
868
+ --l-size-control-xl: 2.5rem;
869
+ }
870
+
871
+ @theme inline {
872
+ /* Fully round border-radius for pill shapes, avatars, and circular elements. */
873
+ --radius-full: calc(infinity * 1px);
874
+
875
+ /* Tailwind utility aliases for text color tokens — use via class="text-color-primary" etc. */
876
+ --text-color-primary: var(--l-color-text-primary);
877
+ --text-color-secondary: var(--l-color-text-secondary);
878
+ --text-color-tertiary: var(--l-color-text-tertiary);
879
+
880
+ --text-color-neutral: var(--l-color-text-neutral);
881
+ --text-color-info: var(--l-color-text-info);
882
+ --text-color-warning: var(--l-color-text-warning);
883
+ --text-color-danger: var(--l-color-text-danger);
884
+ --text-color-success: var(--l-color-text-success);
885
+ }