@slotted/styles 0.1.0-beta.4 → 0.1.0-beta.5

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.
@@ -218,28 +218,32 @@
218
218
  * number is broken only when it is wider than the card itself. A floor on
219
219
  * the trend was tried and pushed the trend through the card's edge.
220
220
  */
221
- [data-ui='stat-card'] [data-part='body'] {
222
- column-gap: var(--_trend-gap);
223
- display: grid;
224
- flex: 1 1 auto;
225
- grid-template-areas:
226
- 'header header'
227
- 'figure trend'
228
- 'message message';
229
- grid-template-columns: minmax(min-content, 1fr) minmax(0, var(--_trend-size));
230
- grid-template-rows: auto minmax(0, 1fr) auto;
231
- min-inline-size: 0;
232
- row-gap: var(--_region-gap);
233
- }
234
-
235
- [data-ui='stat-card'][data-layout='stacked'] [data-part='body'] {
236
- grid-template-areas:
237
- 'header'
238
- 'figure'
239
- 'trend'
240
- 'message';
241
- grid-template-columns: minmax(0, 1fr);
242
- grid-template-rows: auto minmax(0, 1fr) auto auto;
221
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
222
+ :scope [data-part='body'] {
223
+ column-gap: var(--_trend-gap);
224
+ display: grid;
225
+ flex: 1 1 auto;
226
+ grid-template-areas:
227
+ 'header header'
228
+ 'figure trend'
229
+ 'message message';
230
+ grid-template-columns: minmax(min-content, 1fr) minmax(0, var(--_trend-size));
231
+ grid-template-rows: auto minmax(0, 1fr) auto;
232
+ min-inline-size: 0;
233
+ row-gap: var(--_region-gap);
234
+ }
235
+ }
236
+
237
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
238
+ :scope[data-layout='stacked'] [data-part='body'] {
239
+ grid-template-areas:
240
+ 'header'
241
+ 'figure'
242
+ 'trend'
243
+ 'message';
244
+ grid-template-columns: minmax(0, 1fr);
245
+ grid-template-rows: auto minmax(0, 1fr) auto auto;
246
+ }
243
247
  }
244
248
 
245
249
  /**
@@ -250,15 +254,19 @@
250
254
  * inline axis gives these regions no intrinsic width: the figure alone
251
255
  * decides the column, and the text is cut or wrapped by the card's width.
252
256
  */
253
- [data-ui='stat-card'] [data-part='header'] {
254
- contain: inline-size;
255
- grid-area: header;
257
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
258
+ :scope [data-part='header'] {
259
+ contain: inline-size;
260
+ grid-area: header;
261
+ }
256
262
  }
257
263
 
258
- [data-ui='stat-card'] [data-part='figure'] {
259
- align-self: start;
260
- grid-area: figure;
261
- min-inline-size: 0;
264
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
265
+ :scope [data-part='figure'] {
266
+ align-self: start;
267
+ grid-area: figure;
268
+ min-inline-size: 0;
269
+ }
262
270
  }
263
271
 
264
272
  /**
@@ -268,32 +276,40 @@
268
276
  * width is the space a wide value left, which a query on the card cannot
269
277
  * see.
270
278
  */
271
- [data-ui='stat-card'] [data-part='trend'] {
272
- /* The marker's ring is the card's ground, not the page's. */
273
- --slotted-sparkline-ring-color: var(--_surface);
274
-
275
- align-self: center;
276
- container-name: stat-card-trend;
277
- container-type: inline-size;
278
- grid-area: trend;
279
- inline-size: 100%;
280
- min-inline-size: 0;
279
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
280
+ :scope [data-part='trend'] {
281
+ /* The marker's ring is the card's ground, not the page's. */
282
+ --slotted-sparkline-ring-color: var(--_surface);
283
+
284
+ align-self: center;
285
+ container-name: stat-card-trend;
286
+ container-type: inline-size;
287
+ grid-area: trend;
288
+ inline-size: 100%;
289
+ min-inline-size: 0;
290
+ }
281
291
  }
282
292
 
