@wtfalch/design 0.9.0 → 0.9.1

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/dist/tf.css CHANGED
@@ -287,12 +287,9 @@
287
287
  --font-sans: var(--font-sans);
288
288
  --font-mono: var(--font-mono);
289
289
  --text-xs: var(--text-xs);
290
- --text-xs--line-height: inherit;
291
290
  --text-sm: var(--text-sm);
292
- --text-sm--line-height: inherit;
293
291
  --text-base: var(--text-base);
294
292
  --text-lg: var(--text-lg);
295
- --text-lg--line-height: inherit;
296
293
  --text-xl: var(--text-xl);
297
294
  --font-weight-normal: var(--weight);
298
295
  --tracking-normal: var(--tracking);
@@ -307,14 +304,12 @@
307
304
  --spacing-5: var(--space-5);
308
305
  --spacing-6: var(--space-6);
309
306
  --spacing-10: var(--space-10);
310
- --text-2xs--line-height: inherit;
311
307
  --text-2xs: var(--text-2xs);
312
308
  --text-md: var(--text-md);
313
309
  --font-weight-strong: var(--weight-strong);
314
310
  --radius-pill: var(--radius-pill);
315
311
  --color-text: var(--text);
316
312
  --color-muted: var(--muted);
317
- --color-accent: var(--accent);
318
313
  --color-border: var(--border);
319
314
  --color-border-strong: var(--border-strong);
320
315
  }
@@ -570,9 +565,6 @@
570
565
  --tw-border-style: dashed;
571
566
  border-style: dashed;
572
567
  }
573
- .border-accent {
574
- border-color: var(--color-accent);
575
- }
576
568
  .border-border {
577
569
  border-color: var(--color-border);
578
570
  }
@@ -623,19 +615,15 @@
623
615
  }
624
616
  .text-2xs {
625
617
  font-size: var(--text-2xs);
626
- line-height: var(--tw-leading, var(--text-2xs--line-height));
627
618
  }
628
619
  .text-lg {
629
620
  font-size: var(--text-lg);
630
- line-height: var(--tw-leading, var(--text-lg--line-height));
631
621
  }
632
622
  .text-sm {
633
623
  font-size: var(--text-sm);
634
- line-height: var(--tw-leading, var(--text-sm--line-height));
635
624
  }
636
625
  .text-xs {
637
626
  font-size: var(--text-xs);
638
- line-height: var(--tw-leading, var(--text-xs--line-height));
639
627
  }
640
628
  .leading-\[0\] {
641
629
  --tw-leading: 0;
@@ -690,9 +678,6 @@
690
678
  --tw-numeric-spacing: tabular-nums;
691
679
  font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);
692
680
  }
693
- .opacity-0 {
694
- opacity: 0%;
695
- }
696
681
  .opacity-60 {
697
682
  opacity: 60%;
698
683
  }
@@ -735,9 +720,6 @@
735
720
  .surface-panel {
736
721
  background: var(--panel);
737
722
  }
738
- .surface-panel-2 {
739
- background: var(--panel-2);
740
- }
741
723
  .disabled\:cursor-default:disabled {
742
724
  cursor: default;
743
725
  }
@@ -977,7 +959,19 @@
977
959
  }
978
960
  }
979
961
 
980
- /* ---- ./base.css ---- */
962
+ /* ---- ./_system-light.css ---- */
963
+ /* The `system` theme's light half.
964
+ *
965
+ * Its own file, and outside the components layer, because it is a *theme*
966
+ * rather than a component rule. `tokens.css` states the dark base on `:root`
967
+ * and is unlayered; the moment this sat inside `@layer components` it lost to
968
+ * that, and every `system` specimen rendered dark on a light-mode machine.
969
+ * Unlayered beats layered whatever the selector says, which is exactly the
970
+ * trap this repository keeps finding in different costumes.
971
+ *
972
+ * The underscore marks it the same way `_tailwind.built.css` is marked:
973
+ * `copy-css.mjs` passes both through without wrapping them.
974
+ */
981
975
  /* Light, only under the `system` theme. This used to override `:root`
982
976
  unconditionally, so choosing a dark theme on a light-mode laptop got
983
977
  silently repainted. Every other theme states its own palette. */
@@ -1006,6 +1000,8 @@
1006
1000
  }
1007
1001
  }
1008
1002
 
