@codenhub/styles 0.7.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 -8
- package/README.md +8 -7
- package/README.pt-BR.md +9 -8
- 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/cli.js +358 -0
- package/dist/components.css +50 -2
- package/dist/index.css +50 -2
- package/dist/index.d.ts +1 -0
- package/dist/native.css +50 -2
- package/dist/palette.css +1 -1
- package/dist/purge/classes.json +1 -0
- package/dist/purge/index.css +50 -0
- package/dist/theme.css +2 -2
- package/docs/accessibility.md +46 -27
- package/docs/changelog/0.8.0.md +70 -0
- package/docs/changelog/0.9.0.md +40 -0
- package/docs/changelog/index.md +2 -0
- package/docs/es/accessibility.md +47 -28
- package/docs/es/index.md +4 -3
- package/docs/es/integrating/index.md +38 -10
- package/docs/es/integrating/tailwind.md +79 -8
- package/docs/es/integrating/without-a-bundler.md +157 -5
- package/docs/es/setup.md +43 -34
- package/docs/es/usage/aesthetics.md +20 -14
- package/docs/es/usage/buttons.md +6 -2
- package/docs/es/usage/composing.md +6 -2
- package/docs/es/usage/content-and-layout.md +10 -4
- package/docs/es/usage/customizing.md +46 -26
- package/docs/es/usage/feedback.md +5 -1
- package/docs/es/usage/forms.md +30 -5
- package/docs/es/usage/index.md +7 -3
- package/docs/es/usage/presets.md +92 -0
- package/docs/es/usage/solo.md +4 -2
- package/docs/es/usage/theming.md +29 -16
- package/docs/es/usage/tooltips.md +2 -2
- package/docs/index.md +3 -2
- package/docs/integrating/index.md +38 -10
- package/docs/integrating/tailwind.md +78 -7
- package/docs/integrating/without-a-bundler.md +156 -4
- package/docs/pt-BR/accessibility.md +47 -28
- package/docs/pt-BR/index.md +4 -3
- package/docs/pt-BR/integrating/index.md +38 -10
- package/docs/pt-BR/integrating/tailwind.md +79 -8
- package/docs/pt-BR/integrating/without-a-bundler.md +157 -5
- package/docs/pt-BR/setup.md +43 -34
- package/docs/pt-BR/usage/aesthetics.md +20 -14
- package/docs/pt-BR/usage/buttons.md +6 -2
- package/docs/pt-BR/usage/composing.md +6 -2
- package/docs/pt-BR/usage/content-and-layout.md +10 -4
- package/docs/pt-BR/usage/customizing.md +46 -26
- package/docs/pt-BR/usage/feedback.md +5 -1
- package/docs/pt-BR/usage/forms.md +30 -5
- package/docs/pt-BR/usage/index.md +7 -3
- package/docs/pt-BR/usage/presets.md +92 -0
- package/docs/pt-BR/usage/solo.md +4 -2
- package/docs/pt-BR/usage/theming.md +22 -9
- package/docs/pt-BR/usage/tooltips.md +2 -2
- package/docs/setup.md +31 -22
- package/docs/usage/aesthetics.md +19 -13
- package/docs/usage/buttons.md +5 -1
- package/docs/usage/composing.md +5 -1
- package/docs/usage/content-and-layout.md +9 -3
- package/docs/usage/customizing.md +45 -25
- package/docs/usage/feedback.md +4 -0
- package/docs/usage/forms.md +29 -4
- package/docs/usage/index.md +6 -2
- package/docs/usage/presets.md +91 -0
- package/docs/usage/solo.md +3 -1
- package/docs/usage/theming.md +21 -8
- package/docs/usage/tooltips.md +1 -1
- package/llms-full.txt +695 -134
- package/llms.txt +3 -2
- package/package.json +117 -65
- package/{dist/tw → tw}/aesthetics/chunky-tile.css +43 -20
- package/{dist/tw → tw}/aesthetics/cyber.css +19 -25
- package/{dist/tw → tw}/aesthetics/glass.css +110 -36
- package/{dist/tw → tw}/aesthetics/neobrutalism.css +41 -21
- package/{dist/tw → tw}/aesthetics/pixel.css +3 -0
- package/tw/aesthetics/sketch.css +435 -0
- package/{dist/tw → tw}/box.css +109 -26
- package/tw/components/button.css +11 -0
- package/tw/components/button.rules.css +187 -0
- package/tw/components/feedback.css +11 -0
- package/{dist/tw/components/feedback.css → tw/components/feedback.rules.css} +156 -33
- package/tw/components/form.css +11 -0
- package/{dist/tw/components/form.css → tw/components/form.rules.css} +584 -141
- package/tw/components/index.css +16 -0
- package/tw/components/rules.css +41 -0
- package/tw/components/surface.css +11 -0
- package/tw/components/surface.rules.css +225 -0
- package/tw/components/tooltip.css +11 -0
- package/{dist/tw/components/tooltip.css → tw/components/tooltip.rules.css} +82 -61
- package/{dist/tw → tw}/corner.css +18 -12
- package/{dist/tw → tw}/elevation.css +27 -21
- package/{dist/tw → tw}/index.css +11 -9
- package/tw/index.d.ts +1 -0
- package/tw/intent.css +312 -0
- package/tw/modifiers.css +127 -0
- package/tw/native.css +323 -0
- package/tw/presentation.css +139 -0
- package/tw/reset.css +10 -0
- package/{dist/tw/reset.css → tw/reset.rules.css} +7 -8
- package/tw/size.css +34 -0
- package/tw/surface.css +9 -0
- package/tw/surface.rules.css +212 -0
- package/{dist/tw → tw}/theme.css +93 -29
- package/tw/typography.css +8 -0
- package/{dist/tw/typography.css → tw/typography.rules.css} +0 -3
- package/{dist/tw → tw}/utilities/content.css +248 -108
- package/tw/utilities/index.css +11 -0
- package/tw/utilities/layout.css +210 -0
- package/tw/utilities/rules.css +8 -0
- package/dist/tw/aesthetics/sketch.css +0 -398
- package/dist/tw/components/button.css +0 -139
- package/dist/tw/components/index.css +0 -35
- package/dist/tw/components/surface.css +0 -184
- package/dist/tw/intent.css +0 -229
- package/dist/tw/native.css +0 -203
- package/dist/tw/palette.css +0 -460
- package/dist/tw/presentation.css +0 -68
- package/dist/tw/surface.css +0 -61
- package/dist/tw/utilities/index.css +0 -6
- package/dist/tw/utilities/layout.css +0 -144
- /package/{dist/tw → tw}/aesthetics/index.css +0 -0
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
/* Sketch: uneven elliptical corners, a solid ink edge, and a small hard shadow.
|
|
2
|
+
The handwriting face is consumer-supplied, so this file has no font asset or
|
|
3
|
+
network side effect. */
|
|
4
|
+
|
|
5
|
+
/* The layer map, stated before anything uses a layer -- see `theme.css`. The
|
|
6
|
+
aesthetic's token class sits in `components`, below every utility, so a
|
|
7
|
+
consumer's own utility or unlayered CSS beats it; the solo class stays
|
|
8
|
+
unlayered, because it has to beat a foreign component's unlayered CSS. See
|
|
9
|
+
docs/internal/model.md#cascade-layers. */
|
|
10
|
+
@layer theme, base, components, utilities;
|
|
11
|
+
|
|
12
|
+
@layer components {
|
|
13
|
+
.sketch {
|
|
14
|
+
/* Complete radii are taken as written, without the size step or corner
|
|
15
|
+
pattern. Chips use a smaller version of the same irregular outline.
|
|
16
|
+
Surfaces use sharp, hand-drawn square contours tailored for container
|
|
17
|
+
dimensions to avoid interior padding encroachment. Knobs follow R8. */
|
|
18
|
+
--ui-corner: initial;
|
|
19
|
+
--ui-corner-surface: initial;
|
|
20
|
+
--ui-corner-tl: initial;
|
|
21
|
+
--ui-corner-tr: initial;
|
|
22
|
+
--ui-corner-br: initial;
|
|
23
|
+
--ui-corner-bl: initial;
|
|
24
|
+
--ui-radius: var(--sketch-radius, 255px 15px 225px 15px / 15px 225px 15px 255px);
|
|
25
|
+
--ui-radius-surface: var(--sketch-radius-surface, 80px 4px 75px 5px / 3px 70px 4px 80px);
|
|
26
|
+
--ui-radius-pill: var(--sketch-radius-pill, 20px 22px 21px 19px / 20px 22px 21px 19px);
|
|
27
|
+
--ui-radius-tight: 11px 1px 7px 2px / 2px 7px 1px 11px;
|
|
28
|
+
--ui-corner-shape: round;
|
|
29
|
+
|
|
30
|
+
--ui-ink: light-dark(var(--color-neutral-950), var(--color-neutral-50));
|
|
31
|
+
/* Controls take the theme's control border rather than the ink, which is the
|
|
32
|
+
primary colour in both themes; see `neobrutalism.css`. */
|
|
33
|
+
--ui-control-ink: var(--color-control-border);
|
|
34
|
+
--ui-rule-ink: initial;
|
|
35
|
+
--ui-border-width: 1px;
|
|
36
|
+
--ui-border-max: 100px;
|
|
37
|
+
--ui-line-style: solid;
|
|
38
|
+
--ui-rule-style: initial;
|
|
39
|
+
|
|
40
|
+
--ui-shadow-ink: 0%;
|
|
41
|
+
/* The foundation depth colour is restated so a sketch region nested inside
|
|
42
|
+
cyber does not inherit cyber's transparent depth. */
|
|
43
|
+
--elevation-color: light-dark(rgb(15 23 42 / 0.08), rgb(0 0 0 / 0.55));
|
|
44
|
+
--ui-shadow-x: 2px;
|
|
45
|
+
--ui-shadow-y: 2px;
|
|
46
|
+
--ui-shadow-blur: 0px;
|
|
47
|
+
--ui-shadow-spread: 0px;
|
|
48
|
+
--ui-shadow-inset: ;
|
|
49
|
+
--ui-shadow-edge: initial;
|
|
50
|
+
--ui-halo-blur: initial;
|
|
51
|
+
--ui-halo-spread: initial;
|
|
52
|
+
--ui-halo-ink: initial;
|
|
53
|
+
--ui-focus-inset: initial;
|
|
54
|
+
|
|
55
|
+
--ui-active-shadow-x: initial;
|
|
56
|
+
--ui-active-shadow-y: initial;
|
|
57
|
+
--ui-active-transform: scale(0.97);
|
|
58
|
+
--ui-active-translate-x: initial;
|
|
59
|
+
--ui-active-translate-y: initial;
|
|
60
|
+
--ui-hover-transform: none;
|
|
61
|
+
--ui-clip: none;
|
|
62
|
+
--ui-clip-tight: none;
|
|
63
|
+
--ui-backdrop: none;
|
|
64
|
+
--ui-surface-image: initial;
|
|
65
|
+
--ui-surface-ground: initial;
|
|
66
|
+
--ui-surface-shadow: initial;
|
|
67
|
+
--ui-bg-alpha: 1;
|
|
68
|
+
--ui-label-weight: initial;
|
|
69
|
+
--ui-label-tracking: initial;
|
|
70
|
+
--ui-label-case: initial;
|
|
71
|
+
--ui-label-shadow: initial;
|
|
72
|
+
|
|
73
|
+
font-family: var(--font-sketch, cursive);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* Rounded variant: bounded elliptical corners, so the top and bottom edges of
|
|
77
|
+
a wide element stay straight instead of bulging into an egg. On the region
|
|
78
|
+
with `.sketch`, or on one component inside it. Knobs follow R8.
|
|
79
|
+
|
|
80
|
+
Never on a solo element, here or in the rotation below:
|
|
81
|
+
`.sketch-solo.sketch-rounded` paints its own outline, and a complete
|
|
82
|
+
radius declared on it would inherit into whatever it holds -- a `.btn`
|
|
83
|
+
inside a solo toast took a sketch outline on a page with no sketch in
|
|
84
|
+
scope. */
|
|
85
|
+
.sketch-rounded:not(.sketch-solo) {
|
|
86
|
+
--ui-radius: var(--sketch-radius-rounded, 26px 10px 24px 11px / 12px 23px 11px 20px);
|
|
87
|
+
--ui-radius-surface: var(--sketch-radius-surface-rounded, 38px 16px 36px 17px / 16px 34px 17px 32px);
|
|
88
|
+
--ui-radius-pill: var(--sketch-radius-pill, 24px 16px 23px 17px / 17px 21px 16px 20px);
|
|
89
|
+
--ui-radius-tight: 9px 3px 8px 4px / 4px 8px 3px 7px;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* One region token gives every element the same outline, so the rotation and
|
|
93
|
+
the dashed accents are written on components, which the registry records.
|
|
94
|
+
|
|
95
|
+
The nearest region decides. A component in another aesthetic nested inside
|
|
96
|
+
a sketch region keeps that aesthetic's material, and one in a sketch region
|
|
97
|
+
nested again inside that rotates. A `:not(.sketch :is(...) *)` exclusion
|
|
98
|
+
cannot tell those two apart, since the re-entered component also sits below
|
|
99
|
+
the other aesthetic, so each region writes private flags instead and
|
|
100
|
+
inheritance hands a component the nearest one's -- the way neobrutalism
|
|
101
|
+
rests its alert:
|
|
102
|
+
|
|
103
|
+
- `--_sketch-on`, `--_sketch-pointed`, `--_sketch-rounded` are space
|
|
104
|
+
toggles: empty is on, and `initial` makes a value reading one invalid at
|
|
105
|
+
computed-value time, which is off. `.sketch` turns on the pointed
|
|
106
|
+
outlines and `.sketch-rounded` the rounded ones; rounded wins where both
|
|
107
|
+
are on, as the modifier does. Another aesthetic turns all three off.
|
|
108
|
+
- `--_sketch-pass-*` is what that other aesthetic declared for each token
|
|
109
|
+
the rotation writes, so a component under it takes the region's value
|
|
110
|
+
back rather than a rotation's -- cyber's whole surface shape included.
|
|
111
|
+
Off, a value is the pass, then the rounded one, then the pointed one; the
|
|
112
|
+
first that is valid wins, and with none the token is unset, as every
|
|
113
|
+
other aesthetic declares it.
|
|
114
|
+
|
|
115
|
+
The other aesthetics are named below and in the flags, and
|
|
116
|
+
`registry.test.ts` fails when one is missing. A region's own element is
|
|
117
|
+
not rotated: it declares the pass from its own tokens, which a rotation
|
|
118
|
+
would then declare from the pass.
|
|
119
|
+
|
|
120
|
+
Rotation is by sibling position, and a field's control takes its field's
|
|
121
|
+
position instead of its own, so stacked rows alternate. It is stable for a
|
|
122
|
+
given DOM order. A knob, when set, is one outline for every position. */
|
|
123
|
+
.sketch,
|
|
124
|
+
.sketch-rounded:not(.sketch-solo) {
|
|
125
|
+
--_sketch-on: ;
|
|
126
|
+
--_sketch-pass-radius: initial;
|
|
127
|
+
--_sketch-pass-radius-surface: initial;
|
|
128
|
+
--_sketch-pass-radius-tight: initial;
|
|
129
|
+
--_sketch-pass-radius-pill: initial;
|
|
130
|
+
--_sketch-pass-line-style: initial;
|
|
131
|
+
--_sketch-pass-rule-style: initial;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.sketch {
|
|
135
|
+
--_sketch-pointed: ;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.sketch-rounded:not(.sketch-solo) {
|
|
139
|
+
--_sketch-rounded: ;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
:is(.neobrutalism, .glass, .pixel, .chunky-tile, .cyber) {
|
|
143
|
+
--_sketch-on: initial;
|
|
144
|
+
--_sketch-pointed: initial;
|
|
145
|
+
--_sketch-rounded: initial;
|
|
146
|
+
--_sketch-pass-radius: var(--ui-radius);
|
|
147
|
+
--_sketch-pass-radius-surface: var(--ui-radius-surface);
|
|
148
|
+
--_sketch-pass-radius-tight: var(--ui-radius-tight);
|
|
149
|
+
--_sketch-pass-radius-pill: var(--ui-radius-pill);
|
|
150
|
+
--_sketch-pass-line-style: var(--ui-line-style);
|
|
151
|
+
--_sketch-pass-rule-style: var(--ui-rule-style);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
:is(.sketch, .sketch-rounded:not(.sketch-solo), :is(.sketch, .sketch-rounded:not(.sketch-solo)) *):not(
|
|
155
|
+
:is(.neobrutalism, .glass, .pixel, .chunky-tile, .cyber)
|
|
156
|
+
) {
|
|
157
|
+
/* Controls, fields, surfaces, and chips. Each position names its pointed
|
|
158
|
+
outline in `--_sketch-p` and its rounded one in `--_sketch-r`, declared
|
|
159
|
+
with the token, so a position never reads a value inherited from an
|
|
160
|
+
ancestor's. */
|
|
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
|
+
|
|
170
|
+
&:nth-child(4n + 2) {
|
|
171
|
+
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius, 18px 240px 15px 255px / 240px 15px 255px 18px);
|
|
172
|
+
--_sketch-r: var(--_sketch-rounded) var(--sketch-radius-rounded, 11px 25px 12px 24px / 23px 11px 22px 12px);
|
|
173
|
+
--ui-radius: var(--_sketch-pass-radius, var(--_sketch-r, var(--_sketch-p)));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
&:nth-child(4n + 3) {
|
|
177
|
+
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius, 245px 220px 15px 18px / 18px 15px 245px 235px);
|
|
178
|
+
--_sketch-r: var(--_sketch-rounded) var(--sketch-radius-rounded, 24px 12px 26px 10px / 11px 23px 12px 22px);
|
|
179
|
+
--ui-radius: var(--_sketch-pass-radius, var(--_sketch-r, var(--_sketch-p)));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
&:nth-child(4n) {
|
|
183
|
+
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius, 18px 250px 225px 15px / 245px 15px 18px 235px);
|
|
184
|
+
--_sketch-r: var(--_sketch-rounded) var(--sketch-radius-rounded, 12px 24px 10px 25px / 22px 12px 23px 11px);
|
|
185
|
+
--ui-radius: var(--_sketch-pass-radius, var(--_sketch-r, var(--_sketch-p)));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
&:is(.ipt, .textarea, .select, .input-group) {
|
|
190
|
+
.field:nth-child(4n + 1) & {
|
|
191
|
+
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius, 255px 15px 225px 15px / 15px 225px 15px 255px);
|
|
192
|
+
--_sketch-r: var(--_sketch-rounded) var(--sketch-radius-rounded, 26px 10px 24px 11px / 12px 23px 11px 20px);
|
|
193
|
+
--ui-radius: var(--_sketch-pass-radius, var(--_sketch-r, var(--_sketch-p)));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.field:nth-child(4n + 2) & {
|
|
197
|
+
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius, 18px 240px 15px 255px / 240px 15px 255px 18px);
|
|
198
|
+
--_sketch-r: var(--_sketch-rounded) var(--sketch-radius-rounded, 11px 25px 12px 24px / 23px 11px 22px 12px);
|
|
199
|
+
--ui-radius: var(--_sketch-pass-radius, var(--_sketch-r, var(--_sketch-p)));
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.field:nth-child(4n + 3) & {
|
|
203
|
+
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius, 245px 220px 15px 18px / 18px 15px 245px 235px);
|
|
204
|
+
--_sketch-r: var(--_sketch-rounded) var(--sketch-radius-rounded, 24px 12px 26px 10px / 11px 23px 12px 22px);
|
|
205
|
+
--ui-radius: var(--_sketch-pass-radius, var(--_sketch-r, var(--_sketch-p)));
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.field:nth-child(4n) & {
|
|
209
|
+
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius, 18px 250px 225px 15px / 245px 15px 18px 235px);
|
|
210
|
+
--_sketch-r: var(--_sketch-rounded) var(--sketch-radius-rounded, 12px 24px 10px 25px / 22px 12px 23px 11px);
|
|
211
|
+
--ui-radius: var(--_sketch-pass-radius, var(--_sketch-r, var(--_sketch-p)));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
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
|
+
|
|
223
|
+
&:nth-child(4n + 2) {
|
|
224
|
+
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius-surface, 4px 75px 5px 80px / 75px 3px 80px 4px);
|
|
225
|
+
--_sketch-r: var(--_sketch-rounded)
|
|
226
|
+
var(--sketch-radius-surface-rounded, 17px 36px 18px 34px / 33px 16px 32px 17px);
|
|
227
|
+
--ui-radius-surface: var(--_sketch-pass-radius-surface, var(--_sketch-r, var(--_sketch-p)));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
&:nth-child(4n + 3) {
|
|
231
|
+
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius-surface, 75px 70px 4px 5px / 4px 3px 75px 70px);
|
|
232
|
+
--_sketch-r: var(--_sketch-rounded)
|
|
233
|
+
var(--sketch-radius-surface-rounded, 35px 18px 38px 15px / 17px 32px 16px 34px);
|
|
234
|
+
--ui-radius-surface: var(--_sketch-pass-radius-surface, var(--_sketch-r, var(--_sketch-p)));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
&:nth-child(4n) {
|
|
238
|
+
--_sketch-p: var(--_sketch-pointed) var(--sketch-radius-surface, 5px 80px 75px 4px / 75px 4px 5px 70px);
|
|
239
|
+
--_sketch-r: var(--_sketch-rounded)
|
|
240
|
+
var(--sketch-radius-surface-rounded, 18px 35px 16px 37px / 31px 17px 34px 16px);
|
|
241
|
+
--ui-radius-surface: var(--_sketch-pass-radius-surface, var(--_sketch-r, var(--_sketch-p)));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
&:is(.badge, .kbd, .code, .checkbox, .switch, .progress) {
|
|
246
|
+
&:nth-child(4n + 2) {
|
|
247
|
+
--_sketch-p: var(--_sketch-pointed) 2px 8px 1px 10px / 8px 2px 10px 1px;
|
|
248
|
+
--_sketch-r: var(--_sketch-rounded) 4px 8px 3px 9px / 8px 3px 8px 4px;
|
|
249
|
+
--ui-radius-tight: var(--_sketch-pass-radius-tight, var(--_sketch-r, var(--_sketch-p)));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
&:nth-child(4n + 3) {
|
|
253
|
+
--_sketch-p: var(--_sketch-pointed) 8px 2px 10px 1px / 1px 9px 2px 8px;
|
|
254
|
+
--_sketch-r: var(--_sketch-rounded) 8px 4px 9px 3px / 3px 9px 4px 8px;
|
|
255
|
+
--ui-radius-tight: var(--_sketch-pass-radius-tight, var(--_sketch-r, var(--_sketch-p)));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
&:nth-child(4n) {
|
|
259
|
+
--_sketch-p: var(--_sketch-pointed) 1px 10px 2px 7px / 9px 1px 8px 2px;
|
|
260
|
+
--_sketch-r: var(--_sketch-rounded) 3px 9px 4px 8px / 9px 4px 8px 3px;
|
|
261
|
+
--ui-radius-tight: var(--_sketch-pass-radius-tight, var(--_sketch-r, var(--_sketch-p)));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/* A pill button keeps a rounded pill in either variant, bounded to the
|
|
266
|
+
button's half-height so a wide one keeps flat top and bottom edges. */
|
|
267
|
+
&.btn.pill {
|
|
268
|
+
--ui-radius-pill: var(
|
|
269
|
+
--_sketch-pass-radius-pill,
|
|
270
|
+
var(--_sketch-on) var(--sketch-radius-pill, 24px 16px 23px 17px / 17px 21px 16px 20px)
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
&:nth-child(4n + 2) {
|
|
274
|
+
--ui-radius-pill: var(
|
|
275
|
+
--_sketch-pass-radius-pill,
|
|
276
|
+
var(--_sketch-on) var(--sketch-radius-pill, 17px 23px 16px 24px / 21px 16px 20px 17px)
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
&:nth-child(4n + 3) {
|
|
281
|
+
--ui-radius-pill: var(
|
|
282
|
+
--_sketch-pass-radius-pill,
|
|
283
|
+
var(--_sketch-on) var(--sketch-radius-pill, 23px 17px 24px 16px / 16px 20px 17px 21px)
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
&:nth-child(4n) {
|
|
288
|
+
--ui-radius-pill: var(
|
|
289
|
+
--_sketch-pass-radius-pill,
|
|
290
|
+
var(--_sketch-on) var(--sketch-radius-pill, 16px 24px 17px 23px / 20px 17px 21px 16px)
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* Badges, progress bars, and switches take their chip outline where they
|
|
296
|
+
would be fully round. */
|
|
297
|
+
&:is(.badge, .progress, .switch) {
|
|
298
|
+
--ui-radius-pill: var(--_sketch-pass-radius-pill, var(--_sketch-on) var(--ui-radius-tight));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/* Radios and the tooltip trigger stay circles, slightly uneven, so a radio
|
|
302
|
+
is never mistaken for a checkbox. */
|
|
303
|
+
&:is(.radio, .tooltip-icon) {
|
|
304
|
+
--ui-radius-pill: var(--_sketch-pass-radius-pill, var(--_sketch-on) 48% 52% 46% 54% / 53% 46% 54% 47%);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/* The dashed accents, under `.sketch`; every other line stays solid. The
|
|
308
|
+
bare elements `/native` styles as these components are named beside
|
|
309
|
+
them, in `:where()` so the selector's weight stays the class's. */
|
|
310
|
+
&:is(.checkbox, :where(input[type="checkbox"]:not(.switch, .radio))) {
|
|
311
|
+
--ui-line-style: var(--_sketch-pass-line-style, var(--_sketch-pointed) dashed);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
&:is(.divider, .data-table, :where(hr, table)) {
|
|
315
|
+
--ui-rule-style: var(--_sketch-pass-rule-style, var(--_sketch-pointed) dashed);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/* Solo: the same look painted onto the one element carrying the class, for an
|
|
321
|
+
element the package does not style. See docs/internal/model.md#solo-classes and
|
|
322
|
+
the note on `.glass-solo`: it composes with the element's presentation,
|
|
323
|
+
intent, and elevation, and reads its material from its own knobs and
|
|
324
|
+
foundation tokens with literal fallbacks, never a shared material `--ui-*`
|
|
325
|
+
or `--elevation-color` token. Unlayered, and not for this package's own
|
|
326
|
+
components. */
|
|
327
|
+
.sketch-solo {
|
|
328
|
+
/* The composition, the same in every solo class; `registry.test.ts` holds
|
|
329
|
+
the copies together. See the note on `.glass-solo`. */
|
|
330
|
+
--_solo-intent-color: initial;
|
|
331
|
+
--_solo-intent-contrast: initial;
|
|
332
|
+
--_solo-intent-strong: initial;
|
|
333
|
+
--_solo-intent-border: initial;
|
|
334
|
+
--_solo-intent-fill-max: initial;
|
|
335
|
+
--_solo-color: var(--_solo-intent-color, var(--color-text, light-dark(oklch(14.5% 0 0), oklch(98.5% 0 0))));
|
|
336
|
+
--_solo-contrast: var(
|
|
337
|
+
--_solo-intent-contrast,
|
|
338
|
+
var(--color-text-contrast, light-dark(oklch(98.5% 0 0), oklch(14.5% 0 0)))
|
|
339
|
+
);
|
|
340
|
+
--_solo-strong: var(--_solo-intent-strong, var(--color-text-strong, light-dark(oklch(20.5% 0 0), oklch(97% 0 0))));
|
|
341
|
+
--_solo-capped: min(var(--ui-fill, 0%), var(--_solo-intent-fill-max, 20%));
|
|
342
|
+
--_solo-fill: color-mix(in oklab, var(--_solo-color) var(--_solo-capped), transparent);
|
|
343
|
+
--_solo-on-fill: min(var(--ui-fg-on-fill, 0%), max(0%, calc(var(--_solo-capped) * 2 - 100%)));
|
|
344
|
+
--_solo-fg: color-mix(in oklab, var(--_solo-contrast) var(--_solo-on-fill), var(--_solo-strong));
|
|
345
|
+
/* The line with no intent on the element: this aesthetic's own ink. */
|
|
346
|
+
--_solo-ink: var(
|
|
347
|
+
--_solo-intent-border,
|
|
348
|
+
light-dark(var(--color-neutral-950, oklch(14.5% 0 0)), var(--color-neutral-50, oklch(98.5% 0 0)))
|
|
349
|
+
);
|
|
350
|
+
--_solo-edge: color-mix(in oklab, var(--_solo-ink) var(--ui-border, 100%), var(--_solo-fill));
|
|
351
|
+
--_solo-depth: calc(2px * var(--ui-elevation, 1));
|
|
352
|
+
|
|
353
|
+
/* Printed as drawn; see `.glass-solo`. */
|
|
354
|
+
print-color-adjust: exact;
|
|
355
|
+
|
|
356
|
+
border: 1px solid var(--_solo-edge);
|
|
357
|
+
/* The surface shape: the element this exists for is usually a pane. An action
|
|
358
|
+
takes the control shape below. */
|
|
359
|
+
border-radius: var(--sketch-radius-surface, 80px 4px 75px 5px / 3px 70px 4px 80px);
|
|
360
|
+
/* The aesthetic's neutral depth cue, not the ink: the class casts its 2px
|
|
361
|
+
offset in the depth colour, and casting a solo pane in full ink would read
|
|
362
|
+
as a heavier, neobrutalist slab. The depth colour is a literal, for the reason
|
|
363
|
+
`.glass-solo` gives. */
|
|
364
|
+
box-shadow:
|
|
365
|
+
var(--_solo-depth) var(--_solo-depth) 0 0 light-dark(rgb(15 23 42 / 0.08), rgb(0 0 0 / 0.55)),
|
|
366
|
+
inset 0 0 0 100vmax var(--_solo-fill);
|
|
367
|
+
font-family: var(--font-sketch, cursive);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/* An intent class on the element colours it, as on a component. Named rather
|
|
371
|
+
than read from `--intent-*` alone: those slots inherit, so a `.success`
|
|
372
|
+
container would colour a solo element where it leaves a component neutral. */
|
|
373
|
+
.sketch-solo:is(.primary, .secondary, .success, .warning, .destructive, .info) {
|
|
374
|
+
--_solo-intent-color: var(--intent-color);
|
|
375
|
+
--_solo-intent-contrast: var(--intent-contrast);
|
|
376
|
+
--_solo-intent-strong: var(--intent-strong);
|
|
377
|
+
--_solo-intent-border: var(--intent-border);
|
|
378
|
+
--_solo-intent-fill-max: var(--intent-fill-max);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/* The text colour is written only where a fill or an intent is asked for, on
|
|
382
|
+
the element or by a container's fill class. Anywhere else the element keeps
|
|
383
|
+
its own: a dark toast keeps its light text. */
|
|
384
|
+
.sketch-solo:is(
|
|
385
|
+
.solid,
|
|
386
|
+
.soft,
|
|
387
|
+
.ghost,
|
|
388
|
+
.primary,
|
|
389
|
+
.secondary,
|
|
390
|
+
.success,
|
|
391
|
+
.warning,
|
|
392
|
+
.destructive,
|
|
393
|
+
.info,
|
|
394
|
+
:is(.solid, .soft, .ghost) *
|
|
395
|
+
) {
|
|
396
|
+
color: var(--_solo-fg);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/* An action takes the expressive control shape. */
|
|
400
|
+
.sketch-solo:is(
|
|
401
|
+
button,
|
|
402
|
+
a[href],
|
|
403
|
+
[role="button"],
|
|
404
|
+
summary,
|
|
405
|
+
input[type="button"],
|
|
406
|
+
input[type="submit"],
|
|
407
|
+
input[type="reset"]
|
|
408
|
+
) {
|
|
409
|
+
border-radius: var(--sketch-radius, 255px 15px 225px 15px / 15px 225px 15px 255px);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/* With `.sketch-rounded`, the rounded outlines, through their own knobs. */
|
|
413
|
+
.sketch-solo.sketch-rounded {
|
|
414
|
+
border-radius: var(--sketch-radius-surface-rounded, 38px 16px 36px 17px / 16px 34px 17px 32px);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.sketch-solo.sketch-rounded:is(
|
|
418
|
+
button,
|
|
419
|
+
a[href],
|
|
420
|
+
[role="button"],
|
|
421
|
+
summary,
|
|
422
|
+
input[type="button"],
|
|
423
|
+
input[type="submit"],
|
|
424
|
+
input[type="reset"]
|
|
425
|
+
) {
|
|
426
|
+
border-radius: var(--sketch-radius-rounded, 26px 10px 24px 11px / 12px 23px 11px 20px);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/* This entrypoint may be the only package stylesheet loaded, so it cannot rely
|
|
430
|
+
on theme.css's forced-colors material reset. */
|
|
431
|
+
@media (forced-colors: active) {
|
|
432
|
+
.sketch-solo {
|
|
433
|
+
border-style: solid;
|
|
434
|
+
}
|
|
435
|
+
}
|
package/{dist/tw → tw}/box.css
RENAMED
|
@@ -34,6 +34,23 @@
|
|
|
34
34
|
specificity, so restating it here is what keeps a nested box reading its
|
|
35
35
|
own presentation instead of the container's reinterpretation of one. */
|
|
36
36
|
--_fill-cap: 100%;
|
|
37
|
+
/* What a box rests as when nothing above `@apply box` says otherwise: no
|
|
38
|
+
fill, no line, the ordinary depth. Stated on the element, not left to
|
|
39
|
+
the `var()` fallbacks: `--_d-*` inherit like any custom property, so a
|
|
40
|
+
bare `box` inside a `.btn` rested as the button does -- a full fill and
|
|
41
|
+
the button's line. A component writes its own after `@apply box`, where
|
|
42
|
+
the later declaration wins. See docs/internal/model.md#resting-defaults. */
|
|
43
|
+
--_d-fill: 0%;
|
|
44
|
+
--_d-fg-on-fill: 0%;
|
|
45
|
+
--_d-border: 0%;
|
|
46
|
+
--_d-elevation: 1;
|
|
47
|
+
--_d-holds-ink: none;
|
|
48
|
+
|
|
49
|
+
/* Printed as drawn. A browser leaves backgrounds off paper by default, and
|
|
50
|
+
a filled box prints its label in the contrast colour: white on nothing.
|
|
51
|
+
Inherited, so everything inside keeps its paint too. */
|
|
52
|
+
print-color-adjust: exact;
|
|
53
|
+
|
|
37
54
|
--_capped: min(var(--ui-fill, var(--_d-fill)), var(--_fill-cap, 100%), var(--intent-fill-max, 100%));
|
|
38
55
|
/* Whether the intent's cap stopped the fill short, as 0% or 100%. A capped
|
|
39
56
|
fill is a plate the presentation asked to be full, so it rests on the page
|
|
@@ -85,7 +102,26 @@
|
|
|
85
102
|
`--intent-contrast` keeps its own meaning -- `--_on-fill` reconciles it with
|
|
86
103
|
a capped intent -- rather than being bent so neutral's contrast is the ink,
|
|
87
104
|
which renders a checked neutral checkbox black-on-black. */
|
|
88
|
-
--_fg: color-mix(in oklab, var(--intent-contrast) var(--_on-fill), var(--intent-strong));
|
|
105
|
+
--_fg-own: color-mix(in oklab, var(--intent-contrast) var(--_on-fill), var(--intent-strong));
|
|
106
|
+
/* The ink of the plate beneath. Intent does not cascade, so a component with
|
|
107
|
+
none prints the page's ink, and on a filled parent that ink sat on the
|
|
108
|
+
parent's fill: a badge in a primary button read at 1.11:1. A box whose
|
|
109
|
+
fill is a plate hands its own ink down; one with no plate declares these
|
|
110
|
+
invalid, which for a registered property means it inherits them, so the
|
|
111
|
+
ink passes through an input group to the field inside it. `--_through`
|
|
112
|
+
is 100% for a neutral box (its cap is below 100%) that was handed an ink
|
|
113
|
+
and holds none: an intent keeps its own ink, as it keeps its own colour.
|
|
114
|
+
A component that rests on a ground of its own restates all three after
|
|
115
|
+
`@apply box`. See docs/internal/model.md#the-ink-of-the-plate-beneath. */
|
|
116
|
+
--_held-ink: var(--_holds-ink, var(--_d-holds-ink)) var(--_fg-own);
|
|
117
|
+
--_held-on: var(--_holds-ink, var(--_d-holds-ink)) 100%;
|
|
118
|
+
--_own-hold: var(--_holds-ink, var(--_d-holds-ink)) 100%;
|
|
119
|
+
--_through: min(
|
|
120
|
+
var(--_held-on),
|
|
121
|
+
calc(100% - var(--_own-hold)),
|
|
122
|
+
clamp(0%, calc((100% - var(--intent-fill-max, 100%)) * 1000), 100%)
|
|
123
|
+
);
|
|
124
|
+
--_fg: color-mix(in oklab, var(--_held-ink) var(--_through), var(--_fg-own));
|
|
89
125
|
/* P3: the line fades out as the fill fills in, so a filled box has a seamless
|
|
90
126
|
edge. It fades toward `transparent`, not toward the plate: the plate
|
|
91
127
|
already runs under the border (nothing clips the background to the padding
|
|
@@ -98,7 +134,29 @@
|
|
|
98
134
|
`.edgeless` on the fill colour, which the border box paints as a second
|
|
99
135
|
coat -- a ring around an element that asked for no edge. See
|
|
100
136
|
docs/internal/model.md#presentation. */
|
|
101
|
-
|
|
137
|
+
/* The neutral line of a box with no fill, where an aesthetic's line cannot
|
|
138
|
+
be seen without one: glass's hairline is a highlight on a plate, and on a
|
|
139
|
+
`.ghost.edged` button there is no plate (1.01:1 on a light page). A
|
|
140
|
+
component that wants the swap names the ink after `@apply box`; cleared
|
|
141
|
+
here so a box nested in one does not inherit it. `--_bare` is 100% for a
|
|
142
|
+
neutral intent (its cap is below 100%) resolving to no fill, stepped from
|
|
143
|
+
the resolved values as `surface`'s `--_quiet` is, so a container's
|
|
144
|
+
`.ghost` counts and an intent's own line is never swapped. */
|
|
145
|
+
--_bare-ink: initial;
|
|
146
|
+
--_bare: min(
|
|
147
|
+
clamp(0%, calc((100% - var(--intent-fill-max, 100%)) * 1000), 100%),
|
|
148
|
+
clamp(0%, calc(100% - var(--ui-fill, var(--_d-fill)) * 1000), 100%)
|
|
149
|
+
);
|
|
150
|
+
--_line-ink: color-mix(
|
|
151
|
+
in oklab,
|
|
152
|
+
var(--_held-ink) var(--_through),
|
|
153
|
+
color-mix(
|
|
154
|
+
in oklab,
|
|
155
|
+
var(--_bare-ink, var(--intent-border, var(--ui-ink, var(--color-border)))) var(--_bare),
|
|
156
|
+
var(--intent-border, var(--ui-ink, var(--color-border)))
|
|
157
|
+
)
|
|
158
|
+
);
|
|
159
|
+
--_line: color-mix(in oklab, transparent var(--ui-fill, var(--_d-fill)), var(--_line-ink));
|
|
102
160
|
/* How much line there is, as an input rather than a result. A component that
|
|
103
161
|
must keep its line whatever the edge class says raises `--_edge-floor`
|
|
104
162
|
instead of rewriting `--_edge`, and the composition above still runs.
|
|
@@ -134,10 +192,6 @@
|
|
|
134
192
|
public override, undeclared by the package. See docs/internal/model.md#material-tokens. */
|
|
135
193
|
--_scale-size: initial;
|
|
136
194
|
--_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;
|
|
141
195
|
--_scale: var(--ui-scale, min(var(--_scale-size, var(--_scale-pad, 1)), var(--_scale-pad, var(--_scale-size, 1))));
|
|
142
196
|
/* Depth follows the step down and not up: a 4px slab under a 20px button
|
|
143
197
|
swallows it, while a press that travels the aesthetic's whole depth has to
|
|
@@ -149,8 +203,8 @@
|
|
|
149
203
|
with no aesthetic. The order lets a raised card under `.neobrutalism` keep
|
|
150
204
|
the slab. Nothing declares the last slot until something asks for depth, so
|
|
151
205
|
a plain unmodified page has no shadow anywhere. */
|
|
152
|
-
--_sy: calc(var(--ui-shadow-y, var(--_d-shadow-y, var(--
|
|
153
|
-
--_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));
|
|
154
208
|
/* Spread is deliberately not scaled. An aesthetic that draws its edge as an
|
|
155
209
|
inset ring spends spread on it, and scaling that by elevation would erase
|
|
156
210
|
the edge of every component the registry rests at zero. Elevation is depth:
|
|
@@ -161,7 +215,11 @@
|
|
|
161
215
|
mixes where the intent lives). An intent-coloured shadow at full opacity is
|
|
162
216
|
a smear of the component's hue, not depth; neobrutalism's slab, which *is*
|
|
163
217
|
ink, asks for it by name. */
|
|
164
|
-
--_depth-color: color-mix(
|
|
218
|
+
--_depth-color: color-mix(
|
|
219
|
+
in oklab,
|
|
220
|
+
var(--intent-border, var(--ui-ink, var(--color-border))) var(--ui-shadow-ink, 0%),
|
|
221
|
+
var(--elevation-color)
|
|
222
|
+
);
|
|
165
223
|
/* Or the shadow *is* the edge. An aesthetic that draws its line as an inset
|
|
166
224
|
ring (`.pixel`) puts the border where `clip-path` cannot cut it, so that
|
|
167
225
|
ring must answer the edge axis like a real border -- `--_edge` already does,
|
|
@@ -187,7 +245,7 @@
|
|
|
187
245
|
--_halo-layer:
|
|
188
246
|
,
|
|
189
247
|
0 0 var(--ui-halo-blur, 0px) var(--ui-halo-spread, 0px)
|
|
190
|
-
color-mix(in oklab, var(--intent-border) var(--ui-halo-ink), transparent);
|
|
248
|
+
color-mix(in oklab, var(--intent-border, var(--ui-ink, var(--color-border))) var(--ui-halo-ink), transparent);
|
|
191
249
|
/* Indirection so a component can substitute a complete value of its own
|
|
192
250
|
without restating the parts -- `surface` does, for the multi-layer case.
|
|
193
251
|
There is deliberately no `--ui-shadow` wrapper: a complete value has nothing
|
|
@@ -202,8 +260,21 @@
|
|
|
202
260
|
differs from the fill, whatever the fill is. Shadows paint first-on-top,
|
|
203
261
|
so the line is listed last and is the two pixels the ring leaves showing. */
|
|
204
262
|
--_focus-stack:
|
|
205
|
-
var(--_shadow),
|
|
263
|
+
var(--_shadow),
|
|
264
|
+
inset 0 0 0 var(--ui-focus-inset) var(--focus-ring, color-mix(in srgb, var(--color-primary) 64%, transparent)),
|
|
206
265
|
inset 0 0 0 calc(var(--ui-focus-inset) + 2px) var(--color-background);
|
|
266
|
+
/* The same line of the page colour under the outline `reset.css` draws,
|
|
267
|
+
for the same reason: the outline sits over the box's own edge, and on a
|
|
268
|
+
box filled with the ring's colour that part of it was invisible. Under a
|
|
269
|
+
two-pixel line that left one pixel of ring, which neobrutalism's slab
|
|
270
|
+
covered on two sides. Stepped from the capped fill, so only a box filled
|
|
271
|
+
past half takes it: on an unfilled one the ring already reads against the
|
|
272
|
+
page, and a line of the page colour inside a soft field is a stray mark. */
|
|
273
|
+
--_focus-gap: color-mix(
|
|
274
|
+
in oklab,
|
|
275
|
+
var(--color-background) clamp(0%, calc((var(--_capped) - 50%) * 1000), 100%),
|
|
276
|
+
transparent
|
|
277
|
+
);
|
|
207
278
|
|
|
208
279
|
/* Every box sizes itself as `min-height`/`min-width: var(--control-height)`
|
|
209
280
|
plus its own padding and the border shorthand above, so its geometry is
|
|
@@ -274,7 +345,7 @@
|
|
|
274
345
|
non-inherited property is `initial`, that is `none`. Every focused box would
|
|
275
346
|
lose its shadow rather than keep it. */
|
|
276
347
|
&:focus-visible {
|
|
277
|
-
box-shadow: var(--_focus-stack, var(--_shadow));
|
|
348
|
+
box-shadow: var(--_focus-stack, var(--_shadow), inset 0 0 0 2px var(--_focus-gap));
|
|
278
349
|
}
|
|
279
350
|
|
|
280
351
|
&:disabled,
|
|
@@ -292,20 +363,26 @@
|
|
|
292
363
|
full and darkens because the colour changed.
|
|
293
364
|
|
|
294
365
|
Separate from `box` because tinting on hover is right for something you press
|
|
295
|
-
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. */
|
|
296
371
|
@utility box-hover {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
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
|
+
);
|
|
307
383
|
|
|
308
|
-
|
|
384
|
+
transform: var(--ui-hover-transform, none);
|
|
385
|
+
}
|
|
309
386
|
}
|
|
310
387
|
}
|
|
311
388
|
|
|
@@ -314,7 +391,9 @@
|
|
|
314
391
|
component opts in. `btn` and `.card.interactive` both do. The gesture is the
|
|
315
392
|
aesthetic's -- neobrutalism travels into its offset shadow, chunky-tile drops
|
|
316
393
|
onto its bar -- and with no aesthetic it is the base `scale(0.97)` from
|
|
317
|
-
`theme.css
|
|
394
|
+
`theme.css`. Reduced motion keeps every press and drops its motion, in
|
|
395
|
+
`box`, since a press is the feedback that a click landed. The
|
|
396
|
+
`--ui-active-shadow-*` slots
|
|
318
397
|
stay no-ops until an aesthetic sets them.
|
|
319
398
|
|
|
320
399
|
A press that travels into the element's own depth is a translation, given as
|
|
@@ -331,7 +410,11 @@
|
|
|
331
410
|
@utility box-active {
|
|
332
411
|
&:active:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]) {
|
|
333
412
|
--_sx: calc(var(--ui-active-shadow-x, var(--ui-shadow-x, var(--_d-shadow-x, 0px))) * var(--_depth));
|
|
334
|
-
|
|
413
|
+
/* The same three slots as the resting offset, `.raised`'s plain step last,
|
|
414
|
+
so with no aesthetic a pressed button keeps the depth it rests on. */
|
|
415
|
+
--_sy: calc(
|
|
416
|
+
var(--ui-active-shadow-y, var(--ui-shadow-y, var(--_d-shadow-y, var(--_elevation-y, 0px)))) * var(--_depth)
|
|
417
|
+
);
|
|
335
418
|
|
|
336
419
|
--_press: calc(var(--ui-active-translate-x, 0px) * var(--_depth))
|
|
337
420
|
calc(var(--ui-active-translate-y, 0px) * var(--_depth));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
@reference "tailwindcss";
|
|
2
|
+
@import "../theme.css";
|
|
3
|
+
@reference "../box.css";
|
|
4
|
+
|
|
5
|
+
/* The focused entry: what the rules in `button.rules.css` need to compile on their
|
|
6
|
+
own, then the rules. An aggregate entry imports the rules file directly and
|
|
7
|
+
supplies those needs once -- Tailwind stacks a `@utility` each time a file
|
|
8
|
+
that defines it is imported or referenced, so a second route to `box.css`
|
|
9
|
+
doubles every `@apply box`. See docs/internal/model.md (One route to each
|
|
10
|
+
utility). */
|
|
11
|
+
@import "./button.rules.css";
|