283
293
  @container stat-card-trend (max-width: 39px) {
284
- [data-ui='stat-card'] [data-part='trend'] > * {
285
- visibility: hidden;
294
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
295
+ :scope [data-part='trend'] > * {
296
+ visibility: hidden;
297
+ }
286
298
  }
287
299
  }
288
300
 
289
- [data-ui='stat-card'][data-layout='stacked'] [data-part='trend'] {
290
- align-self: end;
291
- margin-block-start: var(--slotted-space-2, 0.25rem);
301
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
302
+ :scope[data-layout='stacked'] [data-part='trend'] {
303
+ align-self: end;
304
+ margin-block-start: var(--slotted-space-2, 0.25rem);
305
+ }
292
306
  }
293
307
 
294
- [data-ui='stat-card'] [data-part='message'] {
295
- contain: inline-size;
296
- grid-area: message;
308
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
309
+ :scope [data-part='message'] {
310
+ contain: inline-size;
311
+ grid-area: message;
312
+ }
297
313
  }
298
314
 
299
315
  /**
@@ -303,29 +319,37 @@
303
319
  * (`docs/token-foundation.md`, rule 4).
304
320
  */
305
321
  @container stat-card (max-width: 219px) {
306
- [data-ui='stat-card'] [data-part='body'] {
307
- grid-template-areas:
308
- 'header'
309
- 'figure'
310
- 'trend'
311
- 'message';
312
- grid-template-columns: minmax(0, 1fr);
313
- grid-template-rows: auto minmax(0, 1fr) auto auto;
322
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
323
+ :scope [data-part='body'] {
324
+ grid-template-areas:
325
+ 'header'
326
+ 'figure'
327
+ 'trend'
328
+ 'message';
329
+ grid-template-columns: minmax(0, 1fr);
330
+ grid-template-rows: auto minmax(0, 1fr) auto auto;
331
+ }
314
332
  }
315
333
 
316
- [data-ui='stat-card'] [data-part='trend'] {
317
- align-self: end;
318
- margin-block-start: var(--slotted-space-2, 0.25rem);
334
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
335
+ :scope [data-part='trend'] {
336
+ align-self: end;
337
+ margin-block-start: var(--slotted-space-2, 0.25rem);
338
+ }
319
339
  }
320
340
 
321
- [data-ui='stat-card'] [data-part='value'] {
322
- font-size: var(--_value-size-narrow);
323
- line-height: var(--_value-line-narrow);
341
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
342
+ :scope [data-part='value'] {
343
+ font-size: var(--_value-size-narrow);
344
+ line-height: var(--_value-line-narrow);
345
+ }
324
346
  }
325
347
 
326
348
  /* The value steps down here, and so does the line its placeholder keeps. */
327
- [data-ui='stat-card'][data-loading] [data-part='value'] {
328
- min-block-size: calc(var(--_value-size-narrow) * var(--_value-line-narrow));
349
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
350
+ :scope[data-loading] [data-part='value'] {
351
+ min-block-size: calc(var(--_value-size-narrow) * var(--_value-line-narrow));
352
+ }
329
353
  }
330
354
  }
331
355
 
@@ -337,13 +361,15 @@
337
361
  * them as part of the name, instead of floating them at the middle of the
338
362
  * block.
339
363
  */
340
- [data-ui='stat-card'] [data-part='header'] {
341
- align-items: baseline;
342
- column-gap: var(--slotted-space-3, 0.375rem);
343
- display: flex;
344
- flex-wrap: wrap;
345
- min-inline-size: 0;
346
- row-gap: var(--slotted-space-2, 0.25rem);
364
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
365
+ :scope [data-part='header'] {
366
+ align-items: baseline;
367
+ column-gap: var(--slotted-space-3, 0.375rem);
368
+ display: flex;
369
+ flex-wrap: wrap;
370
+ min-inline-size: 0;
371
+ row-gap: var(--slotted-space-2, 0.25rem);
372
+ }
347
373
  }
348
374
 
349
375
  /**
@@ -355,32 +381,38 @@
355
381
  * proportion of the type rather than a scale step: it is a width of
356
382
  * words, and it scales with them.
357
383
  */
