@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
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/* Glass: translucent surfaces over a blurred backdrop with a hairline highlight
|
|
2
|
-
edge. It needs something behind it to blur -- on a flat page background it is
|
|
3
|
-
translucent panel and nothing more.
|
|
2
|
+
edge. It needs something behind it to blur -- on a flat page background it is
|
|
3
|
+
a translucent panel and nothing more.
|
|
4
4
|
|
|
5
|
-
Tier 1 only
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
as noise. */
|
|
5
|
+
Tier 1 only: the scope is a token. Only `surface` resolves `--ui-backdrop`,
|
|
6
|
+
so blur reaches cards, panels, alerts and tooltips while controls stay solid.
|
|
7
|
+
An active blur costs a compositing layer apiece, and one under every control
|
|
8
|
+
of a dense cluster reads as noise. */
|
|
10
9
|
|
|
11
10
|
/* The layer map, stated before anything uses a layer -- see `theme.css`. The
|
|
12
11
|
aesthetic's token class sits in `components`, below every utility, so a
|
|
@@ -40,8 +39,19 @@
|
|
|
40
39
|
on a field's 60% resting line, in light. See
|
|
41
40
|
docs/internal/model.md#presentation. */
|
|
42
41
|
--ui-control-ink: light-dark(rgb(0 0 0 / 0.55), rgb(255 255 255 / 0.55));
|
|
42
|
+
/* Nor is a line drawn on a plate: the hairline vanishes on a table's light
|
|
43
|
+
plate, and its default, `.ruled`, and `.ruleless` forms would render as
|
|
44
|
+
one. A table's frame and rules take the theme's ink at a fifth,
|
|
45
|
+
translucent for the same reason the control line is. */
|
|
46
|
+
--ui-rule-ink: light-dark(rgb(0 0 0 / 0.2), rgb(255 255 255 / 0.2));
|
|
43
47
|
|
|
44
|
-
|
|
48
|
+
/* The glass is the ground, not the fill. Thinning fills with
|
|
49
|
+
`--ui-bg-alpha` would make how much colour a presentation asked for
|
|
50
|
+
depend on the aesthetic, which is presentation's question (R1): a
|
|
51
|
+
`.solid` button, a checked toggle, and a `.solid` card stay opaque.
|
|
52
|
+
Translucency lives in `--ui-surface-ground` below, the plate a partial
|
|
53
|
+
fill is painted over. */
|
|
54
|
+
--ui-bg-alpha: 1;
|
|
45
55
|
--ui-backdrop: blur(14px) saturate(1.6);
|
|
46
56
|
--ui-surface-image: initial;
|
|
47
57
|
|
|
@@ -54,6 +64,15 @@
|
|
|
54
64
|
--ui-shadow-y: 0px;
|
|
55
65
|
--ui-shadow-blur: 0px;
|
|
56
66
|
--ui-shadow-spread: 0px;
|
|
67
|
+
--ui-shadow-inset: initial;
|
|
68
|
+
--ui-shadow-ink: initial;
|
|
69
|
+
--ui-active-shadow-x: initial;
|
|
70
|
+
--ui-active-shadow-y: initial;
|
|
71
|
+
/* The theme's depth colour, restated: the surface shadow below resolves it
|
|
72
|
+
here, on the region, so inside chunky tile it inherited opaque black and
|
|
73
|
+
cast a black slab under every card, and inside cyber it inherited
|
|
74
|
+
transparent and cast none. */
|
|
75
|
+
--elevation-color: light-dark(rgb(15 23 42 / 0.08), rgb(0 0 0 / 0.55));
|
|
57
76
|
/* No halo, cleared so a region nested inside another
|
|
58
77
|
aesthetic does not inherit one. */
|
|
59
78
|
--ui-halo-blur: initial;
|
|
@@ -88,8 +107,14 @@
|
|
|
88
107
|
/* Nothing here draws its edge as a ring, and an aesthetic nested inside pixel
|
|
89
108
|
has to say so rather than inherit it. */
|
|
90
109
|
--ui-shadow-edge: initial;
|
|
110
|
+
/* Nothing clips, so the global focus outline shows; pixel's inset focus
|
|
111
|
+
layer is cleared rather than inherited. */
|
|
112
|
+
--ui-focus-inset: initial;
|
|
91
113
|
--ui-hover-transform: none;
|
|
92
|
-
|
|
114
|
+
/* The base press, stated because every token here is: the depth in this
|
|
115
|
+
aesthetic is the blur, so a control has no slab to press into, and a pane
|
|
116
|
+
that gives slightly under the pointer is the one answer a press gets. */
|
|
117
|
+
--ui-active-transform: scale(0.97);
|
|
93
118
|
--ui-active-translate-x: initial;
|
|
94
119
|
--ui-active-translate-y: initial;
|
|
95
120
|
|
|
@@ -105,11 +130,212 @@
|
|
|
105
130
|
surface rather than a softer blur. */
|
|
106
131
|
@media (prefers-reduced-transparency: reduce) {
|
|
107
132
|
.glass {
|
|
108
|
-
--ui-bg-alpha: 1;
|
|
109
133
|
--ui-backdrop: none;
|
|
110
134
|
--ui-surface-ground: var(--color-background);
|
|
111
135
|
}
|
|
112
136
|
}
|
|
137
|
+
|
|
138
|
+
@media (prefers-reduced-motion: reduce) {
|
|
139
|
+
.glass {
|
|
140
|
+
--ui-active-transform: none;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* Liquid glass: a modifier of glass, the way `.sketch-rounded` is of sketch.
|
|
145
|
+
Continuous corners, a bright rim where light catches the pane, a lighter
|
|
146
|
+
blur, and -- in engines that render an SVG filter in `backdrop-filter`,
|
|
147
|
+
Chromium today -- a lens that bends the backdrop at the edges. On the region
|
|
148
|
+
beside `.glass`, or on one surface inside a glass region.
|
|
149
|
+
|
|
150
|
+
Only the corners apply on their own. The ink, ground, and blur are glass
|
|
151
|
+
material, so they are set below only where `.glass` is in scope: a lone
|
|
152
|
+
`.glass-liquid` would otherwise make every surface translucent with nothing
|
|
153
|
+
to blur and every field's line a near-invisible hairline.
|
|
154
|
+
|
|
155
|
+
The corner knobs are glass's own, with larger defaults: a continuous corner
|
|
156
|
+
reads smaller than a round one of the same radius. Where `corner-shape` is
|
|
157
|
+
not drawn the corners stay round.
|
|
158
|
+
|
|
159
|
+
Not on a solo element: `.glass-solo.glass-liquid` paints its own corner
|
|
160
|
+
below, and a token declared on it would inherit into whatever it holds --
|
|
161
|
+
a `.btn` inside a solo toast took liquid's corners on a page with no glass
|
|
162
|
+
in scope. Every scope below skips a solo element for the same reason. */
|
|
163
|
+
.glass-liquid:not(.glass-solo) {
|
|
164
|
+
--ui-corner: var(--glass-radius, 1rem);
|
|
165
|
+
--ui-corner-surface: var(--glass-radius-surface, 1.5rem);
|
|
166
|
+
--ui-corner-shape: squircle;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* The layers' values, on a solo element too: it draws the same two. */
|
|
170
|
+
.glass-liquid {
|
|
171
|
+
--_glass-liquid-blur: blur(2px) saturate(1.8);
|
|
172
|
+
|
|
173
|
+
/* The lens is its own layer rather than a second function in the blur's
|
|
174
|
+
list: Firefox and WebKit accept `url()` there and draw nothing for it, and
|
|
175
|
+
a filter list with an unusable reference is dropped whole -- the blur with
|
|
176
|
+
it. Kept apart, an engine that ignores the lens still blurs.
|
|
177
|
+
|
|
178
|
+
The displacement map is built inside the filter from the box itself:
|
|
179
|
+
erode a flood of the filter region by 8px, blur it into a ramp, and take
|
|
180
|
+
the ramp's slope across x and y as the two displacement channels. Every
|
|
181
|
+
length is absolute, so the band is the same width on a tooltip and on a
|
|
182
|
+
page-wide card; no length is a percentage of the box. The blur is wider
|
|
183
|
+
than the erosion so the ramp's corners round off -- otherwise the square
|
|
184
|
+
core shows through as loops at every corner. A filter cannot read a custom
|
|
185
|
+
property, so the band and the strength are fixed, not knobs. */
|
|
186
|
+
--_glass-liquid-lens: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='lens' x='0' y='0' width='100%' height='100%' color-interpolation-filters='sRGB'><feFlood flood-color='white'/><feMorphology operator='erode' radius='8'/><feGaussianBlur stdDeviation='10' result='ramp'/><feOffset in='ramp' dx='-3' result='l'/><feOffset in='ramp' dx='3' result='r'/><feComposite in='l' in2='r' operator='arithmetic' k2='2' k3='-2' k4='0.5' result='dx'/><feOffset in='ramp' dy='-3' result='u'/><feOffset in='ramp' dy='3' result='d'/><feComposite in='u' in2='d' operator='arithmetic' k2='2' k3='-2' k4='0.5' result='dy'/><feColorMatrix in='dx' values='0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1' result='x'/><feColorMatrix in='dy' values='0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1'/><feComposite in='x' operator='arithmetic' k2='1' k3='1'/><feDisplacementMap in='SourceGraphic' scale='110' xChannelSelector='R' yChannelSelector='G'/></filter></svg>#lens");
|
|
187
|
+
|
|
188
|
+
/* The same lens at a control's size. The pane's band is 8px of erosion
|
|
189
|
+
under a 10px blur, which is most of a 40px button's height: the two
|
|
190
|
+
sides' ramps meet in the middle and the label sits in a loop. A third of
|
|
191
|
+
each length keeps a clear centre for the label. */
|
|
192
|
+
--_glass-liquid-lens-control: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='lens' x='0' y='0' width='100%' height='100%' color-interpolation-filters='sRGB'><feFlood flood-color='white'/><feMorphology operator='erode' radius='3'/><feGaussianBlur stdDeviation='3.5' result='ramp'/><feOffset in='ramp' dx='-1' result='l'/><feOffset in='ramp' dx='1' result='r'/><feComposite in='l' in2='r' operator='arithmetic' k2='2' k3='-2' k4='0.5' result='dx'/><feOffset in='ramp' dy='-1' result='u'/><feOffset in='ramp' dy='1' result='d'/><feComposite in='u' in2='d' operator='arithmetic' k2='2' k3='-2' k4='0.5' result='dy'/><feColorMatrix in='dx' values='0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1' result='x'/><feColorMatrix in='dy' values='0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1'/><feComposite in='x' operator='arithmetic' k2='1' k3='1'/><feDisplacementMap in='SourceGraphic' scale='40' xChannelSelector='R' yChannelSelector='G'/></filter></svg>#lens");
|
|
193
|
+
|
|
194
|
+
/* The rim: light caught on the top-left edge and, fainter, the bottom-right,
|
|
195
|
+
over a soft inner glow. Drawn on the lens layer, the topmost, because a
|
|
196
|
+
rim drawn on the surface itself would sit under the layers and blur. */
|
|
197
|
+
--_glass-liquid-rim:
|
|
198
|
+
inset 1px 1px 0 light-dark(rgb(255 255 255 / 0.75), rgb(255 255 255 / 0.35)),
|
|
199
|
+
inset -1px -1px 0 light-dark(rgb(255 255 255 / 0.35), rgb(255 255 255 / 0.12)),
|
|
200
|
+
inset 0 0 18px light-dark(rgb(255 255 255 / 0.22), rgb(255 255 255 / 0.05));
|
|
201
|
+
--_glass-liquid-sheen: linear-gradient(
|
|
202
|
+
160deg,
|
|
203
|
+
light-dark(rgb(255 255 255 / 0.22), rgb(255 255 255 / 0.06)),
|
|
204
|
+
transparent 45%
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/* The glass material the modifier changes, where glass is in scope: on the
|
|
209
|
+
same element, or on a surface inside a glass region.
|
|
210
|
+
|
|
211
|
+
The backdrop is liquid's lighter blur, for whatever frosts under glass and
|
|
212
|
+
takes no layers below: a bare `<table>` under `/native`, a consumer's own
|
|
213
|
+
`@apply surface`. The layers' selector list cannot name those, and with
|
|
214
|
+
the backdrop cleared here they kept the clearer ground with nothing
|
|
215
|
+
blurred behind it. A surface that does take the layers clears its own. */
|
|
216
|
+
.glass.glass-liquid:not(.glass-solo),
|
|
217
|
+
.glass .glass-liquid:not(.glass-solo) {
|
|
218
|
+
--ui-ink: light-dark(rgb(255 255 255 / 0.45), rgb(255 255 255 / 0.16));
|
|
219
|
+
--ui-surface-ground: color-mix(in srgb, var(--color-background) 30%, transparent);
|
|
220
|
+
--ui-surface-image: initial;
|
|
221
|
+
--ui-backdrop: var(--_glass-liquid-blur);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
225
|
+
.glass.glass-liquid:not(.glass-solo),
|
|
226
|
+
.glass .glass-liquid:not(.glass-solo) {
|
|
227
|
+
--ui-surface-ground: var(--color-background);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.glass-liquid {
|
|
231
|
+
--_glass-liquid-blur: none;
|
|
232
|
+
--_glass-liquid-lens: none;
|
|
233
|
+
--_glass-liquid-lens-control: none;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* The layers: a treatment no token reaches, so a selector list glass owns and
|
|
238
|
+
the registry records. Two pseudo-elements behind the content, the blur
|
|
239
|
+
beneath and the lens with the rim and sheen above it. `isolation` keeps
|
|
240
|
+
them above the element's own plate, which they then blur with the page;
|
|
241
|
+
`position` anchors them, and a component that positions itself -- the
|
|
242
|
+
tooltip bubble -- keeps its own. A default or `.soft` table frosts under
|
|
243
|
+
glass, so it takes the layers too. Both slots are spent, so a host carries
|
|
244
|
+
no `::before` or `::after` of the consumer's; the fields cannot host one.
|
|
245
|
+
|
|
246
|
+
The blur is on the layer and not on the host: an element with a backdrop
|
|
247
|
+
filter of its own is a backdrop root, and a layer inside one sees only that
|
|
248
|
+
element, never the page behind it. So a host clears the region's backdrop.
|
|
249
|
+
|
|
250
|
+
Surfaces take the layers from a liquid scope. A region of another
|
|
251
|
+
aesthetic nested inside, or of plain glass, keeps its own material and
|
|
252
|
+
takes none; this list names the other aesthetics, and `registry.test.ts`
|
|
253
|
+
fails when one is missing.
|
|
254
|
+
|
|
255
|
+
A button takes them only when it carries `.glass-liquid` itself, in a
|
|
256
|
+
glass scope. Controls stay solid under a liquid region, for the reason
|
|
257
|
+
glass gives -- two composited layers and a filter under every control of a
|
|
258
|
+
dense cluster -- and a class on the one button that is meant to be a pane
|
|
259
|
+
is a request rather than a cascade, the idiom `text-control` uses for
|
|
260
|
+
`.edgeless`. Its fill is still presentation's: `.solid` stays an opaque
|
|
261
|
+
plate under the rim, and `.soft` and `.ghost` are the clear panes. A
|
|
262
|
+
disabled one is dimmed by `opacity`, which makes it a backdrop root, so it
|
|
263
|
+
keeps the ground and the rim and bends nothing. */
|
|
264
|
+
:is(.glass-liquid:not(.glass-solo), .glass-liquid:not(.glass-solo) *):is(.glass, .glass *):is(
|
|
265
|
+
.card,
|
|
266
|
+
.panel,
|
|
267
|
+
.alert,
|
|
268
|
+
.tooltip-bubble,
|
|
269
|
+
.surface,
|
|
270
|
+
.data-table:not(.solid, .ghost)
|
|
271
|
+
):not(
|
|
272
|
+
.glass-liquid :is(.neobrutalism, .pixel, .chunky-tile, .cyber, .sketch),
|
|
273
|
+
.glass-liquid :is(.neobrutalism, .pixel, .chunky-tile, .cyber, .sketch) *,
|
|
274
|
+
.glass-liquid .glass:not(.glass-liquid),
|
|
275
|
+
.glass-liquid .glass:not(.glass-liquid) *
|
|
276
|
+
),
|
|
277
|
+
.btn.glass-liquid:is(.glass, .glass *) {
|
|
278
|
+
--ui-backdrop: none;
|
|
279
|
+
|
|
280
|
+
position: relative;
|
|
281
|
+
isolation: isolate;
|
|
282
|
+
|
|
283
|
+
&::before,
|
|
284
|
+
&::after {
|
|
285
|
+
position: absolute;
|
|
286
|
+
inset: 0;
|
|
287
|
+
z-index: -1;
|
|
288
|
+
border-radius: inherit;
|
|
289
|
+
corner-shape: inherit;
|
|
290
|
+
content: "";
|
|
291
|
+
pointer-events: none;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/* Prefixed first, for the reason `surface` gives. */
|
|
295
|
+
&::before {
|
|
296
|
+
-webkit-backdrop-filter: var(--_glass-liquid-blur);
|
|
297
|
+
backdrop-filter: var(--_glass-liquid-blur);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
&::after {
|
|
301
|
+
backdrop-filter: var(--_glass-liquid-lens);
|
|
302
|
+
background-image: var(--_glass-liquid-sheen);
|
|
303
|
+
box-shadow: var(--_glass-liquid-rim);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/* A button's lens is the control one. Swapped as the value the layer reads
|
|
308
|
+
rather than on the layer: the list above outranks any selector that names
|
|
309
|
+
the button's `::after` alone. */
|
|
310
|
+
.btn.glass-liquid:is(.glass, .glass *) {
|
|
311
|
+
--_glass-liquid-lens: var(--_glass-liquid-lens-control);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/* A liquid button rests on liquid's ground rather than on nothing, so a
|
|
316
|
+
`.ghost` or `.soft` one is a pane and not a hole in the page. It reads the
|
|
317
|
+
surface ground the modifier set on it, so reduced transparency and a
|
|
318
|
+
consumer's own `--ui-surface-ground` reach it as they reach a card.
|
|
319
|
+
|
|
320
|
+
In `utilities`, not with the layers: it has to beat `box`'s own
|
|
321
|
+
`--_d-ground: transparent`, which it does there on specificity, and it
|
|
322
|
+
writes only a private nothing a consumer sets. See
|
|
323
|
+
docs/internal/model.md#cascade-layers. */
|
|
324
|
+
@layer utilities {
|
|
325
|
+
.btn.glass-liquid:is(.glass, .glass *) {
|
|
326
|
+
--_d-ground: var(--ui-surface-ground, transparent);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/* Forced colours paint the plain surface: no layer blurs, bends, or lights it. */
|
|
331
|
+
@media (forced-colors: active) {
|
|
332
|
+
.glass-liquid {
|
|
333
|
+
--_glass-liquid-blur: none;
|
|
334
|
+
--_glass-liquid-lens: none;
|
|
335
|
+
--_glass-liquid-lens-control: none;
|
|
336
|
+
--_glass-liquid-rim: none;
|
|
337
|
+
--_glass-liquid-sheen: none;
|
|
338
|
+
}
|
|
113
339
|
}
|
|
114
340
|
|
|
115
341
|
/* Solo: the same look painted onto the one element carrying the class, for an
|
|
@@ -117,24 +343,63 @@
|
|
|
117
343
|
`<div>` on a page that never loaded the base stylesheet. See
|
|
118
344
|
docs/internal/model.md#solo-classes.
|
|
119
345
|
|
|
120
|
-
It
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
346
|
+
It composes with what the element is asked to be, the way a component does:
|
|
347
|
+
the fill and edge a presentation class asks for, on the element or cascaded
|
|
348
|
+
from a container; the intent class on the element; the element's own
|
|
349
|
+
elevation class. Each is read with the unclassed look as its fallback, so
|
|
350
|
+
with none of them, or with no theme loaded, it paints what it always did.
|
|
351
|
+
|
|
352
|
+
Material is the exception. It reads the aesthetic's own knobs and the
|
|
353
|
+
theme's foundation tokens, each with its shipped literal as the fallback,
|
|
354
|
+
and never a material `--ui-*` or `--elevation-color` token: those belong to
|
|
355
|
+
whichever aesthetic an ancestor carries, and a solo element has to be this
|
|
356
|
+
aesthetic inside any of them.
|
|
357
|
+
|
|
124
358
|
Unlayered and one class deep, so it beats a foreign component's
|
|
125
359
|
zero-specificity rules wherever they load. Not for this package's own
|
|
126
|
-
components, which take the aesthetic class instead.
|
|
360
|
+
components, which take the aesthetic class instead.
|
|
361
|
+
|
|
362
|
+
The other five paint the fill as an inset layer over whatever the element
|
|
363
|
+
already is, and write no background, so an unclassed solo element keeps its
|
|
364
|
+
own. Glass's translucent ground is its material, so it owns the background
|
|
365
|
+
and mixes the fill over that ground. */
|
|
127
366
|
.glass-solo {
|
|
128
|
-
|
|
367
|
+
/* The composition, the same in every solo class; `registry.test.ts` holds
|
|
368
|
+
the copies together. See the note on `.glass-solo`. */
|
|
369
|
+
--_solo-intent-color: initial;
|
|
370
|
+
--_solo-intent-contrast: initial;
|
|
371
|
+
--_solo-intent-strong: initial;
|
|
372
|
+
--_solo-intent-border: initial;
|
|
373
|
+
--_solo-intent-fill-max: initial;
|
|
374
|
+
--_solo-color: var(--_solo-intent-color, var(--color-text, light-dark(oklch(14.5% 0 0), oklch(98.5% 0 0))));
|
|
375
|
+
--_solo-contrast: var(
|
|
376
|
+
--_solo-intent-contrast,
|
|
377
|
+
var(--color-text-contrast, light-dark(oklch(98.5% 0 0), oklch(14.5% 0 0)))
|
|
378
|
+
);
|
|
379
|
+
--_solo-strong: var(--_solo-intent-strong, var(--color-text-strong, light-dark(oklch(20.5% 0 0), oklch(97% 0 0))));
|
|
380
|
+
--_solo-capped: min(var(--ui-fill, 0%), var(--_solo-intent-fill-max, 20%));
|
|
381
|
+
--_solo-fill: color-mix(in oklab, var(--_solo-color) var(--_solo-capped), transparent);
|
|
382
|
+
--_solo-on-fill: min(var(--ui-fg-on-fill, 0%), max(0%, calc(var(--_solo-capped) * 2 - 100%)));
|
|
383
|
+
--_solo-fg: color-mix(in oklab, var(--_solo-contrast) var(--_solo-on-fill), var(--_solo-strong));
|
|
384
|
+
/* The line with no intent on the element: this aesthetic's own ink. */
|
|
385
|
+
--_solo-ink: var(--_solo-intent-border, light-dark(rgb(255 255 255 / 0.65), rgb(255 255 255 / 0.22)));
|
|
386
|
+
--_solo-ground: color-mix(
|
|
129
387
|
in srgb,
|
|
130
388
|
var(--color-background, light-dark(oklch(98.5% 0 0), oklch(14.5% 0 0))) 45%,
|
|
131
389
|
transparent
|
|
132
390
|
);
|
|
133
|
-
|
|
391
|
+
/* The plate runs under the border, so the line fades to nothing, as `box`'s
|
|
392
|
+
does, rather than to the fill. */
|
|
393
|
+
--_solo-edge: color-mix(in oklab, var(--_solo-ink) var(--ui-border, 100%), transparent);
|
|
394
|
+
|
|
395
|
+
background-color: color-mix(in oklab, var(--_solo-color) var(--_solo-capped), var(--_solo-ground));
|
|
396
|
+
border: 1px solid var(--_solo-edge);
|
|
134
397
|
/* The surface corner: the element this exists for is a pane. */
|
|
135
398
|
border-radius: var(--glass-radius-surface, 1rem);
|
|
136
399
|
/* The theme's depth colour as a literal, for the reason above: inside a
|
|
137
|
-
`.chunky-tile` region the token is black.
|
|
400
|
+
`.chunky-tile` region the token is black. A complete shadow, so the
|
|
401
|
+
elevation classes do not reach it, as they do not under the aesthetic
|
|
402
|
+
class. */
|
|
138
403
|
box-shadow:
|
|
139
404
|
0 1px 2px -1px light-dark(rgb(15 23 42 / 0.08), rgb(0 0 0 / 0.55)),
|
|
140
405
|
0 18px 40px -16px light-dark(rgb(15 23 42 / 0.08), rgb(0 0 0 / 0.55));
|
|
@@ -144,10 +409,97 @@
|
|
|
144
409
|
backdrop-filter: blur(14px) saturate(1.6);
|
|
145
410
|
}
|
|
146
411
|
|
|
412
|
+
/* An intent class on the element colours it, as on a component. Named rather
|
|
413
|
+
than read from `--intent-*` alone: those slots inherit, so a `.success`
|
|
414
|
+
container would colour a solo element where it leaves a component neutral. */
|
|
415
|
+
.glass-solo:is(.primary, .secondary, .success, .warning, .destructive, .info) {
|
|
416
|
+
--_solo-intent-color: var(--intent-color);
|
|
417
|
+
--_solo-intent-contrast: var(--intent-contrast);
|
|
418
|
+
--_solo-intent-strong: var(--intent-strong);
|
|
419
|
+
--_solo-intent-border: var(--intent-border);
|
|
420
|
+
--_solo-intent-fill-max: var(--intent-fill-max);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/* The text colour is written only where a fill or an intent is asked for, on
|
|
424
|
+
the element or by a container's fill class. Anywhere else the element keeps
|
|
425
|
+
its own: a dark toast keeps its light text. */
|
|
426
|
+
.glass-solo:is(
|
|
427
|
+
.solid,
|
|
428
|
+
.soft,
|
|
429
|
+
.ghost,
|
|
430
|
+
.primary,
|
|
431
|
+
.secondary,
|
|
432
|
+
.success,
|
|
433
|
+
.warning,
|
|
434
|
+
.destructive,
|
|
435
|
+
.info,
|
|
436
|
+
:is(.solid, .soft, .ghost) *
|
|
437
|
+
) {
|
|
438
|
+
color: var(--_solo-fg);
|
|
439
|
+
}
|
|
440
|
+
|
|
147
441
|
@media (prefers-reduced-transparency: reduce) {
|
|
148
442
|
.glass-solo {
|
|
149
|
-
|
|
443
|
+
--_solo-ground: var(--color-background, light-dark(oklch(98.5% 0 0), oklch(14.5% 0 0)));
|
|
444
|
+
|
|
150
445
|
-webkit-backdrop-filter: none;
|
|
151
446
|
backdrop-filter: none;
|
|
152
447
|
}
|
|
153
448
|
}
|
|
449
|
+
|
|
450
|
+
/* With `.glass-liquid`, the liquid pane: its corner and ground, and the same two
|
|
451
|
+
layers behind the element's content. The element's own blur goes, for the
|
|
452
|
+
backdrop-root reason the modifier gives. Both pseudo-elements are spent, so a
|
|
453
|
+
foreign element that draws its own `::before` or `::after` loses them.
|
|
454
|
+
|
|
455
|
+
The layers need a positioned element to anchor to. That one declaration is
|
|
456
|
+
layered, where the element's own `fixed` or `absolute` beats it -- a toast
|
|
457
|
+
keeps its placement, and an unpositioned element is anchored. */
|
|
458
|
+
@layer components {
|
|
459
|
+
.glass-solo.glass-liquid {
|
|
460
|
+
position: relative;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.glass-solo.glass-liquid {
|
|
465
|
+
--_solo-ground: color-mix(
|
|
466
|
+
in srgb,
|
|
467
|
+
var(--color-background, light-dark(oklch(98.5% 0 0), oklch(14.5% 0 0))) 30%,
|
|
468
|
+
transparent
|
|
469
|
+
);
|
|
470
|
+
--_solo-ink: var(--_solo-intent-border, light-dark(rgb(255 255 255 / 0.45), rgb(255 255 255 / 0.16)));
|
|
471
|
+
|
|
472
|
+
isolation: isolate;
|
|
473
|
+
border-radius: var(--glass-radius-surface, 1.5rem);
|
|
474
|
+
corner-shape: squircle;
|
|
475
|
+
-webkit-backdrop-filter: none;
|
|
476
|
+
backdrop-filter: none;
|
|
477
|
+
|
|
478
|
+
&::before,
|
|
479
|
+
&::after {
|
|
480
|
+
position: absolute;
|
|
481
|
+
inset: 0;
|
|
482
|
+
z-index: -1;
|
|
483
|
+
border-radius: inherit;
|
|
484
|
+
corner-shape: inherit;
|
|
485
|
+
content: "";
|
|
486
|
+
pointer-events: none;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
&::before {
|
|
490
|
+
-webkit-backdrop-filter: var(--_glass-liquid-blur);
|
|
491
|
+
backdrop-filter: var(--_glass-liquid-blur);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
&::after {
|
|
495
|
+
backdrop-filter: var(--_glass-liquid-lens);
|
|
496
|
+
background-image: var(--_glass-liquid-sheen);
|
|
497
|
+
box-shadow: var(--_glass-liquid-rim);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
502
|
+
.glass-solo.glass-liquid {
|
|
503
|
+
--_solo-ground: var(--color-background, light-dark(oklch(98.5% 0 0), oklch(14.5% 0 0)));
|
|
504
|
+
}
|
|
505
|
+
}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
for only the one in use: a cascading class has no static call site, so nothing
|
|
3
3
|
here can be tree-shaken.
|
|
4
4
|
|
|
5
|
-
Import after the base stylesheet in either form
|
|
5
|
+
Import before or after the base stylesheet, in either form: every entrypoint
|
|
6
|
+
states the layer order first, so load order decides nothing. */
|
|
6
7
|
@import "./neobrutalism.css";
|
|
7
8
|
@import "./glass.css";
|
|
8
9
|
@import "./pixel.css";
|