@codenhub/styles 0.3.0 → 0.5.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.md +1 -1
- package/dist/aesthetics/chunky-tile.css +1 -1
- package/dist/aesthetics/cyber.css +1 -0
- 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 -0
- package/dist/components.css +1 -1
- package/dist/index.css +1 -1
- package/dist/native.css +1 -1
- package/dist/palette.css +1 -1
- package/dist/theme.css +1 -1
- package/dist/tw/aesthetics/chunky-tile.css +198 -111
- package/dist/tw/aesthetics/cyber.css +227 -0
- package/dist/tw/aesthetics/glass.css +134 -47
- package/dist/tw/aesthetics/index.css +2 -0
- package/dist/tw/aesthetics/neobrutalism.css +149 -49
- package/dist/tw/aesthetics/pixel.css +151 -63
- package/dist/tw/aesthetics/sketch.css +326 -0
- package/dist/tw/box.css +107 -35
- package/dist/tw/components/button.css +40 -19
- package/dist/tw/components/feedback.css +38 -15
- package/dist/tw/components/form.css +161 -154
- package/dist/tw/components/index.css +15 -3
- package/dist/tw/components/loader.css +34 -25
- package/dist/tw/components/surface.css +28 -71
- package/dist/tw/components/tooltip.css +20 -10
- package/dist/tw/corner.css +26 -0
- package/dist/tw/elevation.css +8 -9
- package/dist/tw/intent.css +17 -9
- package/dist/tw/native.css +45 -39
- package/dist/tw/palette.css +452 -446
- package/dist/tw/presentation.css +9 -4
- package/dist/tw/surface.css +62 -0
- package/dist/tw/theme.css +106 -75
- package/dist/tw/utilities/content.css +25 -16
- package/dist/tw/utilities/layout.css +2 -2
- package/docs/accessibility.md +16 -16
- package/docs/changelog/0.4.0.md +12 -0
- package/docs/changelog/0.5.0.md +38 -0
- package/docs/changelog/index.md +2 -0
- package/docs/concepts.md +5 -5
- package/docs/index.md +3 -3
- package/docs/setup.md +23 -3
- package/docs/usage/aesthetics.md +119 -2
- package/docs/usage/buttons.md +13 -13
- package/docs/usage/composing.md +11 -11
- package/docs/usage/content-and-layout.md +13 -13
- package/docs/usage/customizing.md +97 -44
- package/docs/usage/feedback.md +1 -1
- package/docs/usage/forms.md +11 -11
- package/docs/usage/theming.md +1 -1
- package/llms-full.txt +359 -122
- package/package.json +22 -2
package/dist/tw/box.css
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
@reference "tailwindcss";
|
|
2
|
-
|
|
3
1
|
/* How a box is painted, in one place: intent supplies the colour, presentation
|
|
4
2
|
how much of it, the aesthetic the material, and this composes the three. It
|
|
5
3
|
composes here, not on a container, because a custom property resolves its
|
|
@@ -16,14 +14,15 @@
|
|
|
16
14
|
|
|
17
15
|
`--_fill-cap` is the matching slot for a component that reinterprets what a
|
|
18
16
|
presentation means for itself rather than merely bounding it -- `.card.soft`
|
|
19
|
-
uses it to rest at 0% regardless of what `.soft` asks for. It
|
|
20
|
-
separate term rather than a
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
a
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
uses it to rest at 0% regardless of what `.soft` asks for. It is a
|
|
18
|
+
separate term rather than a write of `--ui-fill`, for two reasons. A
|
|
19
|
+
component writing `--ui-fill` from `utilities` would beat a consumer's own
|
|
20
|
+
`[--ui-fill:...]` utility, which the layer map reserves for state
|
|
21
|
+
(docs/internal/model.md#cascade-layers); a private competes with nothing a
|
|
22
|
+
consumer writes. And `--ui-fill` cascades by design, so a neutral panel
|
|
23
|
+
writing `0%` would turn every badge and button inside it ghost, where a
|
|
24
|
+
cap bounds the component and stops there (below). A state that means the
|
|
25
|
+
fill it names -- `:checked` -- writes `--ui-fill` itself.
|
|
27
26
|
|
|
28
27
|
Restated here at `100%` -- a no-op -- for the same reason `--_d-ground`
|
|
29
28
|
is restated `transparent` below rather than left to its `var()` fallback:
|
|
@@ -68,14 +67,20 @@
|
|
|
68
67
|
a capped intent -- rather than being bent so neutral's contrast is the ink,
|
|
69
68
|
which rendered a checked neutral checkbox black-on-black. */
|
|
70
69
|
--_fg: color-mix(in oklab, var(--intent-contrast) var(--_on-fill), var(--intent-strong));
|
|
71
|
-
/* P3: the line
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
ring.
|
|
78
|
-
|
|
70
|
+
/* 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 already
|
|
72
|
+
runs under the border (nothing here clips the background to the padding
|
|
73
|
+
box), so a line blended toward `--_bg` painted the plate a second time over
|
|
74
|
+
itself. On an opaque plate that is invisible; on a translucent one -- a
|
|
75
|
+
neutral fill, capped at 20%, or any fill `--ui-bg-alpha` thins -- it drew a
|
|
76
|
+
ring around the box, 1.54:1 against its own plate in light. Faded toward
|
|
77
|
+
nothing, the border shows the one coat beneath it.
|
|
78
|
+
|
|
79
|
+
Blend first, amount after (`--_edge-amount` below) -- the other order lands
|
|
80
|
+
`.edgeless` on the fill colour, which the border box then paints as a second
|
|
81
|
+
coat: a ring around an element that asked for no edge. See
|
|
82
|
+
docs/internal/model.md#presentation. */
|
|
83
|
+
--_line: color-mix(in oklab, transparent var(--ui-fill, var(--_d-fill)), var(--intent-border));
|
|
79
84
|
/* How much line there is, as an input rather than a result. A component that
|
|
80
85
|
must keep its line whatever the edge class says raises `--_edge-floor`
|
|
81
86
|
instead of rewriting `--_edge`, and the composition above still runs.
|
|
@@ -95,14 +100,30 @@
|
|
|
95
100
|
draws. Zero lengths are written `0px` because `calc(0 * 1)` yields a number
|
|
96
101
|
and a shadow position needs a length. */
|
|
97
102
|
--_elevation: var(--ui-elevation, var(--_d-elevation, 1));
|
|
98
|
-
|
|
103
|
+
|
|
104
|
+
/* The size step, a unitless multiplier the size and padding modifiers publish
|
|
105
|
+
as two privates -- `.sm`/`.p-sm` 0.75, `.p-xs` 0.5, `.lg`/`.p-lg` 1.25 --
|
|
106
|
+
so that when both sit on one element the tighter wins: `.lg.p-xs` is
|
|
107
|
+
small. An unset step takes the other's value, so a lone `.lg` still grows.
|
|
108
|
+
Restated `initial` here, before any modifier, because a custom property
|
|
109
|
+
inherits and a `.card.p-xs` would otherwise shrink every button inside it;
|
|
110
|
+
the modifier rules outrank this one on specificity. `--ui-scale` is the
|
|
111
|
+
public override, undeclared by the package. See docs/internal/model.md#material-tokens. */
|
|
112
|
+
--_scale-size: initial;
|
|
113
|
+
--_scale-pad: initial;
|
|
114
|
+
--_scale: var(--ui-scale, min(var(--_scale-size, var(--_scale-pad, 1)), var(--_scale-pad, var(--_scale-size, 1))));
|
|
115
|
+
/* Depth follows the step down and not up: a 4px slab under a 20px button
|
|
116
|
+
swallows it, while a press that travels the aesthetic's whole depth has to
|
|
117
|
+
land flat on a `.lg` button too. */
|
|
118
|
+
--_depth: calc(var(--_elevation) * min(1, var(--_scale)));
|
|
119
|
+
--_sx: calc(var(--ui-shadow-x, var(--_d-shadow-x, 0px)) * var(--_depth));
|
|
99
120
|
/* Three slots, most specific first: the aesthetic, then a component that draws
|
|
100
121
|
its own depth, then the plain step `.raised`/`.floating` supply on a page
|
|
101
122
|
with no aesthetic. The order lets a raised card under `.neobrutalism` keep
|
|
102
123
|
the slab. Nothing declares the last slot until something asks for depth, so
|
|
103
124
|
a plain unmodified page has no shadow anywhere. */
|
|
104
|
-
--_sy: calc(var(--ui-shadow-y, var(--_d-shadow-y, var(--elevation-y, 0px))) * var(--
|
|
105
|
-
--_sb: calc(var(--ui-shadow-blur, var(--_d-shadow-blur, var(--elevation-blur, 0px))) * var(--
|
|
125
|
+
--_sy: calc(var(--ui-shadow-y, var(--_d-shadow-y, var(--elevation-y, 0px))) * var(--_depth));
|
|
126
|
+
--_sb: calc(var(--ui-shadow-blur, var(--_d-shadow-blur, var(--elevation-blur, 0px))) * var(--_depth));
|
|
106
127
|
/* Spread is deliberately not scaled. An aesthetic that draws its edge as an
|
|
107
128
|
inset ring spends spread on it, and scaling that by elevation would erase
|
|
108
129
|
the edge of every component the registry rests at zero. Elevation is depth:
|
|
@@ -130,13 +151,23 @@
|
|
|
130
151
|
--_edge-shadow-color: var(--ui-shadow-edge) var(--_edge);
|
|
131
152
|
--_shadow-color: var(--_edge-shadow-color, var(--_depth-color));
|
|
132
153
|
--_shadow-parts: var(--ui-shadow-inset,) var(--_sx) var(--_sy) var(--_sb) var(--_ss) var(--_shadow-color);
|
|
154
|
+
/* A shadow that is not depth: light in the element's own intent colour, with
|
|
155
|
+
no offset. Outside the depth layer, and not scaled by elevation, so `.flat`
|
|
156
|
+
leaves it alone and a field resting at zero still takes it. Present only
|
|
157
|
+
when `--ui-halo-ink` is declared: undeclared, the whole layer, leading
|
|
158
|
+
comma included, is invalid at computed-value time and `var()` drops it, so
|
|
159
|
+
no empty layer sits in every box's shadow. */
|
|
160
|
+
--_halo-layer:
|
|
161
|
+
,
|
|
162
|
+
0 0 var(--ui-halo-blur, 0px) var(--ui-halo-spread, 0px)
|
|
163
|
+
color-mix(in oklab, var(--intent-border) var(--ui-halo-ink), transparent);
|
|
133
164
|
/* Indirection so a component can substitute a complete value of its own
|
|
134
165
|
without restating the parts -- `surface` does, for the multi-layer case.
|
|
135
166
|
There is deliberately no `--ui-shadow` wrapper: a complete value has nothing
|
|
136
167
|
for the elevation multiplier to reach, so `.flat` would silently stop working
|
|
137
168
|
on anything that set one. `--ui-surface-shadow` is that escape hatch narrowed
|
|
138
169
|
to the single case that needs it. */
|
|
139
|
-
--_shadow: var(--_shadow-parts);
|
|
170
|
+
--_shadow: var(--_shadow-parts) var(--_halo-layer,);
|
|
140
171
|
--_focus-stack: var(--_shadow), inset 0 0 0 var(--ui-focus-inset) var(--focus-ring);
|
|
141
172
|
|
|
142
173
|
/* Every box sizes itself as `min-height`/`min-width: var(--control-height)`
|
|
@@ -151,17 +182,44 @@
|
|
|
151
182
|
box-sizing: border-box;
|
|
152
183
|
background-color: var(--_bg);
|
|
153
184
|
color: var(--_fg);
|
|
154
|
-
|
|
155
|
-
|
|
185
|
+
/* The line's style is material: `solid`, `dashed`, `dotted`, or `double`,
|
|
186
|
+
which needs a width of 3px or more to draw two lines. It keeps the line's
|
|
187
|
+
colour, so its contrast, whatever it draws. */
|
|
188
|
+
border: var(--_width) var(--ui-line-style, solid) var(--_edge);
|
|
189
|
+
/* The corner is the aesthetic's length at scale 1 times the size step, so a
|
|
190
|
+
small button takes a small corner and a cut stays a true 45 degrees. Each
|
|
191
|
+
corner then multiplies by its own `--ui-corner-tl`/`-tr`/`-br`/`-bl`, 0 or
|
|
192
|
+
1, which is how `.cut-diagonal` and a bevelling aesthetic's diagonal draw
|
|
193
|
+
two corners and leave two square. An explicit `--ui-radius` still wins,
|
|
194
|
+
taken as written. */
|
|
195
|
+
--_corner: calc(var(--ui-corner, var(--radius-control)) * var(--_scale));
|
|
196
|
+
border-radius: var(
|
|
197
|
+
--ui-radius,
|
|
198
|
+
calc(var(--_corner) * var(--ui-corner-tl, 1)) calc(var(--_corner) * var(--ui-corner-tr, 1))
|
|
199
|
+
calc(var(--_corner) * var(--ui-corner-br, 1)) calc(var(--_corner) * var(--ui-corner-bl, 1))
|
|
200
|
+
);
|
|
201
|
+
/* What the radius draws: a round arc by default, a straight cut under an
|
|
202
|
+
aesthetic that bevels (`.cyber`). `round` is the property's initial value,
|
|
203
|
+
so with no aesthetic in scope this is a no-op, and an engine without
|
|
204
|
+
`corner-shape` drops the line at parse time. A component that overrides the
|
|
205
|
+
radius after `@apply box` keeps this, so it bevels by the same amount it
|
|
206
|
+
rounds. See model.md#material-tokens. */
|
|
207
|
+
corner-shape: var(--ui-corner-shape, round);
|
|
156
208
|
box-shadow: var(--_shadow);
|
|
157
209
|
clip-path: var(--ui-clip, none);
|
|
210
|
+
/* The press travel `box-active` writes; `none` at rest, because any other
|
|
211
|
+
`translate` makes the box a stacking context and a containing block.
|
|
212
|
+
Restated here so a pressed card does not carry the boxes inside it. */
|
|
213
|
+
--_press: none;
|
|
214
|
+
translate: var(--_press);
|
|
158
215
|
transition:
|
|
159
216
|
background-color var(--motion-duration-normal) var(--motion-ease),
|
|
160
217
|
border-color var(--motion-duration-normal) var(--motion-ease),
|
|
161
218
|
box-shadow var(--motion-duration-normal) var(--motion-ease),
|
|
162
219
|
color var(--motion-duration-normal) var(--motion-ease),
|
|
163
220
|
opacity var(--motion-duration-normal) var(--motion-ease),
|
|
164
|
-
transform var(--motion-duration-normal) var(--motion-ease)
|
|
221
|
+
transform var(--motion-duration-normal) var(--motion-ease),
|
|
222
|
+
translate var(--motion-duration-normal) var(--motion-ease);
|
|
165
223
|
|
|
166
224
|
/* An aesthetic that clips cannot show the global focus outline, so it declares
|
|
167
225
|
`--ui-focus-inset` and gets an inset layer instead. With no such aesthetic
|
|
@@ -197,14 +255,13 @@
|
|
|
197
255
|
@utility box-hover {
|
|
198
256
|
&:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]):hover {
|
|
199
257
|
--_bg: color-mix(in oklab, var(--intent-hover) var(--_hover-fill), var(--_d-ground, transparent));
|
|
200
|
-
/* P3 again, against the hover tone
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
--
|
|
205
|
-
--_sx: calc(var(--ui-hover-shadow-x, var(--ui-shadow-x, var(--_d-shadow-x, 0px))) * var(--_elevation));
|
|
258
|
+
/* P3 again, against the hover tone: the line still fades as the fill fills
|
|
259
|
+
in, but toward the hover ink. Without this the edge keeps the resting ink
|
|
260
|
+
-- a ring of the colour the box just left. */
|
|
261
|
+
--_line: color-mix(in oklab, transparent var(--ui-fill, var(--_d-fill)), var(--intent-hover));
|
|
262
|
+
--_sx: calc(var(--ui-hover-shadow-x, var(--ui-shadow-x, var(--_d-shadow-x, 0px))) * var(--_depth));
|
|
206
263
|
--_sy: calc(
|
|
207
|
-
var(--ui-hover-shadow-y, var(--ui-shadow-y, var(--_d-shadow-y, var(--elevation-y, 0px)))) * var(--
|
|
264
|
+
var(--ui-hover-shadow-y, var(--ui-shadow-y, var(--_d-shadow-y, var(--elevation-y, 0px)))) * var(--_depth)
|
|
208
265
|
);
|
|
209
266
|
|
|
210
267
|
transform: var(--ui-hover-transform, none);
|
|
@@ -217,11 +274,26 @@
|
|
|
217
274
|
aesthetic's -- neobrutalism travels into its offset shadow, chunky-tile drops
|
|
218
275
|
onto its bar -- and with no aesthetic it is the base `scale(0.97)` from
|
|
219
276
|
`theme.css`, dropped under reduced motion. The `--ui-active-shadow-*` slots
|
|
220
|
-
stay no-ops until an aesthetic sets them.
|
|
277
|
+
stay no-ops until an aesthetic sets them.
|
|
278
|
+
|
|
279
|
+
A press that travels into the element's own depth is a translation, given as
|
|
280
|
+
`--ui-active-translate-x`/`-y` and scaled by `--_depth` like the shadow it
|
|
281
|
+
travels into, so a `.p-xs` button that sits on half the slab moves half as
|
|
282
|
+
far, a `.floating` one twice as far, and a `.flat` one, with no slab to land
|
|
283
|
+
on, not at all. It is the independent `translate` property, so it composes
|
|
284
|
+
with `--ui-active-transform` rather than replacing it.
|
|
285
|
+
|
|
286
|
+
The press writes only `--_press`, and `box` declares `translate` from it.
|
|
287
|
+
A `translate` declaration here sorts this rule ahead of `box-hover`'s -- the
|
|
288
|
+
property ranks before `transform` in Tailwind's order -- and the hovered
|
|
289
|
+
`transform: none` then beats every press. */
|
|
221
290
|
@utility box-active {
|
|
222
291
|
&:active:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]) {
|
|
223
|
-
--_sx: calc(var(--ui-active-shadow-x, var(--ui-shadow-x, var(--_d-shadow-x, 0px))) * var(--
|
|
224
|
-
--_sy: calc(var(--ui-active-shadow-y, var(--ui-shadow-y, var(--_d-shadow-y, 0px))) * var(--
|
|
292
|
+
--_sx: calc(var(--ui-active-shadow-x, var(--ui-shadow-x, var(--_d-shadow-x, 0px))) * var(--_depth));
|
|
293
|
+
--_sy: calc(var(--ui-active-shadow-y, var(--ui-shadow-y, var(--_d-shadow-y, 0px))) * var(--_depth));
|
|
294
|
+
|
|
295
|
+
--_press: calc(var(--ui-active-translate-x, 0px) * var(--_depth))
|
|
296
|
+
calc(var(--ui-active-translate-y, 0px) * var(--_depth));
|
|
225
297
|
|
|
226
298
|
transform: var(--ui-active-transform, none);
|
|
227
299
|
}
|
|
@@ -14,16 +14,34 @@
|
|
|
14
14
|
--_d-border: 0%;
|
|
15
15
|
--_d-elevation: 1;
|
|
16
16
|
|
|
17
|
-
@apply box box-hover box-active relative inline-flex w-fit cursor-pointer items-center justify-center gap-2 px-4 py-2
|
|
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 label is material, shared with `.badge`: weight, tracking, case, and a
|
|
21
|
+
text shadow, set by an aesthetic as tokens (`.chunky-tile`'s heavier,
|
|
22
|
+
tracked label), and a consumer's own `font-*`, `tracking-*`, `uppercase`, or
|
|
23
|
+
text-shadow utility still beats the aesthetic. Tracking has no fallback on
|
|
24
|
+
purpose: undefined, the declaration is invalid at computed-value time and
|
|
25
|
+
`letter-spacing` inherits, which is what it did before the slot existed.
|
|
26
|
+
Case and shadow fall back to `none`, which is what a button already does:
|
|
27
|
+
the user agent stops both inheriting into one. The shadow is written
|
|
28
|
+
without a colour, so it takes the label's own and cannot lower its
|
|
29
|
+
contrast. See docs/internal/model.md#cascade-layers. */
|
|
30
|
+
font-weight: var(--ui-label-weight, var(--font-weight-semibold));
|
|
31
|
+
letter-spacing: var(--ui-label-tracking);
|
|
32
|
+
text-transform: var(--ui-label-case, none);
|
|
33
|
+
text-shadow: var(--ui-label-shadow, none);
|
|
20
34
|
|
|
21
35
|
&.sm {
|
|
22
36
|
@apply min-h-8 px-3 py-1 text-sm;
|
|
37
|
+
|
|
38
|
+
--_scale-size: 0.75;
|
|
23
39
|
}
|
|
24
40
|
|
|
25
41
|
&.lg {
|
|
26
42
|
@apply min-h-12 px-5 py-2.5 text-[1.0625rem];
|
|
43
|
+
|
|
44
|
+
--_scale-size: 1.25;
|
|
27
45
|
}
|
|
28
46
|
|
|
29
47
|
&.icon {
|
|
@@ -32,27 +50,25 @@
|
|
|
32
50
|
min-width: var(--control-height);
|
|
33
51
|
}
|
|
34
52
|
|
|
35
|
-
/*
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
are already the size modifier's class names, so `p-` prefixes here to
|
|
40
|
-
avoid colliding with a button's own size. `.p-xs` is the tightest step,
|
|
41
|
-
below `.compact`: a chip-sized button in a toolbar or a table cell.
|
|
53
|
+
/* Bare `sm`/`lg` are already the size modifier's class names, so `p-`
|
|
54
|
+
prefixes here to avoid colliding with a button's own size. `.p-xs` is the
|
|
55
|
+
tightest step, below `.p-sm`: a chip-sized button in a toolbar or a table
|
|
56
|
+
cell.
|
|
42
57
|
|
|
43
58
|
`.icon` drops both floors -- `min-width` from its own base rule below and
|
|
44
59
|
`min-height` from `--control-height` -- at every padding tier, labeled
|
|
45
|
-
buttons keep the height floor everywhere but `.p-xs
|
|
60
|
+
buttons keep the height floor everywhere but `.p-xs`. `.icon`
|
|
46
61
|
already asks to be square: `aspect-square` ties its width to whatever
|
|
47
62
|
height it lands on, so a height floor that survives keeps the button
|
|
48
63
|
bigger than its own glyph regardless of how tight the padding asked to be
|
|
49
|
-
-- the one combination `.p-xs
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
&.p-xs
|
|
53
|
-
&.dense {
|
|
64
|
+
-- the one combination `.p-xs` used to get right and the other two tiers
|
|
65
|
+
did not, leaving a `.icon.p-sm` floating in a box far bigger than it
|
|
66
|
+
needed and a `.icon.p-lg` doing the same one step further out. */
|
|
67
|
+
&.p-xs {
|
|
54
68
|
@apply px-2 py-0.5;
|
|
55
69
|
|
|
70
|
+
--_scale-pad: 0.5;
|
|
71
|
+
|
|
56
72
|
/* The one padding step that also drops the size floor for a labeled
|
|
57
73
|
button. At this tier the button is a chip in a toolbar or a table
|
|
58
74
|
cell, where `--control-height` is taller than the row it sits in;
|
|
@@ -67,10 +83,11 @@
|
|
|
67
83
|
}
|
|
68
84
|
}
|
|
69
85
|
|
|
70
|
-
&.p-sm
|
|
71
|
-
&.compact {
|
|
86
|
+
&.p-sm {
|
|
72
87
|
@apply px-2.5 py-1;
|
|
73
88
|
|
|
89
|
+
--_scale-pad: 0.75;
|
|
90
|
+
|
|
74
91
|
&.icon {
|
|
75
92
|
@apply p-1;
|
|
76
93
|
|
|
@@ -79,10 +96,11 @@
|
|
|
79
96
|
}
|
|
80
97
|
}
|
|
81
98
|
|
|
82
|
-
&.p-lg
|
|
83
|
-
&.spacious {
|
|
99
|
+
&.p-lg {
|
|
84
100
|
@apply px-6 py-3;
|
|
85
101
|
|
|
102
|
+
--_scale-pad: 1.25;
|
|
103
|
+
|
|
86
104
|
&.icon {
|
|
87
105
|
@apply p-3;
|
|
88
106
|
|
|
@@ -91,7 +109,10 @@
|
|
|
91
109
|
}
|
|
92
110
|
}
|
|
93
111
|
|
|
112
|
+
/* A pill normally takes the round material ahead of the box radius. Sketch
|
|
113
|
+
gives this token the button's own box outline; a bevel still cuts the full
|
|
114
|
+
radius to points under cyber. */
|
|
94
115
|
&.pill {
|
|
95
|
-
|
|
116
|
+
border-radius: var(--ui-radius-pill, calc(infinity * 1px));
|
|
96
117
|
}
|
|
97
118
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
@reference "tailwindcss";
|
|
2
2
|
@import "../theme.css";
|
|
3
3
|
@reference "../box.css";
|
|
4
|
-
@reference "
|
|
4
|
+
@reference "../surface.css";
|
|
5
5
|
|
|
6
6
|
@keyframes anim-skeleton {
|
|
7
7
|
0% {
|
|
@@ -49,16 +49,17 @@
|
|
|
49
49
|
plus `.solid`/`.ghost` so an explicit presentation on the element is
|
|
50
50
|
never clamped to a cap it did not ask for.
|
|
51
51
|
|
|
52
|
-
Grounds on `--color-foreground` through
|
|
53
|
-
|
|
52
|
+
Grounds on `--color-foreground` through `--_d-surface-ground`, exactly
|
|
53
|
+
like `.panel` and a resting `.card.soft`, so glass's ground and a
|
|
54
|
+
consumer's `--ui-surface-ground` still win over it -- an
|
|
54
55
|
alert has no hover state to reveal a tint into either, so this is
|
|
55
56
|
permanent rather than revealed. Unlike a neutral panel or badge, an
|
|
56
57
|
alert cannot lose its visual identity from this: `--_d-border: 100%`
|
|
57
58
|
above holds regardless of fill, so a neutral alert still reads as a
|
|
58
59
|
framed box, just a quiet one instead of a grey slab. */
|
|
59
|
-
&:not(.primary, .secondary, .success, .warning, .destructive, .
|
|
60
|
+
&:not(.primary, .secondary, .success, .warning, .destructive, .info, .solid, .ghost) {
|
|
60
61
|
--_fill-cap: 0%;
|
|
61
|
-
--
|
|
62
|
+
--_d-surface-ground: var(--color-foreground);
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
|
|
@@ -91,11 +92,20 @@
|
|
|
91
92
|
--_d-border: 0%;
|
|
92
93
|
--_d-elevation: 0;
|
|
93
94
|
|
|
94
|
-
@apply box inline-flex min-h-6 w-fit items-center gap-1 px-2.5 text-xs
|
|
95
|
+
@apply box inline-flex min-h-6 w-fit items-center gap-1 px-2.5 text-xs;
|
|
96
|
+
|
|
97
|
+
/* The label material `.btn` reads. Unset, tracking, case, and shadow inherit,
|
|
98
|
+
as a badge's text always has. */
|
|
99
|
+
font-weight: var(--ui-label-weight, var(--font-weight-bold));
|
|
100
|
+
letter-spacing: var(--ui-label-tracking);
|
|
101
|
+
text-transform: var(--ui-label-case);
|
|
102
|
+
text-shadow: var(--ui-label-shadow);
|
|
95
103
|
|
|
96
104
|
/* Pill by default, but an aesthetic that declares no radius has to mean it, so
|
|
97
|
-
the round corner is this component's fallback rather than a hardcoded value.
|
|
98
|
-
|
|
105
|
+
the round corner is this component's fallback rather than a hardcoded value.
|
|
106
|
+
An aesthetic that keeps pills distinct from its control corner says so
|
|
107
|
+
through `--ui-radius-pill` first. */
|
|
108
|
+
border-radius: var(--ui-radius-pill, var(--ui-radius, var(--ui-corner, calc(infinity * 1px))));
|
|
99
109
|
clip-path: var(--ui-clip-tight, var(--ui-clip, none));
|
|
100
110
|
}
|
|
101
111
|
|
|
@@ -114,7 +124,15 @@
|
|
|
114
124
|
animation: anim-skeleton calc(var(--motion-duration-slow) * 4) linear infinite;
|
|
115
125
|
background: linear-gradient(90deg, var(--skeleton-base), var(--skeleton-sheen), var(--skeleton-base));
|
|
116
126
|
background-size: 200% 100%;
|
|
117
|
-
|
|
127
|
+
/* Not a box, so it draws the control corner and its pattern itself, the way
|
|
128
|
+
`box` does at scale 1, and reads the corner shape beside it. */
|
|
129
|
+
--_corner: var(--ui-corner, var(--radius-control));
|
|
130
|
+
border-radius: var(
|
|
131
|
+
--ui-radius,
|
|
132
|
+
calc(var(--_corner) * var(--ui-corner-tl, 1)) calc(var(--_corner) * var(--ui-corner-tr, 1))
|
|
133
|
+
calc(var(--_corner) * var(--ui-corner-br, 1)) calc(var(--_corner) * var(--ui-corner-bl, 1))
|
|
134
|
+
);
|
|
135
|
+
corner-shape: var(--ui-corner-shape, round);
|
|
118
136
|
}
|
|
119
137
|
|
|
120
138
|
/* The track is a box, the fill is not: `box.css`'s formula composes the frame,
|
|
@@ -122,8 +140,8 @@
|
|
|
122
140
|
same contract as `.loader`/`.skeleton`. `.progress` cannot `@apply box`
|
|
123
141
|
(the fill is a `::after`, not the element's own background), so it hand-
|
|
124
142
|
reimplements the formula the way `.quote` does -- see
|
|
125
|
-
docs/internal/
|
|
126
|
-
other three indicators do not get the same treatment. */
|
|
143
|
+
docs/internal/model.md#components-that-do-not-take-the-whole-of-box for the
|
|
144
|
+
decision and why the other three indicators do not get the same treatment. */
|
|
127
145
|
@utility progress {
|
|
128
146
|
--_d-fill: 12%;
|
|
129
147
|
--_d-fg-on-fill: 0%;
|
|
@@ -158,16 +176,21 @@
|
|
|
158
176
|
|
|
159
177
|
@apply relative h-2.5 w-full overflow-hidden;
|
|
160
178
|
background-color: var(--progress-surface, var(--_progress-surface));
|
|
161
|
-
border: var(--ui-border-width, var(--border-width))
|
|
179
|
+
border: var(--ui-border-width, var(--border-width)) var(--ui-line-style, solid)
|
|
180
|
+
var(--progress-edge, var(--_progress-edge));
|
|
162
181
|
/* Round by default; an aesthetic that declares no radius squares the track and
|
|
163
|
-
its fill together. */
|
|
164
|
-
border-radius: var(--ui-radius, calc(infinity * 1px));
|
|
182
|
+
its fill together, and a pill corner reaches both first. */
|
|
183
|
+
border-radius: var(--ui-radius-pill, var(--ui-radius, var(--ui-corner, calc(infinity * 1px))));
|
|
184
|
+
/* Not a box either, and the fill below restates it, so a bevelled track
|
|
185
|
+
carries a bevelled fill rather than a pill inside a cut frame. */
|
|
186
|
+
corner-shape: var(--ui-corner-shape, round);
|
|
165
187
|
|
|
166
188
|
&::after {
|
|
167
189
|
content: "";
|
|
168
190
|
@apply absolute start-0 top-0 bottom-0 block h-full transition-[width] duration-(--motion-duration-slow) ease-(--motion-ease);
|
|
169
191
|
|
|
170
|
-
border-radius: var(--ui-radius, calc(infinity * 1px));
|
|
192
|
+
border-radius: var(--ui-radius-pill, var(--ui-radius, var(--ui-corner, calc(infinity * 1px))));
|
|
193
|
+
corner-shape: var(--ui-corner-shape, round);
|
|
171
194
|
background-color: var(--progress-color, var(--intent-color));
|
|
172
195
|
width: var(--progress-value, 0%);
|
|
173
196
|
z-index: 2;
|