358
- [data-ui='stat-card'] [data-part='label'] {
359
- color: var(--_ink-muted);
360
- flex: 1 1 0%;
361
- font-size: var(--_label-size);
362
- font-weight: var(--slotted-font-weight-medium, 500);
363
- line-height: var(--_label-line);
364
- margin: 0;
365
- min-inline-size: min(100%, 10rem);
366
- overflow-wrap: break-word;
384
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
385
+ :scope [data-part='label'] {
386
+ color: var(--_ink-muted);
387
+ flex: 1 1 0%;
388
+ font-size: var(--_label-size);
389
+ font-weight: var(--slotted-font-weight-medium, 500);
390
+ line-height: var(--_label-line);
391
+ margin: 0;
392
+ min-inline-size: min(100%, 10rem);
393
+ overflow-wrap: break-word;
394
+ }
367
395
  }
368
396
 
369
- [data-ui='stat-card'] [data-part='status'] {
370
- display: inline-flex;
371
- flex: none;
397
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
398
+ :scope [data-part='status'] {
399
+ display: inline-flex;
400
+ flex: none;
401
+ }
372
402
  }
373
403
 
374
404
  /* The action takes the end of the header's first line and stays there
375
405
  when the label wraps: it is the one thing on the card the reader presses,
376
406
  and a corner is where a control is looked for. */
377
- [data-ui='stat-card'] [data-part='action'] {
378
- flex: none;
379
- /* The label's line, so a link here is as tall in the fallback face as in
380
- the web face and the header does not grow when the font arrives. */
381
- font-size: var(--_label-size);
382
- line-height: var(--_label-line);
383
- margin-inline-start: auto;
407
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
408
+ :scope [data-part='action'] {
409
+ flex: none;
410
+ /* The label's line, so a link here is as tall in the fallback face as in
411
+ the web face and the header does not grow when the font arrives. */
412
+ font-size: var(--_label-size);
413
+ line-height: var(--_label-line);
414
+ margin-inline-start: auto;
415
+ }
384
416
  }
385
417
 
386
418
  /* On a finger the card's one control is a full target among 44-pixel
@@ -388,16 +420,19 @@
388
420
  part itself when `render` made it one — reaches
389
421
  the comfortable size in both axes, and the header keeps its height. */
390
422
  @media (pointer: coarse) {
391
- [data-ui='stat-card']
392
- :is([data-part='action']:is(a, button), [data-part='action'] > :is(a, button)) {
393
- position: relative;
423
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
424
+ :scope :is([data-part='action']:is(a, button), [data-part='action'] > :is(a, button)) {
425
+ position: relative;
426
+ }
394
427
  }
395
428
 
396
- [data-ui='stat-card']
397
- :is([data-part='action']:is(a, button), [data-part='action'] > :is(a, button))::before {
398
- content: '';
399
- inset: min(0px, calc((100% - var(--slotted-target-comfortable, 44px)) / 2));
400
- position: absolute;
429
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
430
+ :scope
431
+ :is([data-part='action']:is(a, button), [data-part='action'] > :is(a, button))::before {
432
+ content: '';
433
+ inset: min(0px, calc((100% - var(--slotted-target-comfortable, 44px)) / 2));
434
+ position: absolute;
435
+ }
401
436
  }
402
437
  }
403
438
 
@@ -409,17 +444,21 @@
409
444
  * so a delta that does not fit beside a wide number drops under it rather
410
445
  * than pushing the number.
411
446
  */
412
- [data-ui='stat-card'] [data-part='figure'] {
413
- align-items: baseline;
414
- column-gap: var(--slotted-space-3, 0.375rem);
415
- display: flex;
416
- flex-wrap: wrap;
417
- row-gap: 0;
447
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
448
+ :scope [data-part='figure'] {
449
+ align-items: baseline;
450
+ column-gap: var(--slotted-space-3, 0.375rem);
451
+ display: flex;
452
+ flex-wrap: wrap;
453
+ row-gap: 0;
454
+ }
418
455
  }
419
456
 
420
- [data-ui='stat-card'] [data-part='comparison'] {
421
- contain: inline-size;
422
- flex: 1 1 100%;
457
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
458
+ :scope [data-part='comparison'] {
459
+ contain: inline-size;
460
+ flex: 1 1 100%;
461
+ }
423
462
  }
