@camp.dev/bones 0.4.1 → 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 +61 -106
- package/package.json +4 -36
- package/src/css/bones.css +1008 -141
- package/dist/core/attributes.d.mts +0 -25
- package/dist/core/attributes.mjs +0 -36
- package/dist/css/auto.css +0 -1116
- package/dist/css/bones.css +0 -204
- package/dist/element/boundary.d.mts +0 -26
- package/dist/element/boundary.mjs +0 -220
- package/dist/element/index.d.mts +0 -14
- package/dist/element/index.mjs +0 -6
- package/dist/element/measure.mjs +0 -99
- package/dist/element/overlay.mjs +0 -184
- package/dist/index.d.mts +0 -2
- package/dist/index.mjs +0 -2
- package/dist/react/boundary.d.mts +0 -40
- package/dist/react/boundary.mjs +0 -21
- package/dist/react/create-bones.d.mts +0 -23
- package/dist/react/create-bones.mjs +0 -69
- package/dist/react/index.d.mts +0 -4
- package/dist/react/index.mjs +0 -4
- package/dist/server/bootstrap.d.mts +0 -4
- package/dist/server/bootstrap.mjs +0 -3
- package/dist/server/index.d.mts +0 -17
- package/dist/server/index.mjs +0 -57
- package/src/css/auto.css +0 -1116
package/src/css/bones.css
CHANGED
|
@@ -1,3 +1,56 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
@camp.dev/bones/css: the stylesheet is the API.
|
|
3
|
+
|
|
4
|
+
Everything keys on aria-busy="true". Under a busy element (or on it), a
|
|
5
|
+
leaf with no element children becomes a text bar and a replaced element or
|
|
6
|
+
form control becomes a block. Five data-bones-* attributes adjust that:
|
|
7
|
+
data-bones-type="text|block" overrides the inferred shape,
|
|
8
|
+
data-bones-lines="N" paints N stacked bars, data-bones-length="N" makes
|
|
9
|
+
the bar N characters wide, data-bones-auto="off" exempts a subtree from
|
|
10
|
+
inference, and data-bones-animate picks shimmer, pulse, or none. Outside a
|
|
11
|
+
busy region every attribute is inert.
|
|
12
|
+
|
|
13
|
+
Two cascade strengths, one activation condition. Keep this shape:
|
|
14
|
+
- Inferred rules live in @layer bones-auto. They match arbitrary page
|
|
15
|
+
elements, so page CSS must outrank them. The cost: a page color rule
|
|
16
|
+
keeps an inferred bone's text visible over its bar.
|
|
17
|
+
- Explicit rules (data-bones-type, data-bones-lines) are unlayered. The
|
|
18
|
+
author asked for that bone, so a page rule like h3 { color: #333 } must
|
|
19
|
+
not keep the text visible. They still need the busy scope.
|
|
20
|
+
- The busy scope is :is([aria-busy="true"], [aria-busy="true"] *). The
|
|
21
|
+
busy element itself is eligible, so aria-busy can sit on a component's
|
|
22
|
+
root and a single-leaf component still paints.
|
|
23
|
+
- Within each strength the data-bones-animate scopes beat the default
|
|
24
|
+
because :is(:scope, :scope *) puts them at higher specificity, not
|
|
25
|
+
because of source order. tests/browser/default-animation.test.ts and
|
|
26
|
+
animation-scope.test.ts pin this.
|
|
27
|
+
- The bar geometry is declared twice, once per strength, because a rule
|
|
28
|
+
is either in a layer or not. tests/bones-css.test.ts pins the copies
|
|
29
|
+
equal.
|
|
30
|
+
- The bar is a pseudo-element that inherits the element's padding, so
|
|
31
|
+
its content box is the element's content box and the bar sits inside a
|
|
32
|
+
badge's padding. clip-path: inset(0 round r) content-box gives it
|
|
33
|
+
rounded ends at the content edges as one path; border-radius could not,
|
|
34
|
+
because a radius shrinks by the padding on the way in, and a layered
|
|
35
|
+
mask (still used for the multi-line rows, which repeat) leaves seams
|
|
36
|
+
where the browser snaps each layer's tile to device pixels on its own.
|
|
37
|
+
Percentage padding resolves against a different box on the
|
|
38
|
+
pseudo-element and misses; length padding is exact.
|
|
39
|
+
The padding and box-sizing on the single bar are !important: a page
|
|
40
|
+
reset such as `*, *::before, *::after { box-sizing: border-box;
|
|
41
|
+
padding: 0 }` is unlayered, so it would otherwise beat the inferred copy
|
|
42
|
+
and push the bar back out to the padding edge. No page styles a bone's
|
|
43
|
+
own bar on purpose, and an important layered declaration wins over
|
|
44
|
+
every normal one.
|
|
45
|
+
- The enumerated data-bones-lines and data-bones-length blocks exist for
|
|
46
|
+
browsers without advanced attr(). Delete them once Safari ships attr()
|
|
47
|
+
with type().
|
|
48
|
+
- --bone-radius must carry a unit. --bones-r feeds it to min(), where a
|
|
49
|
+
unitless 0 is a <number> and invalidates the multi-line mask.
|
|
50
|
+
--------------------------------------------------------------------------- */
|
|
51
|
+
|
|
52
|
+
@layer bones-auto;
|
|
53
|
+
|
|
1
54
|
:root {
|
|
2
55
|
/* Bones derive their color from the text color in effect at the bone, so
|
|
3
56
|
they inherit the page's own contrast guarantee on any background in any
|
|
@@ -11,149 +64,914 @@
|
|
|
11
64
|
--bone-duration: 1.5s;
|
|
12
65
|
}
|
|
13
66
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
[data-bone-line] {
|
|
22
|
-
display: block;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
[data-bone-line]:last-child {
|
|
26
|
-
width: 69%;
|
|
67
|
+
@keyframes bone-shimmer {
|
|
68
|
+
0% {
|
|
69
|
+
background-position: 200% 0;
|
|
70
|
+
}
|
|
71
|
+
100% {
|
|
72
|
+
background-position: -200% 0;
|
|
73
|
+
}
|
|
27
74
|
}
|
|
28
75
|
|
|
29
|
-
|
|
30
|
-
|
|
76
|
+
@keyframes bone-pulse {
|
|
77
|
+
0%,
|
|
78
|
+
100% {
|
|
79
|
+
opacity: 1;
|
|
80
|
+
}
|
|
81
|
+
50% {
|
|
82
|
+
opacity: 0.5;
|
|
83
|
+
}
|
|
31
84
|
}
|
|
32
85
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
86
|
+
/* Line count. Enumerated for every Baseline 2024 browser; advanced attr()
|
|
87
|
+
reads any value where it exists (Chrome 133, Firefox 155, Safari after
|
|
88
|
+
Interop 2026). Both tables set an inherited custom property, so they carry
|
|
89
|
+
the busy scope like every other rule here: an attribute on an element
|
|
90
|
+
outside a busy region must not reach the leaves of a busy region nested
|
|
91
|
+
below it. The defaults live in var() fallbacks at the point of use, never
|
|
92
|
+
as declarations in a higher-specificity rule that would beat these. */
|
|
93
|
+
:is([aria-busy="true"], [aria-busy="true"] *) {
|
|
94
|
+
&[data-bones-lines="2"] {
|
|
95
|
+
--bones-lines: 2;
|
|
96
|
+
}
|
|
97
|
+
&[data-bones-lines="3"] {
|
|
98
|
+
--bones-lines: 3;
|
|
99
|
+
}
|
|
100
|
+
&[data-bones-lines="4"] {
|
|
101
|
+
--bones-lines: 4;
|
|
102
|
+
}
|
|
103
|
+
&[data-bones-lines="5"] {
|
|
104
|
+
--bones-lines: 5;
|
|
105
|
+
}
|
|
106
|
+
&[data-bones-lines="6"] {
|
|
107
|
+
--bones-lines: 6;
|
|
108
|
+
}
|
|
109
|
+
&[data-bones-lines="7"] {
|
|
110
|
+
--bones-lines: 7;
|
|
111
|
+
}
|
|
112
|
+
&[data-bones-lines="8"] {
|
|
113
|
+
--bones-lines: 8;
|
|
114
|
+
}
|
|
43
115
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
116
|
+
/* Width in characters. Enumerated 1 through 40 for the same reason. */
|
|
117
|
+
&[data-bones-length="1"] {
|
|
118
|
+
--bones-length: 1;
|
|
119
|
+
}
|
|
120
|
+
&[data-bones-length="2"] {
|
|
121
|
+
--bones-length: 2;
|
|
122
|
+
}
|
|
123
|
+
&[data-bones-length="3"] {
|
|
124
|
+
--bones-length: 3;
|
|
125
|
+
}
|
|
126
|
+
&[data-bones-length="4"] {
|
|
127
|
+
--bones-length: 4;
|
|
128
|
+
}
|
|
129
|
+
&[data-bones-length="5"] {
|
|
130
|
+
--bones-length: 5;
|
|
131
|
+
}
|
|
132
|
+
&[data-bones-length="6"] {
|
|
133
|
+
--bones-length: 6;
|
|
134
|
+
}
|
|
135
|
+
&[data-bones-length="7"] {
|
|
136
|
+
--bones-length: 7;
|
|
137
|
+
}
|
|
138
|
+
&[data-bones-length="8"] {
|
|
139
|
+
--bones-length: 8;
|
|
140
|
+
}
|
|
141
|
+
&[data-bones-length="9"] {
|
|
142
|
+
--bones-length: 9;
|
|
143
|
+
}
|
|
144
|
+
&[data-bones-length="10"] {
|
|
145
|
+
--bones-length: 10;
|
|
146
|
+
}
|
|
147
|
+
&[data-bones-length="11"] {
|
|
148
|
+
--bones-length: 11;
|
|
149
|
+
}
|
|
150
|
+
&[data-bones-length="12"] {
|
|
151
|
+
--bones-length: 12;
|
|
152
|
+
}
|
|
153
|
+
&[data-bones-length="13"] {
|
|
154
|
+
--bones-length: 13;
|
|
155
|
+
}
|
|
156
|
+
&[data-bones-length="14"] {
|
|
157
|
+
--bones-length: 14;
|
|
158
|
+
}
|
|
159
|
+
&[data-bones-length="15"] {
|
|
160
|
+
--bones-length: 15;
|
|
161
|
+
}
|
|
162
|
+
&[data-bones-length="16"] {
|
|
163
|
+
--bones-length: 16;
|
|
164
|
+
}
|
|
165
|
+
&[data-bones-length="17"] {
|
|
166
|
+
--bones-length: 17;
|
|
167
|
+
}
|
|
168
|
+
&[data-bones-length="18"] {
|
|
169
|
+
--bones-length: 18;
|
|
170
|
+
}
|
|
171
|
+
&[data-bones-length="19"] {
|
|
172
|
+
--bones-length: 19;
|
|
173
|
+
}
|
|
174
|
+
&[data-bones-length="20"] {
|
|
175
|
+
--bones-length: 20;
|
|
176
|
+
}
|
|
177
|
+
&[data-bones-length="21"] {
|
|
178
|
+
--bones-length: 21;
|
|
179
|
+
}
|
|
180
|
+
&[data-bones-length="22"] {
|
|
181
|
+
--bones-length: 22;
|
|
182
|
+
}
|
|
183
|
+
&[data-bones-length="23"] {
|
|
184
|
+
--bones-length: 23;
|
|
185
|
+
}
|
|
186
|
+
&[data-bones-length="24"] {
|
|
187
|
+
--bones-length: 24;
|
|
188
|
+
}
|
|
189
|
+
&[data-bones-length="25"] {
|
|
190
|
+
--bones-length: 25;
|
|
191
|
+
}
|
|
192
|
+
&[data-bones-length="26"] {
|
|
193
|
+
--bones-length: 26;
|
|
194
|
+
}
|
|
195
|
+
&[data-bones-length="27"] {
|
|
196
|
+
--bones-length: 27;
|
|
197
|
+
}
|
|
198
|
+
&[data-bones-length="28"] {
|
|
199
|
+
--bones-length: 28;
|
|
200
|
+
}
|
|
201
|
+
&[data-bones-length="29"] {
|
|
202
|
+
--bones-length: 29;
|
|
203
|
+
}
|
|
204
|
+
&[data-bones-length="30"] {
|
|
205
|
+
--bones-length: 30;
|
|
206
|
+
}
|
|
207
|
+
&[data-bones-length="31"] {
|
|
208
|
+
--bones-length: 31;
|
|
209
|
+
}
|
|
210
|
+
&[data-bones-length="32"] {
|
|
211
|
+
--bones-length: 32;
|
|
212
|
+
}
|
|
213
|
+
&[data-bones-length="33"] {
|
|
214
|
+
--bones-length: 33;
|
|
215
|
+
}
|
|
216
|
+
&[data-bones-length="34"] {
|
|
217
|
+
--bones-length: 34;
|
|
218
|
+
}
|
|
219
|
+
&[data-bones-length="35"] {
|
|
220
|
+
--bones-length: 35;
|
|
221
|
+
}
|
|
222
|
+
&[data-bones-length="36"] {
|
|
223
|
+
--bones-length: 36;
|
|
224
|
+
}
|
|
225
|
+
&[data-bones-length="37"] {
|
|
226
|
+
--bones-length: 37;
|
|
227
|
+
}
|
|
228
|
+
&[data-bones-length="38"] {
|
|
229
|
+
--bones-length: 38;
|
|
230
|
+
}
|
|
231
|
+
&[data-bones-length="39"] {
|
|
232
|
+
--bones-length: 39;
|
|
233
|
+
}
|
|
234
|
+
&[data-bones-length="40"] {
|
|
235
|
+
--bones-length: 40;
|
|
236
|
+
}
|
|
47
237
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
238
|
+
@supports (x: attr(x type(*))) {
|
|
239
|
+
&[data-bones-lines] {
|
|
240
|
+
--bones-lines: attr(data-bones-lines type(<number>), 1);
|
|
241
|
+
}
|
|
242
|
+
&[data-bones-length] {
|
|
243
|
+
--bones-length: attr(data-bones-length type(<number>), 4);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
53
246
|
}
|
|
54
247
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
inset-inline: unset;
|
|
59
|
-
top: unset;
|
|
60
|
-
transform: none;
|
|
61
|
-
}
|
|
248
|
+
/* ---------------------------------------------------------------------------
|
|
249
|
+
Inferred. Loses to page CSS.
|
|
250
|
+
--------------------------------------------------------------------------- */
|
|
62
251
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
252
|
+
@layer bones-auto {
|
|
253
|
+
:is([aria-busy="true"], [aria-busy="true"] *) {
|
|
254
|
+
/* Text: any element with no child elements, minus explicit markup, opted
|
|
255
|
+
out subtrees, and the tags that get block treatment or nothing. */
|
|
256
|
+
&:not(:has(*)):not(
|
|
257
|
+
[data-bones-type],
|
|
258
|
+
[data-bones-type] *,
|
|
259
|
+
[data-bones-lines],
|
|
260
|
+
[data-bones-lines] *,
|
|
261
|
+
[data-bones-auto="off"],
|
|
262
|
+
[data-bones-auto="off"] *
|
|
263
|
+
):not(
|
|
264
|
+
img,
|
|
265
|
+
svg,
|
|
266
|
+
video,
|
|
267
|
+
canvas,
|
|
268
|
+
picture,
|
|
269
|
+
iframe,
|
|
270
|
+
embed,
|
|
271
|
+
object,
|
|
272
|
+
audio,
|
|
273
|
+
button,
|
|
274
|
+
input,
|
|
275
|
+
select,
|
|
276
|
+
textarea,
|
|
277
|
+
progress,
|
|
278
|
+
meter,
|
|
279
|
+
hr,
|
|
280
|
+
br,
|
|
281
|
+
svg *,
|
|
282
|
+
picture *,
|
|
283
|
+
select *,
|
|
284
|
+
object *
|
|
285
|
+
) {
|
|
286
|
+
--bones-bar-top: calc((1lh + 1cap) / 2 - 1ex);
|
|
287
|
+
--bones-r: max(0.01px, min(var(--bone-radius), 0.5ex));
|
|
288
|
+
--bones-inset: max(0px, var(--bones-r) - 1px);
|
|
289
|
+
color: rgb(from currentcolor r g b / 0);
|
|
290
|
+
position: relative;
|
|
291
|
+
min-width: calc(var(--bones-length, 4) * 1ch);
|
|
292
|
+
min-height: 1lh;
|
|
293
|
+
&::before {
|
|
294
|
+
content: "\200b";
|
|
295
|
+
}
|
|
296
|
+
/* min-width does nothing on an inline box. An empty inline leaf (a
|
|
297
|
+
<span> with no data yet) gets its width from an inline-block ::before
|
|
298
|
+
instead, so its bar has something to span. Non-empty leaves keep the
|
|
299
|
+
zero-width space, which adds no width and moves no text. */
|
|
300
|
+
&:empty::before {
|
|
301
|
+
content: "";
|
|
302
|
+
display: inline-block;
|
|
303
|
+
min-width: calc(var(--bones-length, 4) * 1ch);
|
|
304
|
+
}
|
|
305
|
+
&::after {
|
|
306
|
+
content: "";
|
|
307
|
+
position: absolute;
|
|
308
|
+
inset-inline: 0;
|
|
309
|
+
top: var(--bones-bar-top);
|
|
310
|
+
height: 1ex;
|
|
311
|
+
padding: inherit !important;
|
|
312
|
+
box-sizing: content-box !important;
|
|
313
|
+
clip-path: inset(0 round var(--bones-r)) content-box;
|
|
314
|
+
pointer-events: none;
|
|
315
|
+
animation: bone-shimmer var(--bone-duration) ease-in-out infinite;
|
|
316
|
+
background: linear-gradient(
|
|
317
|
+
90deg,
|
|
318
|
+
var(--bone-base) 25%,
|
|
319
|
+
var(--bone-highlight) 50%,
|
|
320
|
+
var(--bone-base) 75%
|
|
321
|
+
);
|
|
322
|
+
background-size: 200% 100%;
|
|
323
|
+
}
|
|
324
|
+
/* Width variance: block-level leaves cycle 85 / 100 / 92 / 60 so runs
|
|
325
|
+
of lines look organic. A cap, not a width, so an inline-block or a
|
|
326
|
+
flex-item leaf (a badge, a pill) keeps its content width instead of
|
|
327
|
+
stretching to a share of the row. */
|
|
328
|
+
&:nth-child(4n + 1) {
|
|
329
|
+
max-width: 85%;
|
|
330
|
+
}
|
|
331
|
+
&:nth-child(4n + 2) {
|
|
332
|
+
max-width: 100%;
|
|
333
|
+
}
|
|
334
|
+
&:nth-child(4n + 3) {
|
|
335
|
+
max-width: 92%;
|
|
336
|
+
}
|
|
337
|
+
&:nth-child(4n) {
|
|
338
|
+
max-width: 60%;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
66
341
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
342
|
+
/* Block: replaced elements and form controls fill their own box. A text
|
|
343
|
+
bar across an avatar or a button looks wrong. Leafness is not required;
|
|
344
|
+
svg and select routinely have element children. A loaded image paints
|
|
345
|
+
over its own background, so the picture is pushed out of its content
|
|
346
|
+
box (BON-15); only img, video, and canvas honor that. transition: none
|
|
347
|
+
keeps a page `transition: all` from sliding it out on the way in. */
|
|
348
|
+
&:is(
|
|
349
|
+
img,
|
|
350
|
+
svg,
|
|
351
|
+
video,
|
|
352
|
+
canvas,
|
|
353
|
+
picture,
|
|
354
|
+
iframe,
|
|
355
|
+
embed,
|
|
356
|
+
object,
|
|
357
|
+
audio,
|
|
358
|
+
button,
|
|
359
|
+
input,
|
|
360
|
+
select,
|
|
361
|
+
textarea,
|
|
362
|
+
progress,
|
|
363
|
+
meter
|
|
364
|
+
):not(
|
|
365
|
+
[data-bones-type],
|
|
366
|
+
[data-bones-type] *,
|
|
367
|
+
[data-bones-lines],
|
|
368
|
+
[data-bones-lines] *,
|
|
369
|
+
[data-bones-auto="off"],
|
|
370
|
+
[data-bones-auto="off"] *
|
|
371
|
+
) {
|
|
372
|
+
color: rgb(from currentcolor r g b / 0);
|
|
373
|
+
border-radius: var(--bone-radius);
|
|
374
|
+
border-color: transparent;
|
|
375
|
+
object-position: 9999px 0;
|
|
376
|
+
transition: none;
|
|
377
|
+
animation: bone-shimmer var(--bone-duration) ease-in-out infinite;
|
|
378
|
+
background: linear-gradient(
|
|
379
|
+
90deg,
|
|
380
|
+
var(--bone-base) 25%,
|
|
381
|
+
var(--bone-highlight) 50%,
|
|
382
|
+
var(--bone-base) 75%
|
|
383
|
+
);
|
|
384
|
+
background-size: 200% 100%;
|
|
385
|
+
}
|
|
71
386
|
|
|
72
|
-
img
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
387
|
+
/* An img with no src: Chrome renders it as inline alt text, ignores its
|
|
388
|
+
width and height, and draws a broken-image glyph. inline-block restores
|
|
389
|
+
the box; the transparent pixel replaces the alt rendering. Firefox and
|
|
390
|
+
Safari draw no glyph, so this is a Chrome fix that is harmless
|
|
391
|
+
elsewhere. A CSP that blocks data: images brings the glyph back. */
|
|
392
|
+
&:is(img):is(:not([src]), [src=""]):not(
|
|
393
|
+
[data-bones-type],
|
|
394
|
+
[data-bones-type] *,
|
|
395
|
+
[data-bones-lines],
|
|
396
|
+
[data-bones-lines] *,
|
|
397
|
+
[data-bones-auto="off"],
|
|
398
|
+
[data-bones-auto="off"] *
|
|
399
|
+
) {
|
|
400
|
+
display: inline-block;
|
|
401
|
+
content: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
|
|
402
|
+
}
|
|
403
|
+
}
|
|
83
404
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
405
|
+
@media (prefers-reduced-motion: reduce) {
|
|
406
|
+
:is([aria-busy="true"], [aria-busy="true"] *) {
|
|
407
|
+
&:not(:has(*)):not(
|
|
408
|
+
[data-bones-type],
|
|
409
|
+
[data-bones-type] *,
|
|
410
|
+
[data-bones-lines],
|
|
411
|
+
[data-bones-lines] *,
|
|
412
|
+
[data-bones-auto="off"],
|
|
413
|
+
[data-bones-auto="off"] *
|
|
414
|
+
):not(
|
|
415
|
+
img,
|
|
416
|
+
svg,
|
|
417
|
+
video,
|
|
418
|
+
canvas,
|
|
419
|
+
picture,
|
|
420
|
+
iframe,
|
|
421
|
+
embed,
|
|
422
|
+
object,
|
|
423
|
+
audio,
|
|
424
|
+
button,
|
|
425
|
+
input,
|
|
426
|
+
select,
|
|
427
|
+
textarea,
|
|
428
|
+
progress,
|
|
429
|
+
meter,
|
|
430
|
+
hr,
|
|
431
|
+
br,
|
|
432
|
+
svg *,
|
|
433
|
+
picture *,
|
|
434
|
+
select *,
|
|
435
|
+
object *
|
|
436
|
+
)::after,
|
|
437
|
+
&:is(
|
|
438
|
+
img,
|
|
439
|
+
svg,
|
|
440
|
+
video,
|
|
441
|
+
canvas,
|
|
442
|
+
picture,
|
|
443
|
+
iframe,
|
|
444
|
+
embed,
|
|
445
|
+
object,
|
|
446
|
+
audio,
|
|
447
|
+
button,
|
|
448
|
+
input,
|
|
449
|
+
select,
|
|
450
|
+
textarea,
|
|
451
|
+
progress,
|
|
452
|
+
meter
|
|
453
|
+
):not(
|
|
454
|
+
[data-bones-type],
|
|
455
|
+
[data-bones-type] *,
|
|
456
|
+
[data-bones-lines],
|
|
457
|
+
[data-bones-lines] *,
|
|
458
|
+
[data-bones-auto="off"],
|
|
459
|
+
[data-bones-auto="off"] *
|
|
460
|
+
) {
|
|
461
|
+
animation: bone-pulse 2s ease-in-out infinite;
|
|
462
|
+
background: var(--bone-base);
|
|
463
|
+
background-size: auto;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
88
467
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
468
|
+
@media (forced-colors: active) {
|
|
469
|
+
:is([aria-busy="true"], [aria-busy="true"] *) {
|
|
470
|
+
&:not(:has(*)):not(
|
|
471
|
+
[data-bones-type],
|
|
472
|
+
[data-bones-type] *,
|
|
473
|
+
[data-bones-lines],
|
|
474
|
+
[data-bones-lines] *,
|
|
475
|
+
[data-bones-auto="off"],
|
|
476
|
+
[data-bones-auto="off"] *
|
|
477
|
+
):not(
|
|
478
|
+
img,
|
|
479
|
+
svg,
|
|
480
|
+
video,
|
|
481
|
+
canvas,
|
|
482
|
+
picture,
|
|
483
|
+
iframe,
|
|
484
|
+
embed,
|
|
485
|
+
object,
|
|
486
|
+
audio,
|
|
487
|
+
button,
|
|
488
|
+
input,
|
|
489
|
+
select,
|
|
490
|
+
textarea,
|
|
491
|
+
progress,
|
|
492
|
+
meter,
|
|
493
|
+
hr,
|
|
494
|
+
br,
|
|
495
|
+
svg *,
|
|
496
|
+
picture *,
|
|
497
|
+
select *,
|
|
498
|
+
object *
|
|
499
|
+
)::after,
|
|
500
|
+
&:is(
|
|
501
|
+
img,
|
|
502
|
+
svg,
|
|
503
|
+
video,
|
|
504
|
+
canvas,
|
|
505
|
+
picture,
|
|
506
|
+
iframe,
|
|
507
|
+
embed,
|
|
508
|
+
object,
|
|
509
|
+
audio,
|
|
510
|
+
button,
|
|
511
|
+
input,
|
|
512
|
+
select,
|
|
513
|
+
textarea,
|
|
514
|
+
progress,
|
|
515
|
+
meter
|
|
516
|
+
):not(
|
|
517
|
+
[data-bones-type],
|
|
518
|
+
[data-bones-type] *,
|
|
519
|
+
[data-bones-lines],
|
|
520
|
+
[data-bones-lines] *,
|
|
521
|
+
[data-bones-auto="off"],
|
|
522
|
+
[data-bones-auto="off"] *
|
|
523
|
+
) {
|
|
524
|
+
background-color: GrayText;
|
|
525
|
+
forced-color-adjust: none;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
96
529
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
530
|
+
/* :is(:scope, :scope *) lets the attribute work from the bone itself, from
|
|
531
|
+
the busy element, or from any ancestor: a scoped selector's implicit
|
|
532
|
+
:scope prefix matches strict descendants only (BON-17). The reduced-motion
|
|
533
|
+
override sits inside each animated scope so it matches at the scope's own
|
|
534
|
+
specificity; "none" has no override because none still means none. */
|
|
535
|
+
@scope ([data-bones-animate="shimmer"]) to ([data-bones-animate]:not([data-bones-animate="shimmer"])) {
|
|
536
|
+
:is([aria-busy="true"], [aria-busy="true"] *):is(:scope, :scope *) {
|
|
537
|
+
&:not(:has(*)):not(
|
|
538
|
+
[data-bones-type],
|
|
539
|
+
[data-bones-type] *,
|
|
540
|
+
[data-bones-lines],
|
|
541
|
+
[data-bones-lines] *,
|
|
542
|
+
[data-bones-auto="off"],
|
|
543
|
+
[data-bones-auto="off"] *
|
|
544
|
+
):not(
|
|
545
|
+
img,
|
|
546
|
+
svg,
|
|
547
|
+
video,
|
|
548
|
+
canvas,
|
|
549
|
+
picture,
|
|
550
|
+
iframe,
|
|
551
|
+
embed,
|
|
552
|
+
object,
|
|
553
|
+
audio,
|
|
554
|
+
button,
|
|
555
|
+
input,
|
|
556
|
+
select,
|
|
557
|
+
textarea,
|
|
558
|
+
progress,
|
|
559
|
+
meter,
|
|
560
|
+
hr,
|
|
561
|
+
br,
|
|
562
|
+
svg *,
|
|
563
|
+
picture *,
|
|
564
|
+
select *,
|
|
565
|
+
object *
|
|
566
|
+
)::after,
|
|
567
|
+
&:is(
|
|
568
|
+
img,
|
|
569
|
+
svg,
|
|
570
|
+
video,
|
|
571
|
+
canvas,
|
|
572
|
+
picture,
|
|
573
|
+
iframe,
|
|
574
|
+
embed,
|
|
575
|
+
object,
|
|
576
|
+
audio,
|
|
577
|
+
button,
|
|
578
|
+
input,
|
|
579
|
+
select,
|
|
580
|
+
textarea,
|
|
581
|
+
progress,
|
|
582
|
+
meter
|
|
583
|
+
):not(
|
|
584
|
+
[data-bones-type],
|
|
585
|
+
[data-bones-type] *,
|
|
586
|
+
[data-bones-lines],
|
|
587
|
+
[data-bones-lines] *,
|
|
588
|
+
[data-bones-auto="off"],
|
|
589
|
+
[data-bones-auto="off"] *
|
|
590
|
+
) {
|
|
591
|
+
animation: bone-shimmer var(--bone-duration) ease-in-out infinite;
|
|
592
|
+
background: linear-gradient(
|
|
593
|
+
90deg,
|
|
594
|
+
var(--bone-base) 25%,
|
|
595
|
+
var(--bone-highlight) 50%,
|
|
596
|
+
var(--bone-base) 75%
|
|
597
|
+
);
|
|
598
|
+
background-size: 200% 100%;
|
|
599
|
+
}
|
|
600
|
+
@media (prefers-reduced-motion: reduce) {
|
|
601
|
+
&:not(:has(*)):not(
|
|
602
|
+
[data-bones-type],
|
|
603
|
+
[data-bones-type] *,
|
|
604
|
+
[data-bones-lines],
|
|
605
|
+
[data-bones-lines] *,
|
|
606
|
+
[data-bones-auto="off"],
|
|
607
|
+
[data-bones-auto="off"] *
|
|
608
|
+
):not(
|
|
609
|
+
img,
|
|
610
|
+
svg,
|
|
611
|
+
video,
|
|
612
|
+
canvas,
|
|
613
|
+
picture,
|
|
614
|
+
iframe,
|
|
615
|
+
embed,
|
|
616
|
+
object,
|
|
617
|
+
audio,
|
|
618
|
+
button,
|
|
619
|
+
input,
|
|
620
|
+
select,
|
|
621
|
+
textarea,
|
|
622
|
+
progress,
|
|
623
|
+
meter,
|
|
624
|
+
hr,
|
|
625
|
+
br,
|
|
626
|
+
svg *,
|
|
627
|
+
picture *,
|
|
628
|
+
select *,
|
|
629
|
+
object *
|
|
630
|
+
)::after,
|
|
631
|
+
&:is(
|
|
632
|
+
img,
|
|
633
|
+
svg,
|
|
634
|
+
video,
|
|
635
|
+
canvas,
|
|
636
|
+
picture,
|
|
637
|
+
iframe,
|
|
638
|
+
embed,
|
|
639
|
+
object,
|
|
640
|
+
audio,
|
|
641
|
+
button,
|
|
642
|
+
input,
|
|
643
|
+
select,
|
|
644
|
+
textarea,
|
|
645
|
+
progress,
|
|
646
|
+
meter
|
|
647
|
+
):not(
|
|
648
|
+
[data-bones-type],
|
|
649
|
+
[data-bones-type] *,
|
|
650
|
+
[data-bones-lines],
|
|
651
|
+
[data-bones-lines] *,
|
|
652
|
+
[data-bones-auto="off"],
|
|
653
|
+
[data-bones-auto="off"] *
|
|
654
|
+
) {
|
|
655
|
+
animation: bone-pulse 2s ease-in-out infinite;
|
|
656
|
+
background: var(--bone-base);
|
|
657
|
+
background-size: auto;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
100
662
|
|
|
101
|
-
@
|
|
102
|
-
|
|
103
|
-
|
|
663
|
+
@scope ([data-bones-animate="pulse"]) to ([data-bones-animate]:not([data-bones-animate="pulse"])) {
|
|
664
|
+
:is([aria-busy="true"], [aria-busy="true"] *):is(:scope, :scope *) {
|
|
665
|
+
&:not(:has(*)):not(
|
|
666
|
+
[data-bones-type],
|
|
667
|
+
[data-bones-type] *,
|
|
668
|
+
[data-bones-lines],
|
|
669
|
+
[data-bones-lines] *,
|
|
670
|
+
[data-bones-auto="off"],
|
|
671
|
+
[data-bones-auto="off"] *
|
|
672
|
+
):not(
|
|
673
|
+
img,
|
|
674
|
+
svg,
|
|
675
|
+
video,
|
|
676
|
+
canvas,
|
|
677
|
+
picture,
|
|
678
|
+
iframe,
|
|
679
|
+
embed,
|
|
680
|
+
object,
|
|
681
|
+
audio,
|
|
682
|
+
button,
|
|
683
|
+
input,
|
|
684
|
+
select,
|
|
685
|
+
textarea,
|
|
686
|
+
progress,
|
|
687
|
+
meter,
|
|
688
|
+
hr,
|
|
689
|
+
br,
|
|
690
|
+
svg *,
|
|
691
|
+
picture *,
|
|
692
|
+
select *,
|
|
693
|
+
object *
|
|
694
|
+
)::after,
|
|
695
|
+
&:is(
|
|
696
|
+
img,
|
|
697
|
+
svg,
|
|
698
|
+
video,
|
|
699
|
+
canvas,
|
|
700
|
+
picture,
|
|
701
|
+
iframe,
|
|
702
|
+
embed,
|
|
703
|
+
object,
|
|
704
|
+
audio,
|
|
705
|
+
button,
|
|
706
|
+
input,
|
|
707
|
+
select,
|
|
708
|
+
textarea,
|
|
709
|
+
progress,
|
|
710
|
+
meter
|
|
711
|
+
):not(
|
|
712
|
+
[data-bones-type],
|
|
713
|
+
[data-bones-type] *,
|
|
714
|
+
[data-bones-lines],
|
|
715
|
+
[data-bones-lines] *,
|
|
716
|
+
[data-bones-auto="off"],
|
|
717
|
+
[data-bones-auto="off"] *
|
|
718
|
+
) {
|
|
719
|
+
animation: bone-pulse var(--bone-duration) ease-in-out infinite;
|
|
720
|
+
background: var(--bone-base);
|
|
721
|
+
background-size: auto;
|
|
722
|
+
}
|
|
723
|
+
@media (prefers-reduced-motion: reduce) {
|
|
724
|
+
&:not(:has(*)):not(
|
|
725
|
+
[data-bones-type],
|
|
726
|
+
[data-bones-type] *,
|
|
727
|
+
[data-bones-lines],
|
|
728
|
+
[data-bones-lines] *,
|
|
729
|
+
[data-bones-auto="off"],
|
|
730
|
+
[data-bones-auto="off"] *
|
|
731
|
+
):not(
|
|
732
|
+
img,
|
|
733
|
+
svg,
|
|
734
|
+
video,
|
|
735
|
+
canvas,
|
|
736
|
+
picture,
|
|
737
|
+
iframe,
|
|
738
|
+
embed,
|
|
739
|
+
object,
|
|
740
|
+
audio,
|
|
741
|
+
button,
|
|
742
|
+
input,
|
|
743
|
+
select,
|
|
744
|
+
textarea,
|
|
745
|
+
progress,
|
|
746
|
+
meter,
|
|
747
|
+
hr,
|
|
748
|
+
br,
|
|
749
|
+
svg *,
|
|
750
|
+
picture *,
|
|
751
|
+
select *,
|
|
752
|
+
object *
|
|
753
|
+
)::after,
|
|
754
|
+
&:is(
|
|
755
|
+
img,
|
|
756
|
+
svg,
|
|
757
|
+
video,
|
|
758
|
+
canvas,
|
|
759
|
+
picture,
|
|
760
|
+
iframe,
|
|
761
|
+
embed,
|
|
762
|
+
object,
|
|
763
|
+
audio,
|
|
764
|
+
button,
|
|
765
|
+
input,
|
|
766
|
+
select,
|
|
767
|
+
textarea,
|
|
768
|
+
progress,
|
|
769
|
+
meter
|
|
770
|
+
):not(
|
|
771
|
+
[data-bones-type],
|
|
772
|
+
[data-bones-type] *,
|
|
773
|
+
[data-bones-lines],
|
|
774
|
+
[data-bones-lines] *,
|
|
775
|
+
[data-bones-auto="off"],
|
|
776
|
+
[data-bones-auto="off"] *
|
|
777
|
+
) {
|
|
778
|
+
animation: bone-pulse 2s ease-in-out infinite;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
104
782
|
}
|
|
105
|
-
|
|
106
|
-
|
|
783
|
+
|
|
784
|
+
@scope ([data-bones-animate="none"]) to ([data-bones-animate]:not([data-bones-animate="none"])) {
|
|
785
|
+
:is([aria-busy="true"], [aria-busy="true"] *):is(:scope, :scope *) {
|
|
786
|
+
&:not(:has(*)):not(
|
|
787
|
+
[data-bones-type],
|
|
788
|
+
[data-bones-type] *,
|
|
789
|
+
[data-bones-lines],
|
|
790
|
+
[data-bones-lines] *,
|
|
791
|
+
[data-bones-auto="off"],
|
|
792
|
+
[data-bones-auto="off"] *
|
|
793
|
+
):not(
|
|
794
|
+
img,
|
|
795
|
+
svg,
|
|
796
|
+
video,
|
|
797
|
+
canvas,
|
|
798
|
+
picture,
|
|
799
|
+
iframe,
|
|
800
|
+
embed,
|
|
801
|
+
object,
|
|
802
|
+
audio,
|
|
803
|
+
button,
|
|
804
|
+
input,
|
|
805
|
+
select,
|
|
806
|
+
textarea,
|
|
807
|
+
progress,
|
|
808
|
+
meter,
|
|
809
|
+
hr,
|
|
810
|
+
br,
|
|
811
|
+
svg *,
|
|
812
|
+
picture *,
|
|
813
|
+
select *,
|
|
814
|
+
object *
|
|
815
|
+
)::after,
|
|
816
|
+
&:is(
|
|
817
|
+
img,
|
|
818
|
+
svg,
|
|
819
|
+
video,
|
|
820
|
+
canvas,
|
|
821
|
+
picture,
|
|
822
|
+
iframe,
|
|
823
|
+
embed,
|
|
824
|
+
object,
|
|
825
|
+
audio,
|
|
826
|
+
button,
|
|
827
|
+
input,
|
|
828
|
+
select,
|
|
829
|
+
textarea,
|
|
830
|
+
progress,
|
|
831
|
+
meter
|
|
832
|
+
):not(
|
|
833
|
+
[data-bones-type],
|
|
834
|
+
[data-bones-type] *,
|
|
835
|
+
[data-bones-lines],
|
|
836
|
+
[data-bones-lines] *,
|
|
837
|
+
[data-bones-auto="off"],
|
|
838
|
+
[data-bones-auto="off"] *
|
|
839
|
+
) {
|
|
840
|
+
animation: none;
|
|
841
|
+
background: var(--bone-base);
|
|
842
|
+
background-size: auto;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
107
845
|
}
|
|
108
846
|
}
|
|
109
847
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
848
|
+
/* ---------------------------------------------------------------------------
|
|
849
|
+
Explicit. Wins over page CSS. Same geometry as the inferred rules above;
|
|
850
|
+
the test suite pins the copies equal.
|
|
851
|
+
--------------------------------------------------------------------------- */
|
|
852
|
+
|
|
853
|
+
:is([aria-busy="true"], [aria-busy="true"] *) {
|
|
854
|
+
&:is([data-bones-type="text"], [data-bones-lines]) {
|
|
855
|
+
--bones-bar-top: calc((1lh + 1cap) / 2 - 1ex);
|
|
856
|
+
--bones-r: max(0.01px, min(var(--bone-radius), 0.5ex));
|
|
857
|
+
--bones-inset: max(0px, var(--bones-r) - 1px);
|
|
858
|
+
color: rgb(from currentcolor r g b / 0);
|
|
859
|
+
position: relative;
|
|
860
|
+
min-width: calc(var(--bones-length, 4) * 1ch);
|
|
861
|
+
min-height: calc(var(--bones-lines, 1) * 1lh);
|
|
862
|
+
&::before {
|
|
863
|
+
content: "\200b";
|
|
864
|
+
}
|
|
865
|
+
&::after {
|
|
866
|
+
content: "";
|
|
867
|
+
position: absolute;
|
|
868
|
+
inset-inline: 0;
|
|
869
|
+
top: var(--bones-bar-top);
|
|
870
|
+
height: 1ex;
|
|
871
|
+
padding: inherit !important;
|
|
872
|
+
box-sizing: content-box !important;
|
|
873
|
+
clip-path: inset(0 round var(--bones-r)) content-box;
|
|
874
|
+
pointer-events: none;
|
|
875
|
+
animation: bone-shimmer var(--bone-duration) ease-in-out infinite;
|
|
876
|
+
background: linear-gradient(
|
|
877
|
+
90deg,
|
|
878
|
+
var(--bone-base) 25%,
|
|
879
|
+
var(--bone-highlight) 50%,
|
|
880
|
+
var(--bone-base) 75%
|
|
881
|
+
);
|
|
882
|
+
background-size: 200% 100%;
|
|
883
|
+
}
|
|
114
884
|
}
|
|
115
|
-
|
|
116
|
-
|
|
885
|
+
&[data-bones-type="text"]:empty::before {
|
|
886
|
+
content: "";
|
|
887
|
+
display: inline-block;
|
|
888
|
+
min-width: calc(var(--bones-length, 4) * 1ch);
|
|
117
889
|
}
|
|
118
|
-
}
|
|
119
890
|
|
|
120
|
-
/*
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
[data-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
background: linear-gradient(
|
|
129
|
-
90deg,
|
|
130
|
-
var(--bone-base) 25%,
|
|
131
|
-
var(--bone-highlight) 50%,
|
|
132
|
-
var(--bone-base) 75%
|
|
133
|
-
);
|
|
134
|
-
background-size: 200% 100%;
|
|
135
|
-
}
|
|
891
|
+
/* Width in characters. A modifier, not a type: an inferred leaf with a
|
|
892
|
+
length is still inferred. Unlayered so a page width rule does not beat
|
|
893
|
+
a length the author wrote into the markup. On an inline box width does
|
|
894
|
+
nothing; the empty leaf's ::before carries the length there. */
|
|
895
|
+
&[data-bones-length] {
|
|
896
|
+
width: calc(var(--bones-length, 4) * 1ch);
|
|
897
|
+
max-width: 100%;
|
|
898
|
+
}
|
|
136
899
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
900
|
+
/* N lines in one element. ::after is the single bar above, moved to the
|
|
901
|
+
bottom row and shortened. ::before covers the rows above it and a
|
|
902
|
+
three-layer mask tiled every 1lh cuts it into bars: a stripe body inset
|
|
903
|
+
by the corner radius, and a left and a right cap, each a whole ellipse
|
|
904
|
+
(rx = radius, ry = half the bar) drawn one radius in from the end of a
|
|
905
|
+
half-width tile. The layers combine as a union, and the browser snaps
|
|
906
|
+
each layer's tile to device pixels on its own, so nothing visible may
|
|
907
|
+
sit on a tile edge: the ellipse's inner half hides under the body, its
|
|
908
|
+
outer half is the cap, and the body overlaps it by a pixel
|
|
909
|
+
(--bones-inset) so a snapped tile edge cannot open a gap. At the default
|
|
910
|
+
4px the ends read as rounded corners; at 999px they clamp to a pill.
|
|
911
|
+
Because ::before fills
|
|
912
|
+
the box down to the last row, an element taller than N lines still gets
|
|
913
|
+
a bar on every row. */
|
|
914
|
+
&[data-bones-lines] {
|
|
915
|
+
display: block;
|
|
916
|
+
--bones-last: 60%;
|
|
917
|
+
&::before {
|
|
918
|
+
content: "";
|
|
919
|
+
position: absolute;
|
|
920
|
+
inset: 0 0 1lh 0;
|
|
921
|
+
padding: inherit;
|
|
922
|
+
box-sizing: content-box;
|
|
923
|
+
pointer-events: none;
|
|
924
|
+
animation: bone-shimmer var(--bone-duration) ease-in-out infinite;
|
|
925
|
+
background: linear-gradient(
|
|
926
|
+
90deg,
|
|
927
|
+
var(--bone-base) 25%,
|
|
928
|
+
var(--bone-highlight) 50%,
|
|
929
|
+
var(--bone-base) 75%
|
|
930
|
+
);
|
|
931
|
+
background-size: 200% 100%;
|
|
932
|
+
mask-image:
|
|
933
|
+
linear-gradient(
|
|
934
|
+
to bottom,
|
|
935
|
+
transparent var(--bones-bar-top),
|
|
936
|
+
#000 var(--bones-bar-top) calc(var(--bones-bar-top) + 1ex),
|
|
937
|
+
transparent calc(var(--bones-bar-top) + 1ex)
|
|
938
|
+
),
|
|
939
|
+
radial-gradient(
|
|
940
|
+
ellipse var(--bones-r) 0.5ex at var(--bones-r) calc(var(--bones-bar-top) + 0.5ex),
|
|
941
|
+
#000 calc(100% - 0.5px),
|
|
942
|
+
transparent 100%
|
|
943
|
+
),
|
|
944
|
+
radial-gradient(
|
|
945
|
+
ellipse var(--bones-r) 0.5ex at calc(100% - var(--bones-r))
|
|
946
|
+
calc(var(--bones-bar-top) + 0.5ex),
|
|
947
|
+
#000 calc(100% - 0.5px),
|
|
948
|
+
transparent 100%
|
|
949
|
+
);
|
|
950
|
+
mask-size:
|
|
951
|
+
calc(100% - 2 * var(--bones-inset)) 1lh,
|
|
952
|
+
50% 1lh,
|
|
953
|
+
50% 1lh;
|
|
954
|
+
mask-position:
|
|
955
|
+
var(--bones-inset) 0,
|
|
956
|
+
left 0,
|
|
957
|
+
right 0;
|
|
958
|
+
mask-repeat: repeat-y;
|
|
959
|
+
mask-origin: content-box;
|
|
960
|
+
mask-clip: content-box;
|
|
961
|
+
}
|
|
962
|
+
&::after {
|
|
963
|
+
top: auto;
|
|
964
|
+
bottom: calc(1lh - var(--bones-bar-top) - 1ex);
|
|
965
|
+
width: var(--bones-last);
|
|
966
|
+
}
|
|
144
967
|
}
|
|
145
|
-
}
|
|
146
968
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
@scope ([data-bone-animate="shimmer"]) to ([data-bone-animate]:not([data-bone-animate="shimmer"])) {
|
|
154
|
-
[data-bone="text"]:is(:scope, :scope *)::after,
|
|
155
|
-
[data-bone="block"]:is(:scope, :scope *),
|
|
156
|
-
[data-bone="container"]:is(:scope, :scope *)::before {
|
|
969
|
+
&[data-bones-type="block"] {
|
|
970
|
+
color: rgb(from currentcolor r g b / 0);
|
|
971
|
+
border-radius: var(--bone-radius);
|
|
972
|
+
border-color: transparent;
|
|
973
|
+
object-position: 9999px 0;
|
|
974
|
+
transition: none;
|
|
157
975
|
animation: bone-shimmer var(--bone-duration) ease-in-out infinite;
|
|
158
976
|
background: linear-gradient(
|
|
159
977
|
90deg,
|
|
@@ -163,11 +981,20 @@ canvas[data-bone="block"] {
|
|
|
163
981
|
);
|
|
164
982
|
background-size: 200% 100%;
|
|
165
983
|
}
|
|
984
|
+
&[data-bones-type="block"] > * {
|
|
985
|
+
visibility: hidden;
|
|
986
|
+
}
|
|
987
|
+
&[data-bones-type="block"]:is(img):is(:not([src]), [src=""]) {
|
|
988
|
+
display: inline-block;
|
|
989
|
+
content: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
|
|
990
|
+
}
|
|
991
|
+
}
|
|
166
992
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
[data-
|
|
170
|
-
[data-
|
|
993
|
+
@media (prefers-reduced-motion: reduce) {
|
|
994
|
+
:is([aria-busy="true"], [aria-busy="true"] *) {
|
|
995
|
+
&:is([data-bones-type="text"], [data-bones-lines])::after,
|
|
996
|
+
&[data-bones-lines]::before,
|
|
997
|
+
&[data-bones-type="block"] {
|
|
171
998
|
animation: bone-pulse 2s ease-in-out infinite;
|
|
172
999
|
background: var(--bone-base);
|
|
173
1000
|
background-size: auto;
|
|
@@ -175,30 +1002,70 @@ canvas[data-bone="block"] {
|
|
|
175
1002
|
}
|
|
176
1003
|
}
|
|
177
1004
|
|
|
178
|
-
@
|
|
179
|
-
[
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
1005
|
+
@media (forced-colors: active) {
|
|
1006
|
+
:is([aria-busy="true"], [aria-busy="true"] *) {
|
|
1007
|
+
&:is([data-bones-type="text"], [data-bones-lines])::after,
|
|
1008
|
+
&[data-bones-lines]::before,
|
|
1009
|
+
&[data-bones-type="block"] {
|
|
1010
|
+
background-color: GrayText;
|
|
1011
|
+
forced-color-adjust: none;
|
|
1012
|
+
}
|
|
185
1013
|
}
|
|
1014
|
+
}
|
|
186
1015
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
[data-
|
|
190
|
-
[data-
|
|
191
|
-
|
|
1016
|
+
@scope ([data-bones-animate="shimmer"]) to ([data-bones-animate]:not([data-bones-animate="shimmer"])) {
|
|
1017
|
+
:is([aria-busy="true"], [aria-busy="true"] *):is(:scope, :scope *) {
|
|
1018
|
+
&:is([data-bones-type="text"], [data-bones-lines])::after,
|
|
1019
|
+
&[data-bones-lines]::before,
|
|
1020
|
+
&[data-bones-type="block"] {
|
|
1021
|
+
animation: bone-shimmer var(--bone-duration) ease-in-out infinite;
|
|
1022
|
+
background: linear-gradient(
|
|
1023
|
+
90deg,
|
|
1024
|
+
var(--bone-base) 25%,
|
|
1025
|
+
var(--bone-highlight) 50%,
|
|
1026
|
+
var(--bone-base) 75%
|
|
1027
|
+
);
|
|
1028
|
+
background-size: 200% 100%;
|
|
1029
|
+
}
|
|
1030
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1031
|
+
&:is([data-bones-type="text"], [data-bones-lines])::after,
|
|
1032
|
+
&[data-bones-lines]::before,
|
|
1033
|
+
&[data-bones-type="block"] {
|
|
1034
|
+
animation: bone-pulse 2s ease-in-out infinite;
|
|
1035
|
+
background: var(--bone-base);
|
|
1036
|
+
background-size: auto;
|
|
1037
|
+
}
|
|
192
1038
|
}
|
|
193
1039
|
}
|
|
194
1040
|
}
|
|
195
1041
|
|
|
196
|
-
@scope ([data-
|
|
197
|
-
[
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
1042
|
+
@scope ([data-bones-animate="pulse"]) to ([data-bones-animate]:not([data-bones-animate="pulse"])) {
|
|
1043
|
+
:is([aria-busy="true"], [aria-busy="true"] *):is(:scope, :scope *) {
|
|
1044
|
+
&:is([data-bones-type="text"], [data-bones-lines])::after,
|
|
1045
|
+
&[data-bones-lines]::before,
|
|
1046
|
+
&[data-bones-type="block"] {
|
|
1047
|
+
animation: bone-pulse var(--bone-duration) ease-in-out infinite;
|
|
1048
|
+
background: var(--bone-base);
|
|
1049
|
+
background-size: auto;
|
|
1050
|
+
}
|
|
1051
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1052
|
+
&:is([data-bones-type="text"], [data-bones-lines])::after,
|
|
1053
|
+
&[data-bones-lines]::before,
|
|
1054
|
+
&[data-bones-type="block"] {
|
|
1055
|
+
animation: bone-pulse 2s ease-in-out infinite;
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
@scope ([data-bones-animate="none"]) to ([data-bones-animate]:not([data-bones-animate="none"])) {
|
|
1062
|
+
:is([aria-busy="true"], [aria-busy="true"] *):is(:scope, :scope *) {
|
|
1063
|
+
&:is([data-bones-type="text"], [data-bones-lines])::after,
|
|
1064
|
+
&[data-bones-lines]::before,
|
|
1065
|
+
&[data-bones-type="block"] {
|
|
1066
|
+
animation: none;
|
|
1067
|
+
background: var(--bone-base);
|
|
1068
|
+
background-size: auto;
|
|
1069
|
+
}
|
|
203
1070
|
}
|
|
204
1071
|
}
|