@codenhub/styles 0.8.0 → 0.9.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.
- package/README.es.md +9 -9
- package/README.md +8 -8
- package/README.pt-BR.md +9 -9
- package/dist/aesthetics/chunky-tile.css +1 -1
- package/dist/aesthetics/cyber.css +1 -1
- package/dist/aesthetics/glass.css +1 -1
- package/dist/aesthetics/index.css +1 -1
- package/dist/aesthetics/neobrutalism.css +1 -1
- package/dist/aesthetics/pixel.css +1 -1
- package/dist/aesthetics/sketch.css +1 -1
- package/dist/cli.js +231 -62
- package/dist/components.css +49 -1
- package/dist/index.css +49 -1
- package/dist/native.css +49 -1
- package/dist/purge/classes.json +1 -0
- package/dist/purge/index.css +50 -0
- package/dist/theme.css +1 -1
- package/docs/changelog/0.8.0.md +1 -1
- package/docs/changelog/0.9.0.md +40 -0
- package/docs/changelog/index.md +1 -0
- package/docs/es/index.md +2 -2
- package/docs/es/integrating/tailwind.md +2 -1
- package/docs/es/integrating/without-a-bundler.md +60 -31
- package/docs/es/setup.md +4 -3
- package/docs/es/usage/aesthetics.md +2 -2
- package/docs/es/usage/content-and-layout.md +3 -1
- package/docs/es/usage/customizing.md +30 -16
- package/docs/es/usage/forms.md +2 -2
- package/docs/es/usage/index.md +2 -2
- package/docs/es/usage/solo.md +2 -2
- package/docs/es/usage/theming.md +2 -2
- package/docs/es/usage/tooltips.md +2 -2
- package/docs/index.md +1 -1
- package/docs/integrating/tailwind.md +1 -0
- package/docs/integrating/without-a-bundler.md +59 -30
- package/docs/pt-BR/index.md +2 -2
- package/docs/pt-BR/integrating/tailwind.md +2 -1
- package/docs/pt-BR/integrating/without-a-bundler.md +60 -31
- package/docs/pt-BR/setup.md +4 -3
- package/docs/pt-BR/usage/aesthetics.md +2 -2
- package/docs/pt-BR/usage/content-and-layout.md +3 -1
- package/docs/pt-BR/usage/customizing.md +30 -16
- package/docs/pt-BR/usage/forms.md +2 -2
- package/docs/pt-BR/usage/index.md +2 -2
- package/docs/pt-BR/usage/solo.md +2 -2
- package/docs/pt-BR/usage/theming.md +2 -2
- package/docs/pt-BR/usage/tooltips.md +2 -2
- package/docs/setup.md +3 -2
- package/docs/usage/aesthetics.md +1 -1
- package/docs/usage/content-and-layout.md +2 -0
- package/docs/usage/customizing.md +29 -15
- package/docs/usage/forms.md +1 -1
- package/docs/usage/index.md +1 -1
- package/docs/usage/solo.md +1 -1
- package/docs/usage/theming.md +1 -1
- package/docs/usage/tooltips.md +1 -1
- package/llms-full.txt +145 -61
- package/llms.txt +3 -2
- package/package.json +12 -10
- package/tw/aesthetics/chunky-tile.css +4 -1
- package/tw/aesthetics/cyber.css +4 -1
- package/tw/aesthetics/glass.css +5 -0
- package/tw/aesthetics/neobrutalism.css +4 -1
- package/tw/aesthetics/pixel.css +3 -0
- package/tw/aesthetics/sketch.css +18 -0
- package/tw/box.css +21 -15
- package/tw/components/button.rules.css +1 -1
- package/tw/components/feedback.rules.css +22 -3
- package/tw/components/form.rules.css +65 -35
- package/tw/components/surface.rules.css +8 -5
- package/tw/components/tooltip.rules.css +39 -34
- package/tw/elevation.css +8 -8
- package/tw/native.css +4 -1
- package/tw/theme.css +1 -1
- package/tw/utilities/content.css +74 -54
- package/tw/utilities/layout.css +7 -5
|
@@ -194,6 +194,9 @@
|
|
|
194
194
|
--_tile-bar: color-mix(in oklab, var(--_solo-ink) 72%, rgb(0 0 0));
|
|
195
195
|
--_solo-depth: calc(var(--_tile-lift) * var(--ui-elevation, 1));
|
|
196
196
|
|
|
197
|
+
/* Printed as drawn; see `.glass-solo`. */
|
|
198
|
+
print-color-adjust: exact;
|
|
199
|
+
|
|
197
200
|
border: 2px solid var(--_solo-edge);
|
|
198
201
|
border-radius: var(--tile-radius, 0.75rem);
|
|
199
202
|
box-shadow:
|
|
@@ -282,7 +285,7 @@
|
|
|
282
285
|
input[type="button"],
|
|
283
286
|
input[type="submit"],
|
|
284
287
|
input[type="reset"]
|
|
285
|
-
):active:not(:disabled, [aria-disabled="true"]) {
|
|
288
|
+
):active:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]) {
|
|
286
289
|
box-shadow:
|
|
287
290
|
0 0 0 0 var(--_tile-bar),
|
|
288
291
|
inset 0 0 0 100vmax var(--_solo-fill);
|
package/tw/aesthetics/cyber.css
CHANGED
|
@@ -179,6 +179,9 @@
|
|
|
179
179
|
);
|
|
180
180
|
--_solo-edge: color-mix(in oklab, var(--_solo-ink) var(--ui-border, 100%), var(--_solo-fill));
|
|
181
181
|
|
|
182
|
+
/* Printed as drawn; see `.glass-solo`. */
|
|
183
|
+
print-color-adjust: exact;
|
|
184
|
+
|
|
182
185
|
border: 1px solid var(--_solo-edge);
|
|
183
186
|
/* The surface shape: the element this exists for is usually a pane. An action
|
|
184
187
|
takes the control shape below. */
|
|
@@ -275,6 +278,6 @@
|
|
|
275
278
|
input[type="button"],
|
|
276
279
|
input[type="submit"],
|
|
277
280
|
input[type="reset"]
|
|
278
|
-
):active:not(:disabled, [aria-disabled="true"]) {
|
|
281
|
+
):active:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]) {
|
|
279
282
|
scale: 0.97;
|
|
280
283
|
}
|
package/tw/aesthetics/glass.css
CHANGED
|
@@ -445,6 +445,11 @@
|
|
|
445
445
|
does, rather than to the fill. */
|
|
446
446
|
--_solo-edge: color-mix(in oklab, var(--_solo-ink) var(--ui-border, 100%), transparent);
|
|
447
447
|
|
|
448
|
+
/* Printed as drawn, as `box` is: a browser leaves backgrounds off paper
|
|
449
|
+
and greys a contrast label, so a solid element printed its label on
|
|
450
|
+
no plate. Inherited, so what it holds keeps its paint too. */
|
|
451
|
+
print-color-adjust: exact;
|
|
452
|
+
|
|
448
453
|
background-color: color-mix(in oklab, var(--_solo-color) var(--_solo-capped), var(--_solo-ground));
|
|
449
454
|
border: 1px solid var(--_solo-edge);
|
|
450
455
|
/* The surface corner: the element this exists for is a pane. */
|
|
@@ -187,6 +187,9 @@
|
|
|
187
187
|
and `.floating` doubles it, and the press travels the same distance. */
|
|
188
188
|
--_solo-depth: calc(var(--_neo-offset) * var(--ui-elevation, 1));
|
|
189
189
|
|
|
190
|
+
/* Printed as drawn; see `.glass-solo`. */
|
|
191
|
+
print-color-adjust: exact;
|
|
192
|
+
|
|
190
193
|
border: 2px solid var(--_solo-edge);
|
|
191
194
|
border-radius: 0;
|
|
192
195
|
box-shadow:
|
|
@@ -260,7 +263,7 @@
|
|
|
260
263
|
input[type="button"],
|
|
261
264
|
input[type="submit"],
|
|
262
265
|
input[type="reset"]
|
|
263
|
-
):active:not(:disabled, [aria-disabled="true"]) {
|
|
266
|
+
):active:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]) {
|
|
264
267
|
box-shadow:
|
|
265
268
|
0 0 0 0 var(--_solo-ink),
|
|
266
269
|
inset 0 0 0 100vmax var(--_solo-fill);
|
package/tw/aesthetics/pixel.css
CHANGED
|
@@ -182,6 +182,9 @@
|
|
|
182
182
|
|
|
183
183
|
/* The clip removes a border at the straight sides, so the ring draws the
|
|
184
184
|
edge and the element's own border goes. */
|
|
185
|
+
/* Printed as drawn; see `.glass-solo`. */
|
|
186
|
+
print-color-adjust: exact;
|
|
187
|
+
|
|
185
188
|
border: 0;
|
|
186
189
|
border-radius: 0;
|
|
187
190
|
box-shadow:
|
package/tw/aesthetics/sketch.css
CHANGED
|
@@ -159,6 +159,14 @@
|
|
|
159
159
|
with the token, so a position never reads a value inherited from an
|
|
160
160
|
ancestor's. */
|
|
161
161
|
&:is(.btn, .ipt, .textarea, .select, .input-group, .pre, .tooltip-bubble) {
|
|
162
|
+
/* The first position draws the region's own outline, declared here too
|
|
163
|
+
so a knob set between the region and the element reaches it. */
|
|
164
|
+
&:nth-child(4n + 1) {
|
|
165
|
+
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius, 255px 15px 225px 15px / 15px 225px 15px 255px);
|
|
166
|
+
--_sketch-r: var(--_sketch-rounded) var(--sketch-radius-rounded, 26px 10px 24px 11px / 12px 23px 11px 20px);
|
|
167
|
+
--ui-radius: var(--_sketch-pass-radius, var(--_sketch-r, var(--_sketch-p)));
|
|
168
|
+
}
|
|
169
|
+
|
|
162
170
|
&:nth-child(4n + 2) {
|
|
163
171
|
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius, 18px 240px 15px 255px / 240px 15px 255px 18px);
|
|
164
172
|
--_sketch-r: var(--_sketch-rounded) var(--sketch-radius-rounded, 11px 25px 12px 24px / 23px 11px 22px 12px);
|
|
@@ -205,6 +213,13 @@
|
|
|
205
213
|
}
|
|
206
214
|
|
|
207
215
|
&:is(.card, .panel, .alert, .data-table) {
|
|
216
|
+
&:nth-child(4n + 1) {
|
|
217
|
+
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius-surface, 80px 4px 75px 5px / 3px 70px 4px 80px);
|
|
218
|
+
--_sketch-r: var(--_sketch-rounded)
|
|
219
|
+
var(--sketch-radius-surface-rounded, 38px 16px 36px 17px / 16px 34px 17px 32px);
|
|
220
|
+
--ui-radius-surface: var(--_sketch-pass-radius-surface, var(--_sketch-r, var(--_sketch-p)));
|
|
221
|
+
}
|
|
222
|
+
|
|
208
223
|
&:nth-child(4n + 2) {
|
|
209
224
|
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius-surface, 4px 75px 5px 80px / 75px 3px 80px 4px);
|
|
210
225
|
--_sketch-r: var(--_sketch-rounded)
|
|
@@ -335,6 +350,9 @@
|
|
|
335
350
|
--_solo-edge: color-mix(in oklab, var(--_solo-ink) var(--ui-border, 100%), var(--_solo-fill));
|
|
336
351
|
--_solo-depth: calc(2px * var(--ui-elevation, 1));
|
|
337
352
|
|
|
353
|
+
/* Printed as drawn; see `.glass-solo`. */
|
|
354
|
+
print-color-adjust: exact;
|
|
355
|
+
|
|
338
356
|
border: 1px solid var(--_solo-edge);
|
|
339
357
|
/* The surface shape: the element this exists for is usually a pane. An action
|
|
340
358
|
takes the control shape below. */
|
package/tw/box.css
CHANGED
|
@@ -203,8 +203,8 @@
|
|
|
203
203
|
with no aesthetic. The order lets a raised card under `.neobrutalism` keep
|
|
204
204
|
the slab. Nothing declares the last slot until something asks for depth, so
|
|
205
205
|
a plain unmodified page has no shadow anywhere. */
|
|
206
|
-
--_sy: calc(var(--ui-shadow-y, var(--_d-shadow-y, var(--
|
|
207
|
-
--_sb: calc(var(--ui-shadow-blur, var(--_d-shadow-blur, var(--
|
|
206
|
+
--_sy: calc(var(--ui-shadow-y, var(--_d-shadow-y, var(--_elevation-y, 0px))) * var(--_depth));
|
|
207
|
+
--_sb: calc(var(--ui-shadow-blur, var(--_d-shadow-blur, var(--_elevation-blur, 0px))) * var(--_depth));
|
|
208
208
|
/* Spread is deliberately not scaled. An aesthetic that draws its edge as an
|
|
209
209
|
inset ring spends spread on it, and scaling that by elevation would erase
|
|
210
210
|
the edge of every component the registry rests at zero. Elevation is depth:
|
|
@@ -363,20 +363,26 @@
|
|
|
363
363
|
full and darkens because the colour changed.
|
|
364
364
|
|
|
365
365
|
Separate from `box` because tinting on hover is right for something you press
|
|
366
|
-
and wrong for something you type into, so a component opts in.
|
|
366
|
+
and wrong for something you type into, so a component opts in.
|
|
367
|
+
|
|
368
|
+
Only where the primary pointer can hover, as Tailwind's `hover:` variant:
|
|
369
|
+
a touch screen leaves a tapped element in `:hover` until something else is
|
|
370
|
+
tapped, so without the query a button kept its hover tint after the tap. */
|
|
367
371
|
@utility box-hover {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
372
|
+
@media (hover: hover) {
|
|
373
|
+
&:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]):hover {
|
|
374
|
+
--_bg: color-mix(in oklab, var(--intent-hover) var(--_hover-fill), var(--_ground));
|
|
375
|
+
/* P3 again, against the hover tone: the line still fades as the fill fills
|
|
376
|
+
in, but toward the hover ink. Without this the edge keeps the resting ink
|
|
377
|
+
-- a ring of the colour the box just left. */
|
|
378
|
+
--_line: color-mix(in oklab, transparent var(--ui-fill, var(--_d-fill)), var(--intent-hover));
|
|
379
|
+
--_sx: calc(var(--ui-hover-shadow-x, var(--ui-shadow-x, var(--_d-shadow-x, 0px))) * var(--_depth));
|
|
380
|
+
--_sy: calc(
|
|
381
|
+
var(--ui-hover-shadow-y, var(--ui-shadow-y, var(--_d-shadow-y, var(--_elevation-y, 0px)))) * var(--_depth)
|
|
382
|
+
);
|
|
378
383
|
|
|
379
|
-
|
|
384
|
+
transform: var(--ui-hover-transform, none);
|
|
385
|
+
}
|
|
380
386
|
}
|
|
381
387
|
}
|
|
382
388
|
|
|
@@ -407,7 +413,7 @@
|
|
|
407
413
|
/* The same three slots as the resting offset, `.raised`'s plain step last,
|
|
408
414
|
so with no aesthetic a pressed button keeps the depth it rests on. */
|
|
409
415
|
--_sy: calc(
|
|
410
|
-
var(--ui-active-shadow-y, var(--ui-shadow-y, var(--_d-shadow-y, var(--
|
|
416
|
+
var(--ui-active-shadow-y, var(--ui-shadow-y, var(--_d-shadow-y, var(--_elevation-y, 0px)))) * var(--_depth)
|
|
411
417
|
);
|
|
412
418
|
|
|
413
419
|
--_press: calc(var(--ui-active-translate-x, 0px) * var(--_depth))
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
--_lg-py: var(--_size-lg) 0.625rem;
|
|
103
103
|
--_sm-text: var(--_size-sm) var(--text-sm);
|
|
104
104
|
--_lg-text: var(--_size-lg) 1.0625rem;
|
|
105
|
-
--_sm-leading: var(--_size-sm) var(--
|
|
105
|
+
--_sm-leading: var(--_size-sm) var(--text-sm--line-height);
|
|
106
106
|
--_sm-scale: var(--_size-sm) 0.75;
|
|
107
107
|
--_lg-scale: var(--_size-lg) 1.25;
|
|
108
108
|
--_scale-size: var(--_sm-scale, var(--_lg-scale));
|
|
@@ -137,13 +137,15 @@
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
/* Public, read with their defaults, so a value set on any ancestor reaches
|
|
141
|
+
the placeholder. */
|
|
142
|
+
--_skeleton-base: var(--skeleton-base, color-mix(in oklab, var(--intent-color) 6%, var(--intent-subtle)));
|
|
143
|
+
--_skeleton-sheen: var(--skeleton-sheen, color-mix(in oklab, var(--intent-color) 10%, var(--color-foreground)));
|
|
142
144
|
|
|
143
145
|
@apply min-h-4 w-full;
|
|
144
146
|
|
|
145
147
|
animation: anim-skeleton calc(var(--motion-duration-slow) * 4) linear infinite;
|
|
146
|
-
background: linear-gradient(90deg, var(--
|
|
148
|
+
background: linear-gradient(90deg, var(--_skeleton-base), var(--_skeleton-sheen), var(--_skeleton-base));
|
|
147
149
|
background-size: 200% 100%;
|
|
148
150
|
/* Not a box, so it draws the control corner and its pattern itself, the way
|
|
149
151
|
`box` does at scale 1, and reads the corner shape beside it. */
|
|
@@ -306,6 +308,23 @@
|
|
|
306
308
|
animation: none;
|
|
307
309
|
}
|
|
308
310
|
}
|
|
311
|
+
|
|
312
|
+
/* Forced colours, carried for an applied bar, as the toggles carry theirs.
|
|
313
|
+
The class also keeps the unlayered copy below, which beats every layered
|
|
314
|
+
rule; see there for why each part is named. */
|
|
315
|
+
@media (forced-colors: active) {
|
|
316
|
+
forced-color-adjust: none;
|
|
317
|
+
background-color: Canvas;
|
|
318
|
+
border-color: CanvasText;
|
|
319
|
+
|
|
320
|
+
&::after {
|
|
321
|
+
background-color: CanvasText;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
&::before {
|
|
325
|
+
display: none;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
309
328
|
}
|
|
310
329
|
|
|
311
330
|
/* Forced colours repaint every background as Canvas, the value fill on a
|
|
@@ -116,16 +116,20 @@
|
|
|
116
116
|
/* The last exclusion is `.input-group`'s: a group whose control is disabled
|
|
117
117
|
dims as a disabled field does (see `input-group`), so it does not answer
|
|
118
118
|
the pointer either. The list is the group's own, so a `<select>` with a
|
|
119
|
-
disabled `<option>` is not caught by it.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
119
|
+
disabled `<option>` is not caught by it. Under `(hover: hover)` as the
|
|
120
|
+
other hover responses are: a tapped checkbox, select, or group stays in
|
|
121
|
+
`:hover` without matching `:focus-visible`, and kept the hover line. */
|
|
122
|
+
@media (hover: hover) {
|
|
123
|
+
&:hover:not(
|
|
124
|
+
:disabled,
|
|
125
|
+
.disabled,
|
|
126
|
+
[aria-disabled="true"],
|
|
127
|
+
[data-disabled],
|
|
128
|
+
:focus-visible,
|
|
129
|
+
:has(> :is(.ipt, .textarea, .select, .text-control, input, textarea, select):disabled)
|
|
130
|
+
) {
|
|
131
|
+
--_line-tone: var(--intent-hover);
|
|
132
|
+
}
|
|
129
133
|
}
|
|
130
134
|
|
|
131
135
|
/* The line moves to the intent on top of the `reset.css` `:focus-visible`
|
|
@@ -324,6 +328,22 @@
|
|
|
324
328
|
--intent-fill-max: 100%;
|
|
325
329
|
}
|
|
326
330
|
|
|
331
|
+
/* A bare toggle's "on" plate. `/native` reaches the toggles through `@apply`
|
|
332
|
+
in `base`, where their `:checked` and `:indeterminate` pins lose to
|
|
333
|
+
`.ghost` and `.soft` in `utilities`, so a checked quiet checkbox kept its
|
|
334
|
+
resting plate. The class route already wins on specificity in this layer;
|
|
335
|
+
this repeats its values for the bare element, with the neutral cap
|
|
336
|
+
`native.css`'s reset puts back, which the arm above lifts only when
|
|
337
|
+
checked. Not `radio:indeterminate`, which every radio of a group with
|
|
338
|
+
nothing chosen matches. */
|
|
339
|
+
input:is([type="checkbox"], [type="radio"]):checked,
|
|
340
|
+
input[type="checkbox"]:indeterminate {
|
|
341
|
+
--intent-fill-max: 100%;
|
|
342
|
+
--ui-fill: 100%;
|
|
343
|
+
--ui-fg-on-fill: 100%;
|
|
344
|
+
--_fill-cap: 100%;
|
|
345
|
+
}
|
|
346
|
+
|
|
327
347
|
/* The three toggles read their own component cap (`--_fill-cap`, below) as the
|
|
328
348
|
ceiling regardless of intent, checked or not -- not just at `:checked`, the
|
|
329
349
|
way the arm above still works for a hypothetical checked text-control. A
|
|
@@ -389,7 +409,7 @@
|
|
|
389
409
|
--_lg-py: var(--_size-lg) 0.625rem;
|
|
390
410
|
--_sm-text: var(--_size-sm) var(--text-sm);
|
|
391
411
|
--_lg-text: var(--_size-lg) 1.0625rem;
|
|
392
|
-
--_sm-leading: var(--_size-sm) var(--
|
|
412
|
+
--_sm-leading: var(--_size-sm) var(--text-sm--line-height);
|
|
393
413
|
--_sm-scale: var(--_size-sm) 0.75;
|
|
394
414
|
--_lg-scale: var(--_size-lg) 1.25;
|
|
395
415
|
--_scale-size: var(--_sm-scale, var(--_lg-scale));
|
|
@@ -403,9 +423,10 @@
|
|
|
403
423
|
}
|
|
404
424
|
|
|
405
425
|
@utility field {
|
|
406
|
-
|
|
426
|
+
@apply flex w-full flex-col;
|
|
407
427
|
|
|
408
|
-
|
|
428
|
+
/* Public, read with its default, so a value on a form reaches every field. */
|
|
429
|
+
gap: var(--field-gap, 0.35rem);
|
|
409
430
|
}
|
|
410
431
|
|
|
411
432
|
@utility label {
|
|
@@ -465,7 +486,7 @@
|
|
|
465
486
|
--_lg-py: var(--_size-lg) 0.625rem;
|
|
466
487
|
--_sm-text: var(--_size-sm) var(--text-sm);
|
|
467
488
|
--_lg-text: var(--_size-lg) 1.0625rem;
|
|
468
|
-
--_sm-leading: var(--_size-sm) var(--
|
|
489
|
+
--_sm-leading: var(--_size-sm) var(--text-sm--line-height);
|
|
469
490
|
--_sm-scale: var(--_size-sm) 0.75;
|
|
470
491
|
--_lg-scale: var(--_size-lg) 1.25;
|
|
471
492
|
--_scale-size: var(--_sm-scale, var(--_lg-scale));
|
|
@@ -513,7 +534,7 @@
|
|
|
513
534
|
--_lg-py: var(--_size-lg) 0.625rem;
|
|
514
535
|
--_sm-text: var(--_size-sm) var(--text-sm);
|
|
515
536
|
--_lg-text: var(--_size-lg) 1.0625rem;
|
|
516
|
-
--_sm-leading: var(--_size-sm) var(--
|
|
537
|
+
--_sm-leading: var(--_size-sm) var(--text-sm--line-height);
|
|
517
538
|
--_sm-scale: var(--_size-sm) 0.75;
|
|
518
539
|
--_lg-scale: var(--_size-lg) 1.25;
|
|
519
540
|
--_scale-size: var(--_sm-scale, var(--_lg-scale));
|
|
@@ -553,6 +574,14 @@
|
|
|
553
574
|
padding-inline: 0.75rem;
|
|
554
575
|
background-image: none;
|
|
555
576
|
}
|
|
577
|
+
|
|
578
|
+
/* Forced colours, carried for an applied drop-down: the platform's arrow, for
|
|
579
|
+
the reason the unlayered copy at the foot of this file gives. */
|
|
580
|
+
@media (forced-colors: active) {
|
|
581
|
+
&:not([multiple], [size]:not([size="1"])) {
|
|
582
|
+
appearance: auto;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
556
585
|
}
|
|
557
586
|
|
|
558
587
|
/* A wrapper that owns the field box so a control can carry adornments beside it
|
|
@@ -573,7 +602,7 @@
|
|
|
573
602
|
breathing room a distinct glyph needs, but a text affix meant to glue onto the
|
|
574
603
|
value -- a URL host, a currency symbol, a unit -- reads the same gap as a
|
|
575
604
|
stray space breaking the two apart. A consumer sets `--input-group-gap: 0` on
|
|
576
|
-
|
|
605
|
+
the group or an ancestor for a flush affix; the default stays the icon-tuned
|
|
577
606
|
0.5rem so every existing icon composition is unchanged. */
|
|
578
607
|
@utility input-group {
|
|
579
608
|
@apply text-control flex w-full items-center;
|
|
@@ -597,17 +626,16 @@
|
|
|
597
626
|
--_lg-px: var(--_size-lg) 1rem;
|
|
598
627
|
--_sm-text: var(--_size-sm) var(--text-sm);
|
|
599
628
|
--_lg-text: var(--_size-lg) 1.0625rem;
|
|
600
|
-
--_sm-leading: var(--_size-sm) var(--
|
|
629
|
+
--_sm-leading: var(--_size-sm) var(--text-sm--line-height);
|
|
601
630
|
--_sm-scale: var(--_size-sm) 0.75;
|
|
602
631
|
--_lg-scale: var(--_size-lg) 1.25;
|
|
603
632
|
--_scale-size: var(--_sm-scale, var(--_lg-scale));
|
|
604
633
|
|
|
605
|
-
--input-group-gap: 0.5rem;
|
|
606
|
-
--input-group-pad: var(--_sm-px, var(--_lg-px, 0.75rem));
|
|
607
|
-
|
|
608
634
|
min-height: var(--_sm-h, var(--_lg-h, var(--control-height)));
|
|
609
|
-
|
|
610
|
-
|
|
635
|
+
/* Public, read with their defaults, so a value set on any ancestor reaches
|
|
636
|
+
the group. */
|
|
637
|
+
gap: var(--input-group-gap, 0.5rem);
|
|
638
|
+
padding-inline: var(--input-group-padding, var(--_sm-px, var(--_lg-px, 0.75rem)));
|
|
611
639
|
font-size: var(--_sm-text, var(--_lg-text, inherit));
|
|
612
640
|
line-height: var(--_sm-leading, inherit);
|
|
613
641
|
|
|
@@ -1053,22 +1081,24 @@
|
|
|
1053
1081
|
a badge or a card stays under. */
|
|
1054
1082
|
--_fill-cap: 40%;
|
|
1055
1083
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
--
|
|
1084
|
+
/* The track's size is public, read with its default, so a value set on any
|
|
1085
|
+
ancestor reaches the switch; the knob is derived from it. */
|
|
1086
|
+
--_switch-height: var(--switch-height, 1.25rem);
|
|
1087
|
+
--_switch-width: var(--switch-width, 2.5rem);
|
|
1088
|
+
--_switch-gap: 1px;
|
|
1059
1089
|
/* The edge an aesthetic draws as an inset ring rather than as a border
|
|
1060
1090
|
(`.pixel`), present only while `--ui-shadow-edge` is declared -- the idiom
|
|
1061
1091
|
`box` uses. That ring paints under the knob, so a knob sized from the
|
|
1062
1092
|
border alone covered it: under pixel the border is zero, the knob met the
|
|
1063
1093
|
edge, and an unchecked and a checked switch both read as two halves. */
|
|
1064
1094
|
--_switch-ring: var(--ui-shadow-edge) var(--_ss);
|
|
1065
|
-
--_switch-offset: calc(var(--_switch-ring, 0px) + var(--
|
|
1066
|
-
--
|
|
1067
|
-
--
|
|
1068
|
-
--
|
|
1095
|
+
--_switch-offset: calc(var(--_switch-ring, 0px) + var(--_switch-gap));
|
|
1096
|
+
--_switch-inset: calc(var(--_width) + var(--_switch-offset));
|
|
1097
|
+
--_switch-knob: calc(var(--_switch-height) - var(--_switch-inset) * 2);
|
|
1098
|
+
--_switch-travel: calc(var(--_switch-width) - var(--_switch-inset) * 2 - var(--_switch-knob));
|
|
1069
1099
|
|
|
1070
|
-
height: var(--
|
|
1071
|
-
width: var(--
|
|
1100
|
+
height: var(--_switch-height);
|
|
1101
|
+
width: var(--_switch-width);
|
|
1072
1102
|
/* Pill by default; a squaring aesthetic reaches the track and the knob
|
|
1073
1103
|
together, and an aesthetic with a pill corner of its own reaches both
|
|
1074
1104
|
through that first. */
|
|
@@ -1100,8 +1130,8 @@
|
|
|
1100
1130
|
itself, so the two stay the same shape. */
|
|
1101
1131
|
corner-shape: var(--ui-corner-shape, round);
|
|
1102
1132
|
content: "";
|
|
1103
|
-
height: var(--
|
|
1104
|
-
width: var(--
|
|
1133
|
+
height: var(--_switch-knob);
|
|
1134
|
+
width: var(--_switch-knob);
|
|
1105
1135
|
top: var(--_switch-offset);
|
|
1106
1136
|
inset-inline-start: var(--_switch-offset);
|
|
1107
1137
|
}
|
|
@@ -1111,14 +1141,14 @@
|
|
|
1111
1141
|
/* translate has no logical form, so the checked travel is named as a
|
|
1112
1142
|
physical x offset and mirrored under :dir(rtl) to travel toward the
|
|
1113
1143
|
opposite edge, matching the inset-inline-start resting position. */
|
|
1114
|
-
translate: var(--
|
|
1144
|
+
translate: var(--_switch-travel);
|
|
1115
1145
|
}
|
|
1116
1146
|
|
|
1117
1147
|
/* Direction sits on the control, ahead of the pseudo-element: nested as
|
|
1118
1148
|
`:dir(rtl) &` inside `&:checked::after`, `&` carries `::after`, which
|
|
1119
1149
|
cannot appear inside `:is()`, and the emitted rule matched nothing. */
|
|
1120
1150
|
&:checked:dir(rtl)::after {
|
|
1121
|
-
translate: calc(-1 * var(--
|
|
1151
|
+
translate: calc(-1 * var(--_switch-travel));
|
|
1122
1152
|
}
|
|
1123
1153
|
|
|
1124
1154
|
/* The mark appears without moving under reduced motion, for the entries
|
|
@@ -86,11 +86,14 @@
|
|
|
86
86
|
|
|
87
87
|
--_hover-ground: var(--_m-hover) color-mix(in oklab, var(--color-surface) var(--_quiet), var(--color-background));
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
89
|
+
/* Behind the query `box-hover` is, so a tapped card keeps its ground. */
|
|
90
|
+
@media (hover: hover) {
|
|
91
|
+
&:hover {
|
|
92
|
+
--_d-surface-ground: var(
|
|
93
|
+
--_hover-ground,
|
|
94
|
+
color-mix(in oklab, var(--color-foreground) var(--_quiet), var(--color-background))
|
|
95
|
+
);
|
|
96
|
+
}
|
|
94
97
|
}
|
|
95
98
|
|
|
96
99
|
/* Opt-in, because a card is only sometimes a control. Applications still owe
|
|
@@ -12,40 +12,45 @@
|
|
|
12
12
|
trigger's own `aria-describedby`; wiring that association is the consumer's,
|
|
13
13
|
this package only styles the bubble. See docs/usage/tooltips.md. */
|
|
14
14
|
@utility tooltip {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
--
|
|
24
|
-
--
|
|
25
|
-
--
|
|
15
|
+
/* `--tooltip-gap` and `--tooltip-linger` are public, read with their
|
|
16
|
+
defaults rather than declared, so a value set on any ancestor reaches the
|
|
17
|
+
tooltip. The linger is how long the bubble stays after the pointer leaves
|
|
18
|
+
the trigger: long enough to cross the gap onto the bubble, which keeps it
|
|
19
|
+
open (WCAG 1.4.13). The default is resolved here, so a bubble outside a
|
|
20
|
+
tooltip keeps no delay unless a linger is set above it. The bubble reads
|
|
21
|
+
the public one first, so a value set on the bubble itself, as 0.8
|
|
22
|
+
allowed, still wins. */
|
|
23
|
+
--_tooltip-gap: var(--tooltip-gap, 0.5rem);
|
|
24
|
+
--_tooltip-linger: var(--tooltip-linger, 300ms);
|
|
25
|
+
--_tooltip-top: calc(var(--_tooltip-gap) * -1);
|
|
26
|
+
--_tooltip-right: auto;
|
|
27
|
+
--_tooltip-bottom: auto;
|
|
28
|
+
--_tooltip-left: 50%;
|
|
29
|
+
--_tooltip-origin: bottom;
|
|
30
|
+
--_tooltip-transform: translate(-50%, -100%);
|
|
26
31
|
|
|
27
32
|
@apply relative inline-block;
|
|
28
33
|
|
|
29
34
|
&[data-tooltip-position="bottom"] {
|
|
30
|
-
--
|
|
31
|
-
--
|
|
32
|
-
--
|
|
33
|
-
--
|
|
35
|
+
--_tooltip-top: auto;
|
|
36
|
+
--_tooltip-bottom: calc(var(--_tooltip-gap) * -1);
|
|
37
|
+
--_tooltip-origin: top;
|
|
38
|
+
--_tooltip-transform: translate(-50%, 100%);
|
|
34
39
|
}
|
|
35
40
|
|
|
36
41
|
&[data-tooltip-position="left"] {
|
|
37
|
-
--
|
|
38
|
-
--
|
|
39
|
-
--
|
|
40
|
-
--
|
|
42
|
+
--_tooltip-top: 50%;
|
|
43
|
+
--_tooltip-left: calc(var(--_tooltip-gap) * -1);
|
|
44
|
+
--_tooltip-origin: right;
|
|
45
|
+
--_tooltip-transform: translate(-100%, -50%);
|
|
41
46
|
}
|
|
42
47
|
|
|
43
48
|
&[data-tooltip-position="right"] {
|
|
44
|
-
--
|
|
45
|
-
--
|
|
46
|
-
--
|
|
47
|
-
--
|
|
48
|
-
--
|
|
49
|
+
--_tooltip-top: 50%;
|
|
50
|
+
--_tooltip-left: auto;
|
|
51
|
+
--_tooltip-right: calc(var(--_tooltip-gap) * -1);
|
|
52
|
+
--_tooltip-origin: left;
|
|
53
|
+
--_tooltip-transform: translate(100%, -50%);
|
|
49
54
|
}
|
|
50
55
|
}
|
|
51
56
|
|
|
@@ -59,13 +64,13 @@
|
|
|
59
64
|
/* Hidden rather than merely transparent, so a closed bubble is nothing
|
|
60
65
|
under the pointer, and it lingers before it goes: the host stays hovered
|
|
61
66
|
once the pointer is over the bubble, so crossing the gap in
|
|
62
|
-
`--
|
|
67
|
+
`--_tooltip-linger` keeps it open. Visibility switches at the end of the
|
|
63
68
|
fade, so the bubble is there to land on for the whole of it. */
|
|
64
69
|
visibility: hidden;
|
|
65
70
|
transition-property: opacity, transform, visibility;
|
|
66
71
|
transition-duration: var(--motion-duration-normal);
|
|
67
72
|
transition-timing-function: var(--motion-ease);
|
|
68
|
-
transition-delay: var(--tooltip-linger, 0s);
|
|
73
|
+
transition-delay: var(--tooltip-linger, var(--_tooltip-linger, 0s));
|
|
69
74
|
|
|
70
75
|
/* Filled, over a ground of its own. An intent floods the fill
|
|
71
76
|
(`.tooltip-bubble.primary` is the primary colour); with no intent
|
|
@@ -104,12 +109,12 @@
|
|
|
104
109
|
calc(var(--_corner) * var(--ui-corner-tl, 1)) calc(var(--_corner) * var(--ui-corner-tr, 1))
|
|
105
110
|
calc(var(--_corner) * var(--ui-corner-br, 1)) calc(var(--_corner) * var(--ui-corner-bl, 1))
|
|
106
111
|
);
|
|
107
|
-
left: var(--
|
|
108
|
-
right: var(--
|
|
109
|
-
top: var(--
|
|
110
|
-
bottom: var(--
|
|
111
|
-
transform: var(--
|
|
112
|
-
transform-origin: var(--
|
|
112
|
+
left: var(--_tooltip-left);
|
|
113
|
+
right: var(--_tooltip-right);
|
|
114
|
+
top: var(--_tooltip-top);
|
|
115
|
+
bottom: var(--_tooltip-bottom);
|
|
116
|
+
transform: var(--_tooltip-transform) scale(0);
|
|
117
|
+
transform-origin: var(--_tooltip-origin);
|
|
113
118
|
|
|
114
119
|
/* The bubble appears without growing under reduced motion, for the entries
|
|
115
120
|
without the reset; see `box.css`. */
|
|
@@ -149,7 +154,7 @@
|
|
|
149
154
|
.tooltip:focus-within &,
|
|
150
155
|
.tooltip[data-state="open"] & {
|
|
151
156
|
opacity: 1;
|
|
152
|
-
transform: var(--
|
|
157
|
+
transform: var(--_tooltip-transform) scale(1);
|
|
153
158
|
visibility: visible;
|
|
154
159
|
transition-delay: 0s;
|
|
155
160
|
}
|
|
@@ -161,7 +166,7 @@
|
|
|
161
166
|
focus alike. */
|
|
162
167
|
.tooltip[data-state="closed"] & {
|
|
163
168
|
opacity: 0;
|
|
164
|
-
transform: var(--
|
|
169
|
+
transform: var(--_tooltip-transform) scale(0);
|
|
165
170
|
visibility: hidden;
|
|
166
171
|
transition-delay: 0s;
|
|
167
172
|
}
|
package/tw/elevation.css
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
`.flat` removes a part-based slab or blur without a conditional (complete
|
|
11
11
|
surface shadows like glass remain). See model.md#elevation.
|
|
12
12
|
|
|
13
|
-
`--ui-elevation`, and the plain-page fallback geometry (`--
|
|
14
|
-
`--
|
|
13
|
+
`--ui-elevation`, and the plain-page fallback geometry (`--_elevation-y`,
|
|
14
|
+
`--_elevation-blur`) below, are registered non-inheriting: a class sets them
|
|
15
15
|
on the element it is written on and nothing else picks them up. Inherited, a
|
|
16
16
|
`.floating` dialog's ambient x2 would reach its own unclassed buttons and
|
|
17
17
|
double their shadow with nothing in the markup asking for it. Depth is not
|
|
@@ -37,12 +37,12 @@
|
|
|
37
37
|
inherits: false;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
@property --
|
|
40
|
+
@property --_elevation-y {
|
|
41
41
|
syntax: "*";
|
|
42
42
|
inherits: false;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
@property --
|
|
45
|
+
@property --_elevation-blur {
|
|
46
46
|
syntax: "*";
|
|
47
47
|
inherits: false;
|
|
48
48
|
}
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
/* The aesthetic's depth as authored, said explicitly. */
|
|
64
64
|
@utility raised {
|
|
65
65
|
@layer families {
|
|
66
|
-
--
|
|
67
|
-
--
|
|
66
|
+
--_elevation-y: 1px;
|
|
67
|
+
--_elevation-blur: 3px;
|
|
68
68
|
--ui-elevation: 1;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
/* Twice it, for menus and popovers. */
|
|
73
73
|
@utility floating {
|
|
74
74
|
@layer families {
|
|
75
|
-
--
|
|
76
|
-
--
|
|
75
|
+
--_elevation-y: 1px;
|
|
76
|
+
--_elevation-blur: 3px;
|
|
77
77
|
--ui-elevation: 2;
|
|
78
78
|
}
|
|
79
79
|
}
|
package/tw/native.css
CHANGED
|
@@ -60,7 +60,10 @@
|
|
|
60
60
|
--intent-border: var(--ui-rule-ink, var(--ui-ink, var(--color-border)));
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
/* A bare rule and progress bar take the color they sit in, as `.divider`
|
|
64
|
+
and `.progress` do in `intent.css`; a bar in a filled container drew the
|
|
65
|
+
page's text color over the container's own. */
|
|
66
|
+
:where(hr, progress) {
|
|
64
67
|
--intent-color: currentColor;
|
|
65
68
|
--intent-border: currentColor;
|
|
66
69
|
}
|
package/tw/theme.css
CHANGED
|
@@ -271,7 +271,7 @@
|
|
|
271
271
|
at any depth. It does not win over an explicit selector of the opposite
|
|
272
272
|
theme further up: `.dark *` matches every descendant of a `.dark` element,
|
|
273
273
|
including one inside a nested `.light`, so a `dark:` utility still fires
|
|
274
|
-
there although its tokens are light. `
|
|
274
|
+
there although its tokens are light. `docs/usage/theming.md#the-dark-variant` documents it. */
|
|
275
275
|
@custom-variant dark {
|
|
276
276
|
&:where(.dark, .dark *, .theme-dark, .theme-dark *, [data-theme="dark"], [data-theme="dark"] *) {
|
|
277
277
|
@slot;
|