424
463
 
425
464
  /**
@@ -432,40 +471,44 @@
432
471
  * to pull a large numeral's counters back together, and it is the same
433
472
  * fraction at every size.
434
473
  */
435
- [data-ui='stat-card'] [data-part='value'] {
436
- /* The figure and its unit are two flex items on one baseline — the text
437
- node is an item of its own — so the gap spaces the unit from the digit
438
- on whichever side it stands. A margin on the unit, reset by
439
- `:first-child` for a leading unit, hugged a trailing one: after a bare
440
- figure the unit is the first element child. */
441
- align-items: baseline;
442
- color: var(--_ink);
443
- display: inline-flex;
444
- flex-wrap: wrap;
445
- gap: 0.15em;
446
- font-size: var(--_value-size);
447
- font-variant-numeric: proportional-nums;
448
- font-weight: var(--slotted-font-weight-semibold, 600);
449
- /* The figure is set at the 3xl or 4xl step, where the theme's tighter
450
- tracking applies. */
451
- letter-spacing: var(--slotted-letter-spacing-tighter, -0.03em);
452
- unicode-bidi: plaintext;
453
- line-height: var(--_value-line);
454
- margin: 0;
455
- min-inline-size: 0;
456
- /* A number is never truncated: a value wider than its column breaks
457
- rather than clips, and a consumer who wants it whole formats it
458
- compact or stacks the card. */
459
- overflow-wrap: break-word;
474
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
475
+ :scope [data-part='value'] {
476
+ /* The figure and its unit are two flex items on one baseline — the text
477
+ node is an item of its own — so the gap spaces the unit from the digit
478
+ on whichever side it stands. A margin on the unit, reset by
479
+ `:first-child` for a leading unit, hugged a trailing one: after a bare
480
+ figure the unit is the first element child. */
481
+ align-items: baseline;
482
+ color: var(--_ink);
483
+ display: inline-flex;
484
+ flex-wrap: wrap;
485
+ gap: 0.15em;
486
+ font-size: var(--_value-size);
487
+ font-variant-numeric: proportional-nums;
488
+ font-weight: var(--slotted-font-weight-semibold, 600);
489
+ /* The figure is set at the 3xl or 4xl step, where the theme's tighter
490
+ tracking applies. */
491
+ letter-spacing: var(--slotted-letter-spacing-tighter, -0.03em);
492
+ unicode-bidi: plaintext;
493
+ line-height: var(--_value-line);
494
+ margin: 0;
495
+ min-inline-size: 0;
496
+ /* A number is never truncated: a value wider than its column breaks
497
+ rather than clips, and a consumer who wants it whole formats it
498
+ compact or stacks the card. */
499
+ overflow-wrap: break-word;
500
+ }
460
501
  }
461
502
 
462
503
  /* The unit is in the value's own line, a step down in size and weight, so
463
504
  `$` and `%` read as annotation of the number rather than as digits. */
464
- [data-ui='stat-card'] [data-part='unit'] {
465
- color: var(--_ink-muted);
466
- font-size: var(--_delta-size);
467
- font-weight: var(--slotted-font-weight-medium, 500);
468
- letter-spacing: 0;
505
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
506
+ :scope [data-part='unit'] {
507
+ color: var(--_ink-muted);
508
+ font-size: var(--_delta-size);
509
+ font-weight: var(--slotted-font-weight-medium, 500);
510
+ letter-spacing: 0;
511
+ }
469
512
  }
470
513
 
471
514
  /**
@@ -474,44 +517,58 @@
474
517
  * metrics, and the tone's text role already clears the reading ratio on
475
518
  * the surface. It sits on the value's baseline.
476
519
  */