1003
+ /* ---- ./base.css ---- */
1004
+ @layer components {
1009
1005
  /* Derived from the two surfaces every theme already defines, so a theme gets a
1010
1006
  control colour without knowing this exists. */
1011
1007
  /* Pseudo-elements too. `*` does not match them, and `box-sizing` is not
@@ -1866,8 +1862,10 @@ input:active, textarea:active, select:active { transform: none; }
1866
1862
  color: var(--muted);
1867
1863
  opacity: 1;
1868
1864
  }
1865
+ }
1869
1866
 
1870
1867
  /* ---- ./select.css ---- */
1868
+ @layer components {
1871
1869
  /* How big a control is, asked for rather than inherited.
1872
1870
  Four sizes existed and every one of them came from a descendant selector:
1873
1871
  `.set-row button` was 11px in 3px of padding, `.approval-actions button` was
@@ -1962,16 +1960,19 @@ input:active, textarea:active, select:active { transform: none; }
1962
1960
  /* State is read off React Aria's attributes: `data-open` on the root,
1963
1961
  `data-focused` / `data-selected` / `data-disabled` on an item, where
1964
1962
  `.open`, `[data-active]`, `.on` and `.off` used to be. */
1965
- .sel-list { scroll-padding-block: var(--space-1); box-shadow: var(--shadow-2); })` brings up ended flush against the
1966
- border and read as clipped rather than as one of a set -- and this list
1967
- opens scrolled to whatever is chosen, so that was the ordinary state.
1968
- `scroll-padding` insets what counts as "in view", so it stops short by
1969
- the same four the sides have. */
1963
+ /* The list keeps two things the utilities on `Select` cannot say.
1964
+ *
1965
+ * `scroll-padding-block`: the same room while the list is scrolled as it has
1966
+ * at rest. Padding at the top of a scroll container scrolls away with the
1967
+ * content, so the row `scrollIntoView({block: 'nearest'})` brings up ended
1968
+ * flush against the border and read as clipped rather than as one of a set --
1969
+ * and this list opens scrolled to whatever is chosen, so that was the
1970
+ * ordinary state.
1971
+ *
1972
+ * `box-shadow`: `--shadow-2` is a token, and a utility would have to inline
1973
+ * the value, which is the one thing the vocabulary exists to stop. */
1974
+ .sel-list {
1970
1975
  scroll-padding-block: var(--space-1);
1971
- list-style: none;
1972
- border: var(--border-width) solid var(--border-strong);
1973
- border-radius: var(--radius-md);
1974
- background: var(--panel);
1975
1976
  box-shadow: var(--shadow-2);
1976
1977
  }
1977
1978
 
@@ -1986,6 +1987,19 @@ input:active, textarea:active, select:active { transform: none; }
1986
1987
 
1987
1988
  /* The tick marks the chosen row. Colour alone would not: a list where the only
1988
1989
  difference is a hue is a list you cannot read past. */
1990
+ /* The tick's resting state lives here, beside the state that overrides it.
1991
+ *
1992
+ * It was `opacity-0` on the element and `opacity: 1` here, which worked only
1993
+ * while this sheet was unlayered. A utility is in `@layer utilities` and
1994
+ * beats `@layer components` whatever the selector, so the moment the sheets
1995
+ * moved into a layer the tick stopped appearing on the selected row -- the
1996
+ * resting state won permanently.
1997
+ *
1998
+ * The rule generalises: a utility for a resting state whose active state is a
1999
+ * relationship between elements will always beat that active state. The pair
2000
+ * has to sit in the same layer. */
2001
+ .sel-tick { opacity: 0; }
2002
+
1989
2003
  .sel-item[data-selected] .sel-tick { opacity: 1; }
1990
2004
 
1991
2005
  /* The icon on a speaker's row in the open list -- `Select`'s `aside`. Last in
@@ -2020,8 +2034,10 @@ input:active, textarea:active, select:active { transform: none; }
2020
2034
  .field > input,
2021
2035
  .field > textarea,
2022
2036
  .field > .sel { width: 100%; }
2037
+ }
2023
2038
 
2024
2039
  /* ---- ./dangerzone.css ---- */
2040
+ @layer components {
2025
2041
  /* Destructive, and legible as such standing still. */
2026
2042
  .btn.danger {
2027
2043
  color: var(--bad);
@@ -2133,8 +2149,10 @@ input:active, textarea:active, select:active { transform: none; }
2133
2149
  controls in the same column at the same indent that do not line up read as
2134
2150
  an accident rather than as a pair. */
2135
2151
  .field-row > button { min-width: 9ch; }
2152
+ }
2136
2153
 
2137
2154
  /* ---- ./callout.css ---- */
2155
+ @layer components {
2138
2156
  /* One shape for everything that tells you something.
2139
2157
  `.banner` and `.callout` were the same box drawn twice: a bordered, rounded,
2140
2158
  12px panel with a tint. They differed in padding by a pixel in each direction
@@ -2273,8 +2291,10 @@ input:active, textarea:active, select:active { transform: none; }
2273
2291
  }
2274
2292
 
2275
2293
  .callout button { flex: none; }
2294
+ }
2276
2295
 
2277
2296
  /* ---- ./card.css ---- */
2297
+ @layer components {
2278
2298
  /* `.card` is public API, not this component's private styling.
2279
2299
  *
2280
2300
  * Consumers apply it to their own markup -- the gallery's skeleton specimen
@@ -2416,8 +2436,10 @@ input:active, textarea:active, select:active { transform: none; }
2416
2436
  }
2417
2437
 
2418
2438
  .card[aria-pressed='true']:hover { border-color: var(--accent); }
2439
+ }
2419
2440
 
2420
2441
  /* ---- ./toggle.css ---- */
2442
+ @layer components {
2421
2443
  .card-action .switch-row { padding: 0; gap: var(--space-2); }
2422
2444
 
2423
2445
  .card-action .switch-row .switch-body { flex: none; }
@@ -2648,8 +2670,10 @@ input[type='radio']:active:not(:disabled) {
2648
2670
  @media (prefers-reduced-motion: reduce) {
2649
2671
  .toggle-sweep::before { animation: none; background: color-mix(in oklab, var(--accent) 45%, transparent); }
2650
2672
  }
2673
+ }
2651
2674
 
2652
2675
  /* ---- ./skeleton.css ---- */
2676
+ @layer components {
2653
2677
  .muted { color: var(--muted); }
2654
2678
 
2655
2679
  .pulse-block {
@@ -2704,8 +2728,10 @@ input[type='radio']:active:not(:disabled) {
2704
2728
  /* Still distinguishable from a real block of colour, and still still. */
2705
2729
  .skel-pulse { animation: none; opacity: 0.8; }
2706
2730
  }
2731
+ }
2707
2732
 
2708
2733
  /* ---- ./rows.css ---- */
2734
+ @layer components {
2709
2735
  .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2710
2736
 
2711
2737
  /* A name and the pills that qualify it, on one line, where the name is the only
@@ -2966,8 +2992,10 @@ input[type='radio']:active:not(:disabled) {
2966
2992
  .row-hit:hover .truncate { color: var(--accent); }
2967
2993
 
2968
2994
  .row-hit:focus-visible { outline: none; box-shadow: var(--focus-ring); }
2995
+ }
2969
2996
 
2970
2997
  /* ---- ./progress.css ---- */
2998
+ @layer components {
2971
2999
  /* progress ----------------------------------------------------------- */
2972
3000
 
2973
3001
  /* The bar itself: a track with a child it fills, an animation and a
@@ -3009,8 +3037,10 @@ input[type='radio']:active:not(:disabled) {
3009
3037
  /* Still distinguishable from empty, and from full. */
3010
3038
  .bar-indeterminate > i { animation: none; width: 100%; opacity: 0.35; }
3011
3039
  }
3040
+ }
3012
3041
 
3013
3042
  /* ---- ./tabs.css ---- */
3043
+ @layer components {
3014
3044
  /* ---------------------------------------------------------------- tabs */
3015
3045
  .tabs { position: relative; display: flex; gap: var(--space-1); }
3016
3046
 
@@ -3111,8 +3141,10 @@ input[type='radio']:active:not(:disabled) {
3111
3141
  }
3112
3142
 
3113
3143
  .tabs-vertical .tab:active:not(:disabled) { border-color: transparent; }
3144
+ }
3114
3145
 
3115
3146
  /* ---- ./toast.css ---- */
3147
+ @layer components {
3116
3148
  /* ---------------------------------------------------------------- toasts */
3117
3149
  .toasts {
3118
3150
  position: fixed;
@@ -3210,8 +3242,10 @@ input[type='radio']:active:not(:disabled) {
3210
3242
  outline: 2px solid var(--accent);
3211
3243
  outline-offset: 2px;
3212
3244
  }
3245
+ }
3213
3246
 
3214
3247
  /* ---- ./modal.css ---- */
3248
+ @layer components {
3215
3249
  /* modal --------------------------------------------------------------- */
3216
3250
 
3217
3251
  /* `hidden` needs saying out loud here. The browser's own `[hidden]` rule is a
@@ -3442,8 +3476,10 @@ input[type='radio']:active:not(:disabled) {
3442
3476
  .modal.sheet[data-entering],
3443
3477
  .modal.sheet[data-exiting] { animation: none; }
3444
3478
  }
3479
+ }
3445
3480
 
3446
3481
  /* ---- ./slider.css ---- */
3482
+ @layer components {
3447
3483
  /* slider ----------------------------------------------------------------- */
3448
3484
  /* A number from a range -- `Slider.tsx` says when one is the right control.
3449
3485
  The row is laid out like a switch row: words on the left, the control on the
@@ -3665,8 +3701,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
3665
3701
  the scale, and the two line up; an explicit `size-*` still wins. */
3666
3702
  :where(.set-row) button,
3667
3703
  :where(.set-row) .slider-box { font-size: var(--text-xs); }
3704
+ }
3668
3705
 
3669
3706
  /* ---- ./checkbox.css ---- */
3707
+ @layer components {
3670
3708
  /* A row you choose. There is no checkbox in it.
3671
3709
  Every one of the fourteen in this app sits beside a name and a line of
3672
3710
  explanation, so the row was always the thing being designed and the 17px
@@ -3836,8 +3874,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
3836
3874
  .choice[data-disabled] .choice-why { opacity: 0.5; }
3837
3875
 
3838
3876
  .choice[data-disabled]::after { opacity: 0.4; }
3877
+ }
3839
3878
 
3840
3879
  /* ---- ./table.css ---- */
3880
+ @layer components {
3841
3881
  /* A second line under a row's name, inside the `<th scope="row">` that makes it
3842
3882
  one. The cell is bold because it is a heading; what hangs under it is not,
3843
3883
  and inherited the weight -- so a pinned version read as loud as the thing it
@@ -3885,27 +3925,48 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
3885
3925
  .data-table .num { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
3886
3926
 
3887
3927
  .data-table thead th[style*='right'] { text-align: right; }
3928
+ }
3888
3929
 
3889
3930
  /* ---- ./sizegrid.css ---- */
3890
- /* What is left of the size grid once it draws itself.
3931
+ @layer components {
3932
+ /* The cell's colour, all of it, in one place.
3933
+ *
3934
+ * `SizeGrid` draws the cell's geometry with utilities and leaves every colour
3935
+ * here, because `on` and `chosen` override the resting state -- and a utility
3936
+ * is in `@layer utilities`, which beats `@layer components` whatever the
3937
+ * selector. Stated as `surface-panel-2` and `border-border` on the element,
3938
+ * the resting state won permanently and no cell ever lit up.
3891
3939
  *
3892
- * `on` follows the pointer; `chosen` is what is actually saved, shown only
3893
- * when nothing is hovered so the two can never contradict each other.
3894
- * `chosen` is a border colour and says so at the call site; `on` is a fill
3895
- * mixed from the accent, and `color-mix` in an arbitrary value is less
3896
- * readable than the rule it replaces. */
3940
+ * That is the third time this pattern has bitten: `Select`'s tick and
3941
+ * `Empty`'s figure were the other two. The rule: a resting state whose
3942
+ * active state is a CSS rule has to be a CSS rule too. */
3943
+ .size-cell {
3944
+ border: var(--border-width) solid var(--border);
3945
+ background: var(--panel-2);
3946
+ }
3947
+
3948
+ /* `on` follows the pointer; `chosen` is what is actually saved, shown only
3949
+ when nothing is hovered so the two can never contradict each other. */
3897
3950
  .size-cell.on {
3898
3951
  border-color: var(--accent);
3899
3952
  background: color-mix(in srgb, var(--accent) 45%, transparent);
3900
3953
  }
3901
3954
 
3955
+ .size-cell.chosen { border-color: var(--accent); }
3956
+ }
3957
+
3902
3958
  /* ---- ./tooltip.css ---- */
3959
+ @layer components {
3903
3960
  /* A callout: something worth knowing, with nothing to answer. Distinct from a
3904
3961
  `?`, which is an offer to read more, and from a banner, which is a problem.
3905
3962
  The mark is a round `i` rather than an emoji so it takes the theme's colours
3906
3963
  and stays the same size as the text beside it. */
3907
- /* An info-toned `.callout`, spelled the old way. Identical to it now rather than
3908
- nearly identical to it, which is the whole point of the consolidation: the
3964
+ /* An info-toned `.callout`, spelled the old way. Identical to it now rather
3965
+ than nearly identical to it, which is the whole point of the consolidation.
3966
+ (This comment has been unterminated since before the Tailwind branch -- it
3967
+ stops mid-sentence and never closes, so the CSS parser merged it with the
3968
+ one below and recovered. Nothing was lost from the stylesheet; the rest of
3969
+ the sentence was. Closed here rather than guessed at.) */
3909
3970
 
3910
3971
  /* What is left once `Tooltip` draws its own mark: the hover and focus that
3911
3972
  reach the mark from its parent, and the tip -- whose closed and open
@@ -3988,8 +4049,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
3988
4049
  }
3989
4050
 
3990
4051
  .explain-tip strong { color: var(--text); font-weight: 600; }
4052
+ }
3991
4053
 
3992
4054
  /* ---- ./illustration.css ---- */
4055
+ @layer components {
3993
4056
  /* illustrations -------------------------------------------------------- */
3994
4057
 
3995
4058
  /* Open Peeps, two colours, wearing whatever the theme is.
@@ -4027,8 +4090,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
4027
4090
  * original rule already carried a note about needing two classes to beat
4028
4091
  * `.illo`; layers make that impossible rather than merely fiddly. */
4029
4092
  .nothing-figure { color: var(--muted); }
4093
+ }
4030
4094
 
4031
4095
  /* ---- ./field.css ---- */
4096
+ @layer components {
4032
4097
  /* fields --------------------------------------------------------------- */
4033
4098
 
4034
4099
  /* Label, description, input, error -- in the order they are wanted. The
@@ -4203,8 +4268,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
4203
4268
  background: var(--panel-2);
4204
4269
  color: var(--text);
4205
4270
  }
4271
+ }
4206
4272
 
4207
4273
  /* ---- ./tour.css ---- */
4274
+ @layer components {
4208
4275
  /* tour ----------------------------------------------------------------- */
4209
4276
 
4210
4277
  /* The layer sits over everything and catches nothing: the scrim is painted by
@@ -4266,12 +4333,14 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
4266
4333
  .tour-actions { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-2); }
4267
4334
 
4268
4335
  .tour-count { color: var(--muted); font-size: var(--text-xs); }
4336
+ }
4269
4337
 
4270
4338
  /* The mail and forum shell, added in 0.4.0. After the rest, because the
4271
4339
  anchored surfaces (`.pop`, `.menu-sheet`, `.cmd`) sit over everything and a
4272
4340
  rule of equal specificity that came earlier would lose to whatever the
4273
4341
  sheets they cover happen to set. */
4274
4342
  /* ---- ./stat.css ---- */
4343
+ @layer components {
4275
4344
  /* What the utilities on `Stat` cannot say: a tone on the tile colouring the
4276
4345
  figure inside it. An attribute on the parent selecting a child is a
4277
4346
  relationship; a utility is a property on one element.
@@ -4282,8 +4351,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
4282
4351
  .stat[data-tone='good'] .stat-value { color: var(--good); }
4283
4352
  .stat[data-tone='warn'] .stat-value { color: var(--warn); }
4284
4353
  .stat[data-tone='bad'] .stat-value { color: var(--bad); }
4354
+ }
4285
4355
 
4286
4356
  /* ---- ./shell.css ---- */
4357
+ @layer components {
4287
4358
  /* The measure, and only the measure.
4288
4359
  *
4289
4360
  * `Shell` draws itself with utilities -- it is layout and nothing else. What
@@ -4310,8 +4381,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
4310
4381
  font-size: var(--text-sm);
4311
4382
  white-space: nowrap;
4312
4383
  }
4384
+ }
4313
4385
 
4314
4386
  /* ---- ./scrollarea.css ---- */
4387
+ @layer components {
4315
4388
  /* A box that scrolls, with its edges drawn.
4316
4389
 
4317
4390
  The fades are `::before`/`::after` on the scroller itself, pinned with
@@ -4404,8 +4477,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
4404
4477
  .scroller.faded::before,
4405
4478
  .scroller.faded::after { transition: none; }
4406
4479
  }
4480
+ }
4407
4481
 
4408
4482
  /* ---- ./splitpane.css ---- */
4483
+ @layer components {
4409
4484
  /* Two panes and the handle between them. */
4410
4485
  .split {
4411
4486
  display: flex;
@@ -4505,8 +4580,10 @@ body.splitting * { cursor: inherit !important; }
4505
4580
  @media (prefers-reduced-motion: reduce) {
4506
4581
  .split-grip { transition: none; }
4507
4582
  }
4583
+ }
4508
4584
 
4509
4585
  /* ---- ./popover.css ---- */
4586
+ @layer components {
4510
4587
  /* A small surface anchored to what opened it. Same sheet as the select's list,
4511
4588
  because they are the same object -- something that appeared over the page,
4512
4589
  attached to a control. */
@@ -4560,8 +4637,10 @@ body.splitting * { cursor: inherit !important; }
4560
4637
  .pop[data-entering],
4561
4638
  .pop[data-exiting] { animation: none; }
4562
4639
  }
4640
+ }
4563
4641
 
4564
4642
  /* ---- ./menu.css ---- */
4643
+ @layer components {
4565
4644
  /* What is left once `Menu` draws its sheet and its list: the rows, whose
4566
4645
  `data-focused`, `data-pressed` and danger states React Aria stamps on
4567
4646
  them, and the rules that reach from a row into what it holds. The
@@ -4643,8 +4722,10 @@ body.splitting * { cursor: inherit !important; }
4643
4722
  }
4644
4723
 
4645
4724
  .menu-sheet { box-shadow: var(--shadow-2); }
4725
+ }
4646
4726
 
4647
4727
  /* ---- ./command.css ---- */
4728
+ @layer components {
4648
4729
  /* The command palette: a field over the app and a list under it. */
4649
4730
  .cmd-scrim {
4650
4731
  position: fixed;
@@ -4786,8 +4867,10 @@ body.splitting * { cursor: inherit !important; }
4786
4867
  .cmd-scrim[data-exiting],
4787
4868
  .cmd[data-entering] { animation: none; }
4788
4869
  }
4870
+ }
4789
4871
 
4790
4872
  /* ---- ./pagination.css ---- */
4873
+ @layer components {
4791
4874
  /* What is left once `Pagination` draws its own frame: the step and page
4792
4875
  buttons, whose hover, focus-visible and current states are pseudo-classes
4793
4876
  on two selectors at once, and `.pager-count strong`, which reaches into
@@ -4906,8 +4989,10 @@ body.splitting * { cursor: inherit !important; }
4906
4989
  .pager-page,
4907
4990
  .pager-jump { transition: none; }
4908
4991
  }
4992
+ }
4909
4993
 
4910
4994
  /* ---- ./identity.css ---- */
4995
+ @layer components {
4911
4996
  /* A person, said in one line: initials, name, sometimes the address. */
4912
4997
  .ident {
4913
4998
  display: inline-flex;
@@ -5008,6 +5093,7 @@ body.splitting * { cursor: inherit !important; }
5008
5093
 
5009
5094
  .ident-remove:hover { background: var(--panel); color: var(--text); }
5010
5095
  .ident-remove:focus-visible { outline: none; box-shadow: var(--focus-ring); }
5096
+ }
5011
5097
  /* ---- tf: the themes ---- */
5012
5098
  :root[data-theme='night']{--bg:#0f1115;--panel:#161a21;--panel-2:#1c222b;--border:#262d38;--text:#e6e9ef;--muted:#8b94a4;--accent:#5b9dff;--accent-dim:#2a4877;--app-bg:#0f1115;color-scheme:dark}
5013
5099
  :root[data-theme='paper']{--bg:#f6f7f9;--panel:#ffffff;--panel-2:#f0f2f5;--border:#e4e8ec;--border-strong:#8792a1;--text:#191d23;--muted:#5d6773;--accent:#0e7872;--accent-dim:#7fbdb8;--on-accent:#ffffff;--good:#1c7a4a;--warn:#8a6216;--bad:#b3312c;--info:#216bc9;--shadow-1:0 4px 14px rgba(16, 24, 40, 0.08);--shadow-2:0 8px 24px rgba(16, 24, 40, 0.10);--shadow-3:0 12px 32px rgba(16, 24, 40, 0.12);--scrim:rgba(16, 24, 40, 0.32);color-scheme:light}