@codenhub/styles 0.5.0 → 0.7.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/NOTICE +18 -16
- package/README.es.md +61 -0
- package/README.md +27 -22
- package/README.pt-BR.md +61 -0
- 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 +2 -2
- package/dist/aesthetics/neobrutalism.css +1 -1
- package/dist/aesthetics/pixel.css +1 -1
- package/dist/aesthetics/sketch.css +1 -1
- package/dist/components.css +2 -2
- package/dist/index.css +2 -2
- package/dist/native.css +2 -2
- package/dist/palette.css +1 -1
- package/dist/theme.css +2 -2
- package/dist/tw/aesthetics/chunky-tile.css +120 -62
- package/dist/tw/aesthetics/cyber.css +102 -40
- package/dist/tw/aesthetics/glass.css +371 -19
- package/dist/tw/aesthetics/index.css +2 -1
- package/dist/tw/aesthetics/neobrutalism.css +121 -33
- package/dist/tw/aesthetics/pixel.css +111 -16
- package/dist/tw/aesthetics/sketch.css +100 -28
- package/dist/tw/box.css +69 -28
- package/dist/tw/components/button.css +35 -14
- package/dist/tw/components/feedback.css +61 -58
- package/dist/tw/components/form.css +255 -142
- package/dist/tw/components/index.css +4 -9
- package/dist/tw/components/surface.css +80 -68
- package/dist/tw/components/tooltip.css +75 -41
- package/dist/tw/elevation.css +14 -22
- package/dist/tw/index.css +15 -19
- package/dist/tw/intent.css +35 -27
- package/dist/tw/native.css +22 -12
- package/dist/tw/palette.css +14 -11
- package/dist/tw/presentation.css +16 -30
- package/dist/tw/reset.css +36 -43
- package/dist/tw/surface.css +11 -12
- package/dist/tw/theme.css +87 -103
- package/dist/tw/utilities/content.css +311 -200
- package/dist/tw/utilities/layout.css +41 -37
- package/docs/accessibility.md +104 -58
- package/docs/changelog/0.1.1.md +1 -0
- package/docs/changelog/0.2.0.md +1 -0
- package/docs/changelog/0.3.0.md +1 -0
- package/docs/changelog/0.4.0.md +1 -0
- package/docs/changelog/0.5.0.md +8 -3
- package/docs/changelog/0.6.0.md +53 -0
- package/docs/changelog/0.7.0.md +50 -0
- package/docs/changelog/index.md +2 -0
- package/docs/concepts.md +188 -46
- package/docs/es/accessibility.md +150 -0
- package/docs/es/concepts.md +212 -0
- package/docs/es/index.md +104 -0
- package/docs/es/integrating/astro.md +35 -0
- package/docs/es/integrating/index.md +47 -0
- package/docs/es/integrating/nextjs.md +67 -0
- package/docs/es/integrating/svelte.md +45 -0
- package/docs/es/integrating/tailwind.md +78 -0
- package/docs/es/integrating/vue.md +31 -0
- package/docs/es/integrating/without-a-bundler.md +115 -0
- package/docs/es/setup.md +180 -0
- package/docs/es/usage/aesthetics.md +276 -0
- package/docs/es/usage/buttons.md +131 -0
- package/docs/es/usage/composing.md +164 -0
- package/docs/es/usage/content-and-layout.md +215 -0
- package/docs/es/usage/customizing.md +298 -0
- package/docs/es/usage/feedback.md +153 -0
- package/docs/es/usage/forms.md +231 -0
- package/docs/es/usage/index.md +29 -0
- package/docs/es/usage/solo.md +84 -0
- package/docs/es/usage/theming.md +296 -0
- package/docs/es/usage/tooltips.md +127 -0
- package/docs/index.md +89 -21
- package/docs/integrating/astro.md +3 -4
- package/docs/integrating/index.md +18 -13
- package/docs/integrating/nextjs.md +4 -5
- package/docs/integrating/svelte.md +5 -4
- package/docs/integrating/tailwind.md +29 -8
- package/docs/integrating/vue.md +3 -4
- package/docs/integrating/without-a-bundler.md +114 -0
- package/docs/pt-BR/accessibility.md +150 -0
- package/docs/pt-BR/concepts.md +212 -0
- package/docs/pt-BR/index.md +104 -0
- package/docs/pt-BR/integrating/astro.md +35 -0
- package/docs/pt-BR/integrating/index.md +47 -0
- package/docs/pt-BR/integrating/nextjs.md +67 -0
- package/docs/pt-BR/integrating/svelte.md +45 -0
- package/docs/pt-BR/integrating/tailwind.md +78 -0
- package/docs/pt-BR/integrating/vue.md +31 -0
- package/docs/pt-BR/integrating/without-a-bundler.md +115 -0
- package/docs/pt-BR/setup.md +180 -0
- package/docs/pt-BR/usage/aesthetics.md +276 -0
- package/docs/pt-BR/usage/buttons.md +131 -0
- package/docs/pt-BR/usage/composing.md +164 -0
- package/docs/pt-BR/usage/content-and-layout.md +215 -0
- package/docs/pt-BR/usage/customizing.md +298 -0
- package/docs/pt-BR/usage/feedback.md +153 -0
- package/docs/pt-BR/usage/forms.md +231 -0
- package/docs/pt-BR/usage/index.md +29 -0
- package/docs/pt-BR/usage/solo.md +84 -0
- package/docs/pt-BR/usage/theming.md +296 -0
- package/docs/pt-BR/usage/tooltips.md +127 -0
- package/docs/setup.md +134 -91
- package/docs/usage/aesthetics.md +102 -65
- package/docs/usage/buttons.md +108 -40
- package/docs/usage/composing.md +105 -92
- package/docs/usage/content-and-layout.md +159 -127
- package/docs/usage/customizing.md +112 -43
- package/docs/usage/feedback.md +135 -70
- package/docs/usage/forms.md +184 -99
- package/docs/usage/index.md +18 -14
- package/docs/usage/solo.md +83 -0
- package/docs/usage/theming.md +260 -119
- package/docs/usage/tooltips.md +103 -42
- package/llms-full.txt +2465 -1272
- package/llms.txt +25 -17
- package/package.json +28 -35
- package/dist/tw/components/loader.css +0 -117
package/dist/tw/box.css
CHANGED
|
@@ -35,6 +35,21 @@
|
|
|
35
35
|
own presentation instead of the container's reinterpretation of one. */
|
|
36
36
|
--_fill-cap: 100%;
|
|
37
37
|
--_capped: min(var(--ui-fill, var(--_d-fill)), var(--_fill-cap, 100%), var(--intent-fill-max, 100%));
|
|
38
|
+
/* Whether the intent's cap stopped the fill short, as 0% or 100%. A capped
|
|
39
|
+
fill is a plate the presentation asked to be full, so it rests on the page
|
|
40
|
+
background rather than on nothing: 20% of the page's ink over nothing
|
|
41
|
+
showed whatever sat behind a neutral `.solid` -- glass's backdrop, an
|
|
42
|
+
image, the colour of a filled card around it -- where on a plain page it
|
|
43
|
+
read as the light grey plate it is meant to be. The component's own cap
|
|
44
|
+
is measured out first, so a text control's 20% wash and a neutral
|
|
45
|
+
`.card.soft`'s 0% stay the tints they are, whatever the intent. Stepped
|
|
46
|
+
rather than scaled because the two percentages cannot be divided in every
|
|
47
|
+
engine yet. */
|
|
48
|
+
--_plate: clamp(
|
|
49
|
+
0%,
|
|
50
|
+
calc((min(var(--ui-fill, var(--_d-fill)), var(--_fill-cap, 100%)) - var(--_capped)) * 1000),
|
|
51
|
+
100%
|
|
52
|
+
);
|
|
38
53
|
--_fill: calc(var(--_capped) * var(--ui-bg-alpha, 1));
|
|
39
54
|
--_hover-fill: calc(min(100%, var(--_capped) + var(--hover-step)) * var(--ui-bg-alpha, 1));
|
|
40
55
|
/* How much of the foreground is the contrast ink: what the presentation asks
|
|
@@ -57,40 +72,48 @@
|
|
|
57
72
|
declaration beats the inherited one at any specificity; `surface`, `kbd`,
|
|
58
73
|
`code`, `pre` and the tooltip each restate theirs after `@apply box`. */
|
|
59
74
|
--_d-ground: transparent;
|
|
75
|
+
/* The ground, made the page background wherever `--_plate` says the cap
|
|
76
|
+
stopped the fill -- over a component's own ground too, so a capped
|
|
77
|
+
`.solid` surface under glass is opaque like every other `.solid`. */
|
|
78
|
+
--_ground: color-mix(in oklab, var(--color-background) var(--_plate), var(--_d-ground, transparent));
|
|
60
79
|
|
|
61
|
-
--_bg: color-mix(in oklab, var(--intent-color) var(--_fill), var(--
|
|
80
|
+
--_bg: color-mix(in oklab, var(--intent-color) var(--_fill), var(--_ground));
|
|
62
81
|
/* The two ends answer different questions: `--intent-contrast` prints *on* the
|
|
63
82
|
fill, `--intent-strong` prints on the page (the slot for readable ink on a
|
|
64
83
|
subtle fill). Reading `--intent-color` at the page end instead makes every
|
|
65
84
|
colour do double duty and prints a soft amber component at 3.1:1.
|
|
66
85
|
`--intent-contrast` keeps its own meaning -- `--_on-fill` reconciles it with
|
|
67
86
|
a capped intent -- rather than being bent so neutral's contrast is the ink,
|
|
68
|
-
which
|
|
87
|
+
which renders a checked neutral checkbox black-on-black. */
|
|
69
88
|
--_fg: color-mix(in oklab, var(--intent-contrast) var(--_on-fill), var(--intent-strong));
|
|
70
89
|
/* P3: the line fades out as the fill fills in, so a filled box has a seamless
|
|
71
|
-
edge. It fades toward `transparent`, not toward the plate: the plate
|
|
72
|
-
runs under the border (nothing
|
|
73
|
-
box), so a line blended toward `--_bg`
|
|
74
|
-
itself
|
|
75
|
-
neutral fill
|
|
76
|
-
|
|
77
|
-
nothing, the border shows the one coat beneath it.
|
|
90
|
+
edge. It fades toward `transparent`, not toward the plate: the plate
|
|
91
|
+
already runs under the border (nothing clips the background to the padding
|
|
92
|
+
box), so a line blended toward `--_bg` paints the plate a second time over
|
|
93
|
+
itself -- invisible on an opaque plate, a ring on a translucent one (a
|
|
94
|
+
neutral fill capped at 20%, or any fill `--ui-bg-alpha` thins). Faded
|
|
95
|
+
toward nothing, the border shows the one coat beneath it.
|
|
78
96
|
|
|
79
|
-
Blend first, amount after (`--_edge-amount` below)
|
|
80
|
-
`.edgeless` on the fill colour, which the border box
|
|
81
|
-
coat
|
|
97
|
+
Blend first, amount after (`--_edge-amount` below): the other order lands
|
|
98
|
+
`.edgeless` on the fill colour, which the border box paints as a second
|
|
99
|
+
coat -- a ring around an element that asked for no edge. See
|
|
82
100
|
docs/internal/model.md#presentation. */
|
|
83
101
|
--_line: color-mix(in oklab, transparent var(--ui-fill, var(--_d-fill)), var(--intent-border));
|
|
84
102
|
/* How much line there is, as an input rather than a result. A component that
|
|
85
103
|
must keep its line whatever the edge class says raises `--_edge-floor`
|
|
86
104
|
instead of rewriting `--_edge`, and the composition above still runs.
|
|
87
105
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
106
|
+
Rewriting the result drops every term it was composed from, silently and
|
|
107
|
+
with nothing to report. Bounding the input leaves the axis live, so
|
|
108
|
+
`.edged` and `.edgeless` still mean what they say on a component that
|
|
109
|
+
floors itself.
|
|
110
|
+
|
|
111
|
+
Restated at `0%` -- no floor -- for the reason `--_fill-cap` is restated
|
|
112
|
+
above: the floor inherits, so a field's or a tooltip bubble's `100%` reached
|
|
113
|
+
every box nested inside, and a `.btn.edgeless` clear button in an
|
|
114
|
+
`.input-group` drew a field's line it had asked not to have. Components
|
|
115
|
+
that floor themselves declare theirs after `@apply box`. */
|
|
116
|
+
--_edge-floor: 0%;
|
|
94
117
|
--_edge-amount: max(var(--ui-border, var(--_d-border)), var(--_edge-floor, 0%));
|
|
95
118
|
--_edge: color-mix(in oklab, var(--_line) var(--_edge-amount), transparent);
|
|
96
119
|
--_width: min(var(--ui-border-width, var(--border-width)), var(--ui-border-max, 100px));
|
|
@@ -111,6 +134,10 @@
|
|
|
111
134
|
public override, undeclared by the package. See docs/internal/model.md#material-tokens. */
|
|
112
135
|
--_scale-size: initial;
|
|
113
136
|
--_scale-pad: initial;
|
|
137
|
+
/* The padding the same modifiers set on a `.card` or `.panel`, restated for
|
|
138
|
+
the same reason: a `.card.p-xs` or `.flush` would otherwise pad every
|
|
139
|
+
surface nested inside it to its own value. */
|
|
140
|
+
--surface-padding: initial;
|
|
114
141
|
--_scale: var(--ui-scale, min(var(--_scale-size, var(--_scale-pad, 1)), var(--_scale-pad, var(--_scale-size, 1))));
|
|
115
142
|
/* Depth follows the step down and not up: a 4px slab under a 20px button
|
|
116
143
|
swallows it, while a press that travels the aesthetic's whole depth has to
|
|
@@ -168,17 +195,22 @@
|
|
|
168
195
|
on anything that set one. `--ui-surface-shadow` is that escape hatch narrowed
|
|
169
196
|
to the single case that needs it. */
|
|
170
197
|
--_shadow: var(--_shadow-parts) var(--_halo-layer,);
|
|
171
|
-
|
|
198
|
+
/* The inset focus layer an aesthetic that clips asks for, in two tones. The
|
|
199
|
+
ring is the primary colour, so on a `.solid.primary` box it was painted
|
|
200
|
+
over its own colour and a focused button was pixel for pixel a resting
|
|
201
|
+
one. A line of the page colour sits inside it: one of the two always
|
|
202
|
+
differs from the fill, whatever the fill is. Shadows paint first-on-top,
|
|
203
|
+
so the line is listed last and is the two pixels the ring leaves showing. */
|
|
204
|
+
--_focus-stack:
|
|
205
|
+
var(--_shadow), inset 0 0 0 var(--ui-focus-inset) var(--focus-ring),
|
|
206
|
+
inset 0 0 0 calc(var(--ui-focus-inset) + 2px) var(--color-background);
|
|
172
207
|
|
|
173
208
|
/* Every box sizes itself as `min-height`/`min-width: var(--control-height)`
|
|
174
|
-
plus its own padding and the border shorthand above, so its geometry is
|
|
175
|
-
right under `
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
inherited the `content-box` default and every sized control came out
|
|
180
|
-
inflated by its own padding and border. A component's own geometry is not an
|
|
181
|
-
external reset's job; `box` owns it. */
|
|
209
|
+
plus its own padding and the border shorthand above, so its geometry is
|
|
210
|
+
only right under `border-box`. `reset.css` sets that on `*`, but only the
|
|
211
|
+
`.`, `/native` and `/tw/reset` entrypoints carry the reset; `/components`
|
|
212
|
+
and the granular `/tw/*` component entrypoints ship neither it nor
|
|
213
|
+
Preflight, so `box` owns it. */
|
|
182
214
|
box-sizing: border-box;
|
|
183
215
|
background-color: var(--_bg);
|
|
184
216
|
color: var(--_fg);
|
|
@@ -221,6 +253,15 @@
|
|
|
221
253
|
transform var(--motion-duration-normal) var(--motion-ease),
|
|
222
254
|
translate var(--motion-duration-normal) var(--motion-ease);
|
|
223
255
|
|
|
256
|
+
/* Reduced motion stops here as well as in `reset.css`: `/components` and the
|
|
257
|
+
focused `/tw/*` entries carry no reset, so each component that moves says
|
|
258
|
+
so itself -- this for everything `box` paints, and the components with a
|
|
259
|
+
transition or animation of their own beside it. The same near-zero
|
|
260
|
+
duration the reset uses, so a `transitionend` still fires. */
|
|
261
|
+
@media (prefers-reduced-motion: reduce) {
|
|
262
|
+
transition-duration: 0.01ms;
|
|
263
|
+
}
|
|
264
|
+
|
|
224
265
|
/* An aesthetic that clips cannot show the global focus outline, so it declares
|
|
225
266
|
`--ui-focus-inset` and gets an inset layer instead. With no such aesthetic
|
|
226
267
|
the token is undefined, which makes the whole stack invalid at computed-value
|
|
@@ -254,7 +295,7 @@
|
|
|
254
295
|
and wrong for something you type into, so a component opts in. */
|
|
255
296
|
@utility box-hover {
|
|
256
297
|
&:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]):hover {
|
|
257
|
-
--_bg: color-mix(in oklab, var(--intent-hover) var(--_hover-fill), var(--
|
|
298
|
+
--_bg: color-mix(in oklab, var(--intent-hover) var(--_hover-fill), var(--_ground));
|
|
258
299
|
/* P3 again, against the hover tone: the line still fades as the fill fills
|
|
259
300
|
in, but toward the hover ink. Without this the edge keeps the resting ink
|
|
260
301
|
-- a ring of the colour the box just left. */
|
|
@@ -17,6 +17,18 @@
|
|
|
17
17
|
@apply box box-hover box-active relative inline-flex w-fit cursor-pointer items-center justify-center gap-2 px-4 py-2 whitespace-nowrap no-underline select-none;
|
|
18
18
|
|
|
19
19
|
min-height: var(--control-height);
|
|
20
|
+
/* The vertical padding gives back the line `box` draws, so a default button
|
|
21
|
+
is exactly `--control-height` tall like `.ipt` beside it, under any
|
|
22
|
+
aesthetic's line width. At the default 16px/1.5 text the label and the
|
|
23
|
+
padding fill it; the size and padding modifiers set their own. */
|
|
24
|
+
padding-block: calc(0.5rem - var(--_width));
|
|
25
|
+
/* The surrounding font, not the user agent's smaller button one, on every
|
|
26
|
+
entry: `/components` carries no reset to say so, and a `.btn` link and a
|
|
27
|
+
`.btn` button have to print the same label. `.sm` and `.lg` set their own
|
|
28
|
+
size over this. */
|
|
29
|
+
font-family: inherit;
|
|
30
|
+
font-size: inherit;
|
|
31
|
+
line-height: inherit;
|
|
20
32
|
/* The label is material, shared with `.badge`: weight, tracking, case, and a
|
|
21
33
|
text shadow, set by an aesthetic as tokens (`.chunky-tile`'s heavier,
|
|
22
34
|
tracked label), and a consumer's own `font-*`, `tracking-*`, `uppercase`, or
|
|
@@ -50,20 +62,29 @@
|
|
|
50
62
|
min-width: var(--control-height);
|
|
51
63
|
}
|
|
52
64
|
|
|
53
|
-
/*
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
/* The size steps for an icon button, square at each: `.sm`'s 2rem, with the
|
|
66
|
+
padding giving back the line width the way the default button's does, and
|
|
67
|
+
`.lg`'s 3rem. Each names its width as well as its height, because WebKit
|
|
68
|
+
does not let `aspect-ratio` widen a box past its `min-width`. */
|
|
69
|
+
&.icon.sm {
|
|
70
|
+
min-width: 2rem;
|
|
71
|
+
padding: calc(0.375rem - var(--_width));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
&.icon.lg {
|
|
75
|
+
min-width: 3rem;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Bare `sm`/`lg` are the size modifier's class names, so `p-` prefixes here.
|
|
79
|
+
`.p-xs` is the tightest step, below `.p-sm`: a chip-sized button in a
|
|
80
|
+
toolbar or a table cell.
|
|
81
|
+
|
|
82
|
+
`.icon` drops both floors -- `min-width` from its own base rule above and
|
|
83
|
+
`min-height` from `--control-height` -- at every padding tier; labeled
|
|
84
|
+
buttons keep the height floor everywhere but `.p-xs`. `.icon` is already
|
|
85
|
+
square: `aspect-square` ties its width to whatever height it lands on, so a
|
|
86
|
+
surviving height floor would keep the button bigger than its own glyph
|
|
87
|
+
however tight the padding asked to be. */
|
|
67
88
|
&.p-xs {
|
|
68
89
|
@apply px-2 py-0.5;
|
|
69
90
|
|
|
@@ -38,50 +38,45 @@
|
|
|
38
38
|
--_d-elevation: 0;
|
|
39
39
|
|
|
40
40
|
/* Same carve-out as `.panel`'s, and for the same reason: a neutral alert
|
|
41
|
-
mixes 12% of near-black ink onto the page
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
alert has no hover state to reveal a tint into either, so this is
|
|
56
|
-
permanent rather than revealed. Unlike a neutral panel or badge, an
|
|
57
|
-
alert cannot lose its visual identity from this: `--_d-border: 100%`
|
|
58
|
-
above holds regardless of fill, so a neutral alert still reads as a
|
|
59
|
-
framed box, just a quiet one instead of a grey slab. */
|
|
41
|
+
mixes 12% of near-black ink onto the page (`217, 217, 217` against `250,
|
|
42
|
+
250, 250`), a slab rather than a status signal. Scoped to no named intent:
|
|
43
|
+
a named intent keeps its ordinary wash, because untinting
|
|
44
|
+
`.alert.soft.destructive` would silence the status it exists to carry
|
|
45
|
+
rather than quiet it. `:not(...)` names every intent class, plus
|
|
46
|
+
`.solid`/`.ghost` so an explicit presentation on the element is never
|
|
47
|
+
clamped to a cap it did not ask for.
|
|
48
|
+
|
|
49
|
+
Grounds on `--color-foreground` through `--_d-surface-ground`, exactly like
|
|
50
|
+
`.panel` and a resting `.card.soft`, so glass's ground and a consumer's
|
|
51
|
+
`--ui-surface-ground` still win over it. An alert has no hover state to
|
|
52
|
+
reveal a tint into either, so this is permanent. A neutral alert keeps its
|
|
53
|
+
identity: `--_d-border: 100%` above holds regardless of fill, so it still
|
|
54
|
+
reads as a framed box, just a quiet one instead of a grey slab. */
|
|
60
55
|
&:not(.primary, .secondary, .success, .warning, .destructive, .info, .solid, .ghost) {
|
|
61
56
|
--_fill-cap: 0%;
|
|
62
57
|
--_d-surface-ground: var(--color-foreground);
|
|
63
58
|
}
|
|
64
59
|
}
|
|
65
60
|
|
|
66
|
-
/* No icon is shipped
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
`.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
whether one is present. Any icon element works, the same contract
|
|
73
|
-
`.input-group` documents -- an inline `<svg>`, an `<img>`, or a class from an
|
|
74
|
-
icon set such as `@codenhub/icons`. */
|
|
61
|
+
/* No icon is shipped. `.alert` is already `flex`, so an icon dropped in as a
|
|
62
|
+
real child is spaced by `gap-3`: `.alert-icon` only fixes its size and
|
|
63
|
+
alignment, not whether one is present. Any icon element works, the same
|
|
64
|
+
contract `.input-group` documents -- an inline `<svg>`, an `<img>`, or a
|
|
65
|
+
class from an icon set such as `@codenhub/icons`. See
|
|
66
|
+
`docs/internal/model.md#input-group-owns-the-box-the-control-inside-gives-it-up`. */
|
|
75
67
|
@utility alert-icon {
|
|
76
68
|
@apply inline-flex flex-none items-center justify-center;
|
|
77
69
|
|
|
78
|
-
/*
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
70
|
+
/* A `@codenhub/icons` glyph sizes itself in an unlayered rule, which no
|
|
71
|
+
layered rule outranks whatever its specificity, but it reads its size from
|
|
72
|
+
`--ic-size`, so the size goes there as well as on the box for any other
|
|
73
|
+
icon. No `!important`: that would shut out the consumer's own resize too.
|
|
74
|
+
An icon set with another prefix, or one that sizes unlayered with no knob,
|
|
75
|
+
keeps its own size. */
|
|
76
|
+
--ic-size: 1.25rem;
|
|
77
|
+
|
|
78
|
+
width: 1.25rem;
|
|
79
|
+
height: 1.25rem;
|
|
85
80
|
}
|
|
86
81
|
|
|
87
82
|
/* A soft, edgeless chip. Small enough that the structural silhouette would be
|
|
@@ -111,10 +106,7 @@
|
|
|
111
106
|
|
|
112
107
|
/* An indicator reads intent and no presentation token at all. It is a stand-in
|
|
113
108
|
for content rather than a box with a look of its own, so there is nothing for
|
|
114
|
-
a container's `.solid` or `.edgeless` to say about it
|
|
115
|
-
removes the visibility floor that used to fight `--ui-fill` for control of the
|
|
116
|
-
base tone, and the transparent border that only ever appeared if something up
|
|
117
|
-
the tree asked for an edge. */
|
|
109
|
+
a container's `.solid` or `.edgeless` to say about it. */
|
|
118
110
|
@utility skeleton {
|
|
119
111
|
--skeleton-base: color-mix(in oklab, var(--intent-color) 6%, var(--intent-subtle));
|
|
120
112
|
--skeleton-sheen: color-mix(in oklab, var(--intent-color) 10%, var(--color-foreground));
|
|
@@ -133,15 +125,21 @@
|
|
|
133
125
|
calc(var(--_corner) * var(--ui-corner-br, 1)) calc(var(--_corner) * var(--ui-corner-bl, 1))
|
|
134
126
|
);
|
|
135
127
|
corner-shape: var(--ui-corner-shape, round);
|
|
128
|
+
|
|
129
|
+
/* Reduced motion stops the shimmer here, for the entries without the reset;
|
|
130
|
+
see `box.css`. The gradient stays, so the placeholder still reads. */
|
|
131
|
+
@media (prefers-reduced-motion: reduce) {
|
|
132
|
+
animation: none;
|
|
133
|
+
}
|
|
136
134
|
}
|
|
137
135
|
|
|
138
136
|
/* The track is a box, the fill is not: `box.css`'s formula composes the frame,
|
|
139
137
|
the value fill stays `--intent-color` at full strength with no presentation,
|
|
140
|
-
same contract as `.
|
|
138
|
+
same contract as `.skeleton`. `.progress` cannot `@apply box`
|
|
141
139
|
(the fill is a `::after`, not the element's own background), so it hand-
|
|
142
140
|
reimplements the formula the way `.quote` does -- see
|
|
143
141
|
docs/internal/model.md#components-that-do-not-take-the-whole-of-box for the
|
|
144
|
-
decision and why the other
|
|
142
|
+
decision and why the other two indicators do not get the same treatment. */
|
|
145
143
|
@utility progress {
|
|
146
144
|
--_d-fill: 12%;
|
|
147
145
|
--_d-fg-on-fill: 0%;
|
|
@@ -161,17 +159,16 @@
|
|
|
161
159
|
not `.pre`/`.code`/`.kbd`'s opaque `--intent-subtle` ground. */
|
|
162
160
|
--_progress-surface: color-mix(in oklab, var(--intent-color) var(--_progress-fill), transparent);
|
|
163
161
|
/* One `color-mix()`, not `box`/`.quote`'s two chained through a `--_line`
|
|
164
|
-
step: a WebKit build
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
is indistinguishable from blending through the surface first. */
|
|
162
|
+
step: a WebKit build destabilizes when composing dozens of tracks each
|
|
163
|
+
carrying a three-level color-mix chain into one page (fine at ten, a
|
|
164
|
+
~30-minute CI hang at forty; only chain depth reproduces it).
|
|
165
|
+
`box`/`.quote`'s extra step blends the line toward the fill first so a
|
|
166
|
+
heavily filled box does not draw a ring of a different colour around its
|
|
167
|
+
own plate -- a real risk up to `.solid`'s 100% fill. `.progress` never
|
|
168
|
+
reaches that: `.solid` is unsupported here (`registry.json`), so the fill
|
|
169
|
+
this reads never exceeds `.soft`'s 12%, and mixing straight from
|
|
170
|
+
`--intent-border` at that fill is indistinguishable from blending through
|
|
171
|
+
the surface first. */
|
|
175
172
|
--_progress-edge: color-mix(in oklab, var(--intent-border) var(--ui-border, var(--_d-border)), transparent);
|
|
176
173
|
|
|
177
174
|
@apply relative h-2.5 w-full overflow-hidden;
|
|
@@ -213,13 +210,19 @@
|
|
|
213
210
|
&.indeterminate::after {
|
|
214
211
|
width: 33%;
|
|
215
212
|
animation: anim-progress-indeterminate 1.5s infinite ease-in-out;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* Reduced motion, for the entries without the reset; see `box.css`. The
|
|
216
|
+
value moves without sliding, and the shimmer and the indeterminate sweep
|
|
217
|
+
stop where the reset would stop them: the fill rests at the start. */
|
|
218
|
+
@media (prefers-reduced-motion: reduce) {
|
|
219
|
+
&::after {
|
|
220
|
+
transition-duration: 0.01ms;
|
|
221
|
+
}
|
|
220
222
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
+
&.active::before,
|
|
224
|
+
&.indeterminate::after {
|
|
225
|
+
animation: none;
|
|
223
226
|
}
|
|
224
227
|
}
|
|
225
228
|
}
|