477
- [data-ui='stat-card'] [data-part='delta'] {
478
- align-items: center;
479
- color: var(--_tone-text);
480
- column-gap: var(--slotted-space-1, 0.125rem);
481
- display: inline-flex;
482
- font-size: var(--_delta-size);
483
- font-variant-numeric: tabular-nums;
484
- font-weight: var(--slotted-font-weight-semibold, 600);
485
- line-height: 1;
486
- /* A signed number is a run of its own: in a right-to-left document the
487
- sign of `+12.4%` is a neutral character and drifts to the far end of
488
- the run, so the run is laid out by its own content. */
489
- unicode-bidi: plaintext;
490
- white-space: nowrap;
491
- }
492
-
493
- [data-ui='stat-card'] [data-part='delta'][data-tone='neutral'] {
494
- --_tone-text: var(--_ink-muted);
520
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
521
+ :scope [data-part='delta'] {
522
+ align-items: center;
523
+ color: var(--_tone-text);
524
+ column-gap: var(--slotted-space-1, 0.125rem);
525
+ display: inline-flex;
526
+ font-size: var(--_delta-size);
527
+ font-variant-numeric: tabular-nums;
528
+ font-weight: var(--slotted-font-weight-semibold, 600);
529
+ line-height: 1;
530
+ /* A signed number is a run of its own: in a right-to-left document the
531
+ sign of `+12.4%` is a neutral character and drifts to the far end of
532
+ the run, so the run is laid out by its own content. */
533
+ unicode-bidi: plaintext;
534
+ white-space: nowrap;
535
+ }
536
+ }
537
+
538
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
539
+ :scope [data-part='delta'][data-tone='neutral'] {
540
+ --_tone-text: var(--_ink-muted);
541
+ }
495
542
  }
496
543
 
497
- [data-ui='stat-card'] [data-part='delta'][data-tone='accent'] {
498
- --_tone-text: var(--slotted-tone-accent-text);
544
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
545
+ :scope [data-part='delta'][data-tone='accent'] {
546
+ --_tone-text: var(--slotted-tone-accent-text);
547
+ }
499
548
  }
500
549
 
501
- [data-ui='stat-card'] [data-part='delta'][data-tone='secondary'] {
502
- --_tone-text: var(--slotted-tone-secondary-text);
550
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
551
+ :scope [data-part='delta'][data-tone='secondary'] {
552
+ --_tone-text: var(--slotted-tone-secondary-text);
553
+ }
503
554
  }
504
555
 
505
- [data-ui='stat-card'] [data-part='delta'][data-tone='success'] {
506
- --_tone-text: var(--slotted-tone-success-text);
556
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
557
+ :scope [data-part='delta'][data-tone='success'] {
558
+ --_tone-text: var(--slotted-tone-success-text);
559
+ }
507
560
  }
508
561
 
509
- [data-ui='stat-card'] [data-part='delta'][data-tone='warning'] {
510
- --_tone-text: var(--slotted-tone-warning-text);
562
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
563
+ :scope [data-part='delta'][data-tone='warning'] {
564
+ --_tone-text: var(--slotted-tone-warning-text);
565
+ }
511
566
  }
512
567
 
513
- [data-ui='stat-card'] [data-part='delta'][data-tone='danger'] {
514
- --_tone-text: var(--slotted-tone-danger-text);
568
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
569
+ :scope [data-part='delta'][data-tone='danger'] {
570
+ --_tone-text: var(--slotted-tone-danger-text);
571
+ }
515
572
  }
516
573
 
517
574
  /**
@@ -522,38 +579,43 @@
522
579
  * change draws `minus`. The binding renders the glyph inside the icon box;
523
580
  * the part hands the box its size, and the box inherits the delta's ink.
524
581
  */
525
- [data-ui='stat-card'] [data-part='indicator'] {
526
- --slotted-icon-size: var(--_indicator-size);
582
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
583
+ :scope [data-part='indicator'] {
584
+ --slotted-icon-size: var(--_indicator-size);
527
585
 
528
- display: inline-flex;
529
- flex: none;
586
+ display: inline-flex;
587
+ flex: none;
588
+ }
530
589
  }
531
590
 
532
591
  /* A reflection across the horizontal axis, not motion: nothing travels when
533
592
  a rise becomes a fall. Time runs from the right in a right-to-left
534
593
  document, so the rise points the other way there, as the sparkline beside
535
594
  it does — the `directional` icon box the binding draws does that. */
536
- [data-ui='stat-card']
537
- [data-part='delta'][data-trend='down']
538
- [data-part='indicator']
539
- > [data-ui='icon'] {
540
- rotate: x 180deg;
595
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
596
+ :scope [data-part='delta'][data-trend='down'] [data-part='indicator'] > [data-ui='icon'] {
597
+ rotate: x 180deg;
598
+ }
541
599
  }
542
600
 
543
601
  /* ── Comparison: the prose under the figure ───────────────────────────── */
544
602
 
545
- [data-ui='stat-card'] [data-part='comparison'] {
546
- color: var(--_ink-muted);
547
- font-size: var(--_prose-size);
548
- line-height: var(--_prose-line);
549
- margin-block-start: var(--_region-gap);
550
- margin: 0;
551
- min-inline-size: 0;
552
- overflow-wrap: anywhere;
603
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
604
+ :scope [data-part='comparison'] {
605
+ color: var(--_ink-muted);
606
+ font-size: var(--_prose-size);
607
+ line-height: var(--_prose-line);
608
+ margin-block-start: var(--_region-gap);
609
+ margin: 0;
610
+ min-inline-size: 0;
611
+ overflow-wrap: anywhere;
612
+ }
553
613
  }
554
614
 
555
- [data-ui='stat-card'] [data-part='period'] {
556
- color: var(--_ink-muted);
615
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
616
+ :scope [data-part='period'] {
617
+ color: var(--_ink-muted);
618
+ }
557
619
  }
558
620
 
559
621
  /* ── Trend: where a sparkline goes ────────────────────────────────────── */
@@ -566,55 +628,75 @@
566
628
  * — a card with no delta, or a metric with no valence, draws its trend in
567
629
  * the theme's blue and not in grey.
568
630
  */
569
- [data-ui='stat-card'] [data-part='trend'] {
570
- align-self: center;
571
- display: flex;
631
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
632
+ :scope [data-part='trend'] {
633
+ align-self: center;
634
+ display: flex;
635
+ }
572
636
  }
573
637
 
574
- [data-ui='stat-card'][data-tone='success'] [data-part='trend'] {
575
- --slotted-sparkline-color: var(--slotted-tone-success-text);
638
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
639
+ :scope[data-tone='success'] [data-part='trend'] {
640
+ --slotted-sparkline-color: var(--slotted-tone-success-text);
641
+ }
576
642
  }
577
643
 
578
- [data-ui='stat-card'][data-tone='danger'] [data-part='trend'] {
579
- --slotted-sparkline-color: var(--slotted-tone-danger-text);
644
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
645
+ :scope[data-tone='danger'] [data-part='trend'] {
646
+ --slotted-sparkline-color: var(--slotted-tone-danger-text);
647
+ }
580
648
  }
581
649
 
582
- [data-ui='stat-card'][data-tone='warning'] [data-part='trend'] {
583
- --slotted-sparkline-color: var(--slotted-tone-warning-text);
650
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
651
+ :scope[data-tone='warning'] [data-part='trend'] {
652
+ --slotted-sparkline-color: var(--slotted-tone-warning-text);
653
+ }
584
654
  }
585
655
 
586
- [data-ui='stat-card'][data-tone='accent'] [data-part='trend'] {
587
- --slotted-sparkline-color: var(--slotted-tone-accent-text);
656
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
657
+ :scope[data-tone='accent'] [data-part='trend'] {
658
+ --slotted-sparkline-color: var(--slotted-tone-accent-text);
659
+ }
588
660
  }
589
661
 
590
- [data-ui='stat-card'][data-tone='secondary'] [data-part='trend'] {
591
- --slotted-sparkline-color: var(--slotted-tone-secondary-text);
662
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
663
+ :scope[data-tone='secondary'] [data-part='trend'] {
664
+ --slotted-sparkline-color: var(--slotted-tone-secondary-text);
665
+ }
592
666
  }
593
667
 
594
- [data-ui='stat-card'][data-fill='plain'] [data-part='trend'] {
595
- --slotted-sparkline-ring-color: var(--slotted-surface-raised, Canvas);
668
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
669
+ :scope[data-fill='plain'] [data-part='trend'] {
670
+ --slotted-sparkline-ring-color: var(--slotted-surface-raised, Canvas);
671
+ }
596
672
  }
597
673
 
598
674
  /* ── Message: what stands in for a value that is missing or failed ────── */
599
675
 
600
- [data-ui='stat-card'] [data-part='message'] {
601
- color: var(--_ink-muted);
602
- font-size: var(--_prose-size);
603
- line-height: var(--_prose-line);
604
- margin: 0;
605
- min-inline-size: 0;
606
- overflow-wrap: anywhere;
676
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
677
+ :scope [data-part='message'] {
678
+ color: var(--_ink-muted);
679
+ font-size: var(--_prose-size);
680
+ line-height: var(--_prose-line);
681
+ margin: 0;
682
+ min-inline-size: 0;
683
+ overflow-wrap: anywhere;
684
+ }
607
685
  }
608
686
 
609
- [data-ui='stat-card'][data-status='error'] [data-part='message'] {
610
- color: var(--slotted-tone-danger-text);
687
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
688
+ :scope[data-status='error'] [data-part='message'] {
689
+ color: var(--slotted-tone-danger-text);
690
+ }
611
691
  }
612
692
 
613
693
  /* A value that is not there is a dash in the muted step, at the value's
614
694
  own size, so the row keeps its height and its rhythm. */
615
- [data-ui='stat-card'][data-status='empty'] [data-part='value'],
616
- [data-ui='stat-card'][data-status='error'] [data-part='value'] {
617
- color: var(--_ink-muted);
695
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
696
+ :scope[data-status='empty'] [data-part='value'],
697
+ :scope[data-status='error'] [data-part='value'] {
698
+ color: var(--_ink-muted);
699
+ }
618
700
  }
619
701
 
620
702
  /* ── Loading ──────────────────────────────────────────────────────────── */
@@ -634,28 +716,36 @@
634
716
  * arrived. The floor is one line of the value's own type, so the two states
635
717
  * occupy the same box.
636
718
  */
637
- [data-ui='stat-card'][data-loading] [data-part='value'] {
638
- min-block-size: calc(var(--_value-size) * var(--_value-line));
719
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
720
+ :scope[data-loading] [data-part='value'] {
721
+ min-block-size: calc(var(--_value-size) * var(--_value-line));
722
+ }
639
723
  }
640
724
 
641
- [data-ui='stat-card'][data-loading] [data-part='trend'] {
642
- --slotted-skeleton-block-size: var(
643
- --slotted-sparkline-block-size,
644
- var(--slotted-space-9, 2rem)
645
- );
725
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
726
+ :scope[data-loading] [data-part='trend'] {
727
+ --slotted-skeleton-block-size: var(
728
+ --slotted-sparkline-block-size,
729
+ var(--slotted-space-9, 2rem)
730
+ );
731
+ }
646
732
  }
647
733
 
648
- [data-ui='stat-card'][data-loading][data-size='sm'] [data-part='trend'] {
649
- --slotted-skeleton-block-size: var(
650
- --slotted-sparkline-block-size-sm,
651
- var(--slotted-space-7, 1.25rem)
652
- );
734
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
735
+ :scope[data-loading][data-size='sm'] [data-part='trend'] {
736
+ --slotted-skeleton-block-size: var(
737
+ --slotted-sparkline-block-size-sm,
738
+ var(--slotted-space-7, 1.25rem)
739
+ );
740
+ }
653
741
  }
654
742
 
655
- [data-ui='stat-card'][data-loading][data-size='lg'] [data-part='trend'] {
656
- --slotted-skeleton-block-size: var(
657
- --slotted-sparkline-block-size-lg,
658
- var(--slotted-space-11, 3rem)
659
- );
743
+ @scope ([data-ui='stat-card']) to ([data-ui]:not(:scope) > *) {
744
+ :scope[data-loading][data-size='lg'] [data-part='trend'] {
745
+ --slotted-skeleton-block-size: var(
746
+ --slotted-sparkline-block-size-lg,
747
+ var(--slotted-space-11, 3rem)
748
+ );
749
+ }
660
750
  }
661
751
  }