@apliteni/apliteni-ui 0.94.0 → 0.95.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.
@@ -13,7 +13,7 @@
13
13
  display: grid;
14
14
  grid-template-columns: max-content 1fr;
15
15
  min-height: calc(100vh - var(--ui-app-top, 0px));
16
- background: var(--bg); /* ring-gap: inherit — page background inherits root overrides. */
16
+ background: var(--bg); /* code-bg: inherit — page background inherits root overrides. */
17
17
  color: var(--text);
18
18
  font-family: var(--font-sans);
19
19
  /* The rail's width, and the one property the fold moves: the nav's own column
@@ -42,7 +42,7 @@
42
42
  padding: var(--space-5) var(--space-4);
43
43
  border-right: var(--ui-rail-rule) solid var(--rail-edge);
44
44
  box-shadow: var(--elev-rail);
45
- background: var(--surface); --ring-gap: var(--surface);
45
+ background: var(--surface);
46
46
  position: sticky;
47
47
  top: var(--ui-app-top, 0px);
48
48
  height: calc(100vh - var(--ui-app-top, 0px));
@@ -67,8 +67,8 @@
67
67
  to the --surface-3 the folded rail already paints, a hovered row to half of it, so
68
68
  the pointer stays quieter than the reader's own row in both themes (#475 r34). The
69
69
  danger and current rows are named out: this rule outranks nav.css's states. */
70
- .ui-app__rail .ui-nav__item:not(.is-danger):not(.is-active):hover { background: color-mix(in srgb, var(--surface-3) 50%, transparent); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ }
71
- .ui-app__rail .ui-nav__item.is-active { background: var(--surface-3); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */ }
70
+ .ui-app__rail .ui-nav__item:not(.is-danger):not(.is-active):hover { background: color-mix(in srgb, var(--surface-3) 50%, transparent); /* code-bg: inherit — The wash keeps the containing ground. */ }
71
+ .ui-app__rail .ui-nav__item.is-active { background: var(--surface-3); /* code-bg: inherit — The control keeps the containing ground. */ }
72
72
  .ui-app__brand {
73
73
  display: flex;
74
74
  align-items: center;
@@ -88,7 +88,7 @@
88
88
  /* Carries the shell's class as well as its own, for the same reason the rail
89
89
  rows do (see nav.css): a host stylesheet's `a:link` is (0,1,1). */
90
90
  .ui-app .ui-app__brand { color: var(--strong); }
91
- .ui-app__brand:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); border-radius: var(--radius-xs); }
91
+ .ui-app__brand:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); border-radius: var(--radius-xs); }
92
92
  .ui-app__brand svg { display: block; flex: none; }
93
93
 
94
94
  /* The head band: the product's mark, and the rail's own control at the far end of
@@ -119,7 +119,7 @@
119
119
  resting step. */
120
120
  /* Re-tuned at #295, which took the light rail down a step with the page. Below 720px
121
121
  the glyph is the whole row, so it is held at text grade rather than at 1.4.11's bar —
122
- stories/apps/shell-states.test.js:1595 `a resting glyph is dimmer but still legible`. */
122
+ stories/apps/shell-states.test.js:1597 `a resting glyph is dimmer but still legible`. */
123
123
  .ui-app__rail .ui-nav__ic svg { opacity: 0.66; }
124
124
 
125
125
  /* A destructive row of the rail is a navigation row and rests like one; the danger
@@ -160,7 +160,7 @@
160
160
  width: var(--ui-app-av); height: var(--ui-app-av); flex: none;
161
161
  margin-inline-start: calc((var(--ui-nav-strip) - var(--ui-app-av)) / 2);
162
162
  border-radius: var(--radius-pill);
163
- background: var(--surface); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */
163
+ background: var(--surface); /* code-bg: inherit — decorative or text-only paint; nothing nested reads a ground from it. */
164
164
  color: var(--strong);
165
165
  display: grid; place-items: center;
166
166
  font-size: calc(var(--text-xs) + 1px);
@@ -194,7 +194,7 @@
194
194
  font-weight: inherit;
195
195
  letter-spacing: normal;
196
196
  }
197
- .ui-app .ui-app__user-trigger:hover { background: var(--surface); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */ }
197
+ .ui-app .ui-app__user-trigger:hover { background: var(--surface); /* code-bg: inherit — control paint; the containing surface is the ground, for a chip and for a band alike. */ }
198
198
  .ui-app__user-trigger .ui-app__who { flex: 1 1 auto; text-align: left; }
199
199
  /* The panel is portalled onto <body>, so nothing here may hang off .ui-app: by the
200
200
  time it is open it is no longer inside the rail that drew it.
@@ -283,7 +283,7 @@
283
283
  does not do: an ordinary row drops its wash here, answered by the floating name below.
284
284
  nav.css's folded rules, a rung further. why: docs/components.md#the-page-shell */
285
285
  :where(.ui-app.is-collapsed) .ui-app__rail .ui-nav__item.is-active { isolation: isolate; background: none; }
286
- :where(.ui-app.is-collapsed) .ui-app__rail .ui-nav__item.is-active::before { content: ""; position: absolute; left: 0; top: 50%; width: var(--ui-nav-strip); height: 100%; border-radius: 10px; transform: translateY(-50%); /* motion: still — a mark on the current row, whose own highlight already transitions; this centres it, it does not travel */ background: var(--surface-3); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ z-index: -1; }
286
+ :where(.ui-app.is-collapsed) .ui-app__rail .ui-nav__item.is-active::before { content: ""; position: absolute; left: 0; top: 50%; width: var(--ui-nav-strip); height: 100%; border-radius: 10px; transform: translateY(-50%); /* motion: still — a mark on the current row, whose own highlight already transitions; this centres it, it does not travel */ background: var(--surface-3); /* code-bg: inherit — The plate contains no focus target. */ z-index: -1; }
287
287
  :where(.ui-app.is-collapsed) .ui-app__rail .ui-nav__item:not(.is-danger):not(.is-active):hover { background: none; }
288
288
  /* The label IS the chip. `fixed` is the fallback placement, out of the rail's own
289
289
  clip; the @supports branch below pins it to the row and is the only one that
@@ -297,7 +297,7 @@
297
297
  why: docs/foundations.md#elevation */
298
298
  :where(.ui-app.is-collapsed) .ui-app__rail .ui-nav__item:is(:hover, :focus-visible) > .ui-nav__label,
299
299
  :where(.ui-app.is-collapsed) .ui-app__rail .ui-app__user-trigger:is(:hover, :focus-visible) > .ui-app__who,
300
- .ui-app__rail .ui-app__fold:is(:hover, :focus-visible) > .ui-nav__label { position: fixed; left: calc(var(--ui-rail-w) + var(--space-2)); z-index: var(--z-dropdown); width: max-content; max-width: 15rem; margin-block: -7px; padding: 6px 10px; border: 1px solid var(--float-edge); box-shadow: inset 0 0 0 1px var(--elev-edge, var(--float-edge-inner)), var(--elev-drop); border-radius: var(--radius-xs); background: var(--surface); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ color: var(--strong); opacity: 1; pointer-events: none; }
300
+ .ui-app__rail .ui-app__fold:is(:hover, :focus-visible) > .ui-nav__label { position: fixed; left: calc(var(--ui-rail-w) + var(--space-2)); z-index: var(--z-dropdown); width: max-content; max-width: 15rem; margin-block: -7px; padding: 6px 10px; border: 1px solid var(--float-edge); box-shadow: inset 0 0 0 1px var(--elev-edge, var(--float-edge-inner)), var(--elev-drop); border-radius: var(--radius-xs); background: var(--surface); /* code-bg: inherit — decorative or text-only paint; nothing nested reads a ground from it. */ color: var(--strong); opacity: 1; pointer-events: none; }
301
301
  @supports (anchor-name: --a) and (anchor-scope: --a) {
302
302
  .ui-app.is-collapsed,
303
303
  .ui-app:has(.ui-app__fold) { anchor-scope: --ui-rail; }
@@ -346,7 +346,7 @@
346
346
  height: var(--ui-app-band);
347
347
  flex: none;
348
348
  padding-inline: clamp(24px, 4vw, 56px);
349
- background: var(--bg); /* ring-gap: inherit — page background inherits root overrides. */
349
+ background: var(--bg); /* code-bg: inherit — page background inherits root overrides. */
350
350
  border-bottom: 1px solid var(--border);
351
351
  /* Sticky for the reason the rail beside it is: chrome that scrolls away is chrome
352
352
  you scroll back up for. */
@@ -382,7 +382,7 @@
382
382
  color: var(--text);
383
383
  /* The band search uses the same reading surface as other text controls.
384
384
  why: docs/foundations.md#elevation */
385
- background: var(--surface); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */
385
+ background: var(--surface); /* code-bg: inherit — control paint; the containing surface is the ground, for a chip and for a band alike. */
386
386
  border: 1px solid var(--border);
387
387
  border-radius: var(--radius-md);
388
388
  cursor: pointer;
@@ -393,10 +393,10 @@
393
393
  without `.ui-btn`, so base.css's shared rule never reached it and focus fell
394
394
  through to the browser's own square outline, drawn around a 12px radius.
395
395
  why: docs/foundations.md#the-focus-ring */
396
- .ui-app__search:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); border-color: var(--accent); }
396
+ .ui-app__search:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
397
397
  /* The same glyph the palette draws in its own search box, at the same box and the
398
398
  same stroke: the trigger and the thing it opens are not two search marks.
399
- src/styles/command-palette.css:109 `.ui-cmdk__search-ic svg` */
399
+ src/styles/command-palette.css:108 `.ui-cmdk__search-ic svg` */
400
400
  .ui-app__search-ic { display: flex; flex: none; }
401
401
  .ui-app__search-ic svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 2.2; }
402
402
  /* Part of the button's name, so it is squeezed rather than dropped: an ellipsis
@@ -488,7 +488,7 @@
488
488
  .ui-app__rail .ui-nav__sub { margin-inline-start: 0; padding-inline-start: 0; border-inline-start-width: 0; }
489
489
  .ui-app__rail .ui-nav__item:not(:has(.ui-nav__ic))::after { opacity: 0.62; }
490
490
  .ui-app__rail .ui-nav__item.is-active { isolation: isolate; background: none; }
491
- .ui-app__rail .ui-nav__item.is-active::before { content: ""; position: absolute; left: 0; top: 50%; width: var(--ui-nav-strip); height: 100%; border-radius: 10px; transform: translateY(-50%); /* motion: still — a mark on the current row, whose own highlight already transitions; this centres it, it does not travel */ background: var(--surface-3); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ z-index: -1; }
491
+ .ui-app__rail .ui-nav__item.is-active::before { content: ""; position: absolute; left: 0; top: 50%; width: var(--ui-nav-strip); height: 100%; border-radius: 10px; transform: translateY(-50%); /* motion: still — a mark on the current row, whose own highlight already transitions; this centres it, it does not travel */ background: var(--surface-3); /* code-bg: inherit — The plate contains no focus target. */ z-index: -1; }
492
492
  .ui-app__rail .ui-nav__item:not(.is-danger):not(.is-active):hover { background: none; }
493
493
  /* The one line of this block that is deliberately NOT the reader's fold: a finger
494
494
  is the only pointer this width has, so a row and the account block are held to
@@ -497,7 +497,7 @@
497
497
  .ui-app__rail .ui-nav__item,
498
498
  .ui-app__rail .ui-app__user-trigger { min-height: 44px; }
499
499
  .ui-app__rail .ui-nav__item:is(:hover, :focus-visible) > .ui-nav__label,
500
- .ui-app__rail .ui-app__user-trigger:is(:hover, :focus-visible) > .ui-app__who { position: fixed; left: calc(var(--ui-rail-w) + var(--space-2)); z-index: var(--z-dropdown); width: max-content; max-width: 15rem; margin-block: -7px; padding: 6px 10px; border: 1px solid var(--float-edge); box-shadow: inset 0 0 0 1px var(--elev-edge, var(--float-edge-inner)), var(--elev-drop); border-radius: var(--radius-xs); background: var(--surface); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ color: var(--strong); opacity: 1; pointer-events: none; }
500
+ .ui-app__rail .ui-app__user-trigger:is(:hover, :focus-visible) > .ui-app__who { position: fixed; left: calc(var(--ui-rail-w) + var(--space-2)); z-index: var(--z-dropdown); width: max-content; max-width: 15rem; margin-block: -7px; padding: 6px 10px; border: 1px solid var(--float-edge); box-shadow: inset 0 0 0 1px var(--elev-edge, var(--float-edge-inner)), var(--elev-drop); border-radius: var(--radius-xs); background: var(--surface); /* code-bg: inherit — decorative or text-only paint; nothing nested reads a ground from it. */ color: var(--strong); opacity: 1; pointer-events: none; }
501
501
  @supports (anchor-name: --a) and (anchor-scope: --a) {
502
502
  .ui-app { anchor-scope: --ui-rail; }
503
503
  .ui-app__rail { anchor-name: --ui-rail; }
@@ -532,7 +532,7 @@
532
532
  /* Floats over a spotlit page, so it takes the floating step and the floating
533
533
  treatment: the two-step edge in dark, the drop alone in light.
534
534
  why: docs/foundations.md#elevation */
535
- background: var(--bg-elevated); --ring-gap: var(--bg-elevated);
535
+ background: var(--bg-elevated);
536
536
  border: 1px solid var(--float-edge);
537
537
  box-shadow: inset 0 0 0 1px var(--elev-edge, var(--float-edge-inner)), var(--elev-drop);
538
538
  border-radius: 22px;
@@ -555,7 +555,7 @@
555
555
  width: 38px; height: 38px; flex: none;
556
556
  border-radius: 11px;
557
557
  display: grid; place-items: center;
558
- background: var(--glow-purple); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */
558
+ background: var(--glow-purple); /* code-bg: inherit — a wash paints over a ground and behind a chip, so the opaque ground below it is the step. */
559
559
  color: var(--accent);
560
560
  }
561
561
  .ui-scope__icon svg { width: 21px; height: 21px; stroke: currentColor; fill: none; stroke-width: 1.8; }
@@ -576,7 +576,7 @@
576
576
  font-size: calc(var(--text-xs) + 1px);
577
577
  letter-spacing: 0.06em;
578
578
  color: var(--purple-mid);
579
- background: var(--glow-purple); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */
579
+ background: var(--glow-purple); /* code-bg: inherit — a wash paints over a ground and behind a chip, so the opaque ground below it is the step. */
580
580
  border-radius: 999px;
581
581
  padding: 6px 14px;
582
582
  margin-bottom: 26px;
@@ -621,7 +621,7 @@
621
621
  width: 46px; height: 46px;
622
622
  border-radius: 13px;
623
623
  display: grid; place-items: center;
624
- background: var(--glow-purple); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */
624
+ background: var(--glow-purple); /* code-bg: inherit — a wash paints over a ground and behind a chip, so the opaque ground below it is the step. */
625
625
  color: var(--accent);
626
626
  margin-bottom: 16px;
627
627
  }
@@ -99,7 +99,7 @@
99
99
  display: grid;
100
100
  place-items: center;
101
101
  /* muted-ink: glyph — permission seal */ color: var(--dim);
102
- background: color-mix(in srgb, var(--text) 7%, transparent); /* ring-gap: inherit — decorative paint has no nested focus target. */
102
+ background: color-mix(in srgb, var(--text) 7%, transparent); /* code-bg: inherit — decorative paint has no nested focus target. */
103
103
  }
104
104
  .ui-denied__seal svg {
105
105
  width: 20px;
@@ -81,7 +81,7 @@
81
81
  .m-skeleton {
82
82
  position: relative;
83
83
  overflow: hidden;
84
- background: color-mix(in srgb, var(--text) 8%, transparent); /* ring-gap: inherit — loading placeholder has no nested focus target. */
84
+ background: color-mix(in srgb, var(--text) 8%, transparent); /* code-bg: inherit — loading placeholder has no nested focus target. */
85
85
  border-radius: var(--radius-sm, 8px);
86
86
  }
87
87
  .m-skeleton::after {
@@ -75,9 +75,9 @@
75
75
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
76
76
  }
77
77
  .ui-nav .ui-nav__item { color: var(--text); } /* (0,2,0): a host sheet's a:link is (0,1,1) — why: docs/components.md#the-page-shell */
78
- .ui-nav__item:hover { background: color-mix(in srgb, var(--surface) 50%, transparent); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ color: var(--strong); }
78
+ .ui-nav__item:hover { background: color-mix(in srgb, var(--surface) 50%, transparent); /* code-bg: inherit — The wash keeps the containing ground. */ color: var(--strong); }
79
79
  .ui-nav__item.is-active {
80
- background: var(--surface); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */
80
+ background: var(--surface); /* code-bg: inherit — control paint; the containing surface is the ground, for a chip and for a band alike. */
81
81
  color: var(--strong);
82
82
  font-weight: 500;
83
83
  }
@@ -86,8 +86,8 @@
86
86
  ground the rail stands on, so layout.css takes it the next rung where the rail
87
87
  is itself --surface. #475 r33/r34. why: docs/components.md#the-page-shell */
88
88
 
89
- .ui-nav__item:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); }
90
- .ui-nav__item.is-active:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); }
89
+ .ui-nav__item:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
90
+ .ui-nav__item.is-active:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
91
91
 
92
92
  .ui-nav__ic { display: inline-flex; flex: none; }
93
93
  .ui-nav__ic svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 2.2; opacity: 0.72; }
@@ -112,10 +112,10 @@
112
112
  /* Destructive row (sign out, revoke). Body ink at rest, --pink once a pointer or
113
113
  the keyboard reaches it — as .ui-btn--danger and .ui-dropdown__item do. */
114
114
  .ui-nav__item.is-danger { color: var(--text); }
115
- .ui-nav__item.is-danger:hover { background: var(--glow-pink); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ color: var(--pink); }
115
+ .ui-nav__item.is-danger:hover { background: var(--glow-pink); /* code-bg: inherit — a wash paints over a ground and behind a chip, so the opaque ground below it is the step. */ color: var(--pink); }
116
116
  /* Tabbing onto it is the same "about to click this" the pointer means. The ring
117
117
  says where you are; only this says what the row does. */
118
- .ui-nav__item.is-danger:focus-visible { background: var(--glow-pink); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ color: var(--pink); }
118
+ .ui-nav__item.is-danger:focus-visible { background: var(--glow-pink); /* code-bg: inherit — a wash paints over a ground and behind a chip, so the opaque ground below it is the step. */ color: var(--pink); }
119
119
  /* An unavailable row uses disabled ink directly; opacity would also fade its
120
120
  background and pull its label toward the rail behind it (#220). */
121
121
  .ui-nav__item.is-disabled { /* muted-ink: state — unavailable control */ color: var(--disabled-ink); cursor: default; pointer-events: none; }
@@ -134,17 +134,17 @@
134
134
  font-size: var(--text-xs);
135
135
  font-weight: 600;
136
136
  line-height: 1;
137
- background: var(--surface); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */
137
+ background: var(--surface); /* code-bg: inherit — decorative or text-only paint; nothing nested reads a ground from it. */
138
138
  color: var(--text);
139
139
  /* The count fades with the words. It is never lost: sidebarNav() spells it
140
140
  into the row's aria-label, so "Pending 3" is what a reader hears at either
141
141
  width. */
142
142
  transition: opacity var(--dur-fast) var(--ease);
143
143
  }
144
- .ui-nav__badge.is-accent { background: var(--glow-purple); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ color: var(--accent); }
145
- .ui-nav__badge.is-live { background: var(--chip-success-fill); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ color: var(--chip-success-ink); }
146
- .ui-nav__badge.is-danger { background: var(--glow-pink); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ color: var(--pink); }
147
- .ui-nav__item.is-active .ui-nav__badge.is-neutral { background: var(--surface); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ color: var(--strong); }
144
+ .ui-nav__badge.is-accent { background: var(--glow-purple); /* code-bg: inherit — a wash paints over a ground and behind a chip, so the opaque ground below it is the step. */ color: var(--accent); }
145
+ .ui-nav__badge.is-live { background: var(--chip-success-fill); /* code-bg: inherit — decorative or text-only paint; nothing nested reads a ground from it. */ color: var(--chip-success-ink); }
146
+ .ui-nav__badge.is-danger { background: var(--glow-pink); /* code-bg: inherit — a wash paints over a ground and behind a chip, so the opaque ground below it is the step. */ color: var(--pink); }
147
+ .ui-nav__item.is-active .ui-nav__badge.is-neutral { background: var(--surface); /* code-bg: inherit — decorative or text-only paint; nothing nested reads a ground from it. */ color: var(--strong); }
148
148
  /* Same shape, one row up: on the current row the accent counter drops both the
149
149
  wash and the accent and reads as the neutral one beside it. The row already
150
150
  carries the one mark it is allowed — the plate — and the count is a number,
@@ -152,7 +152,7 @@
152
152
  recorded: accent ink on --surface fell under WCAG AA in four of the eight
153
153
  theme x accent cells (4.08 in dark Nebula), and no alpha cleared it. Nothing
154
154
  now paints that pair. See #429 and docs/foundations.md#colour-and-contrast. */
155
- .ui-nav__item.is-active .ui-nav__badge.is-accent { background: var(--surface); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ color: var(--strong); }
155
+ .ui-nav__item.is-active .ui-nav__badge.is-accent { background: var(--surface); /* code-bg: inherit — decorative or text-only paint; nothing nested reads a ground from it. */ color: var(--strong); }
156
156
 
157
157
  /* Collapsible group */
158
158
  .ui-nav__group { display: flex; flex-direction: column; }
@@ -274,7 +274,7 @@
274
274
  height: 100%;
275
275
  border-radius: 10px;
276
276
  transform: translateY(-50%); /* motion: still — a mark on the current row, whose own highlight already transitions; this centres it, it does not travel */
277
- background: var(--surface); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */
277
+ background: var(--surface); /* code-bg: inherit — The plate contains no focus target. */
278
278
  z-index: -1;
279
279
  }
280
280
  /* Nothing switches the hover wash off here: since #588 a folded row is only as wide
@@ -305,7 +305,7 @@
305
305
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
306
306
  }
307
307
  .ui-nav__tab:hover { color: var(--strong); }
308
- .ui-nav__tab:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); border-radius: 8px; }
308
+ .ui-nav__tab:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); border-radius: 8px; }
309
309
  .ui-nav__tab.is-active { color: var(--strong); }
310
310
 
311
311
  /* underline variant */
@@ -324,9 +324,9 @@
324
324
 
325
325
  /* pill variant */
326
326
  .ui-nav--tabs.is-pill .ui-nav__tab { border-radius: var(--radius-pill); padding: 8px 15px; }
327
- .ui-nav--tabs.is-pill .ui-nav__tab:hover { background: var(--surface); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */ }
327
+ .ui-nav--tabs.is-pill .ui-nav__tab:hover { background: var(--surface); /* code-bg: inherit — control paint; the containing surface is the ground, for a chip and for a band alike. */ }
328
328
  .ui-nav--tabs.is-pill .ui-nav__tab.is-active {
329
- background: var(--glow-purple); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */
329
+ background: var(--glow-purple); /* code-bg: inherit — a wash paints over a ground and behind a chip, so the opaque ground below it is the step. */
330
330
  color: var(--accent);
331
331
  }
332
332
 
@@ -361,7 +361,7 @@
361
361
  does above: a linked crumb is an <a>, and a host stylesheet's `a:link` is
362
362
  (0,1,1), which outranks a bare (0,1,0) class. */
363
363
  .ui-nav .ui-nav__crumb { color: var(--text); }
364
- a.ui-nav__crumb:hover { color: var(--strong); background: var(--surface); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */ }
365
- a.ui-nav__crumb:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); }
364
+ a.ui-nav__crumb:hover { color: var(--strong); background: var(--surface); /* code-bg: inherit — control paint; the containing surface is the ground, for a chip and for a band alike. */ }
365
+ a.ui-nav__crumb:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
366
366
  .ui-nav__crumb.is-current { color: var(--strong); font-weight: 500; }
367
367
  .ui-nav__crumb .ui-nav__ic svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2.5; }
@@ -68,8 +68,13 @@
68
68
  selector for the markup this component emits, and the spelling that keeps a
69
69
  rule about an ENABLED control out of the disabled-rule sweep in
70
70
  stories/guidelines/accessibility-floor.test.js, which reads selector text. */
71
+ /* The one selected mark #578 round r34 LEFT as an edge, and why. A pager stands on
72
+ the page in one showcase and on a card in another; --surface steps off the page at
73
+ 1.110:1 and off a card at 1.000:1, so a fill that marks the current page on one
74
+ ground marks nothing on the other. The hairline is what survives both. Open for
75
+ Artur on #578. */
71
76
  .ui-pager__page.is-current:not([disabled]) {
72
- background: var(--surface); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */
77
+ background: var(--surface); /* code-bg: inherit — control paint; the containing surface is the ground, for a chip and for a band alike. */
73
78
  border-color: var(--border);
74
79
  color: var(--strong);
75
80
  font-weight: var(--weight-semibold);
@@ -1,12 +1,12 @@
1
1
  /* ============================================================================
2
2
  * Segmented control — .ui-seg (the deck's pill switch: theme, Deck/Text, plan)
3
- * The selected button keeps the reading surface and gains an accent edge.
3
+ * The chosen button is a fill that steps off the track, and a step of ink.
4
4
  * ========================================================================== */
5
5
 
6
6
  /* The strip wraps rather than overflows: a track wider than its column used to
7
7
  push the page's scrollWidth past the viewport, which drags every sibling with
8
- it. Wrapping keeps the focus ring's glow unclipped, which `overflow: auto`
9
- here would not. #435 */
8
+ it. Wrapping keeps the focus band unclipped, which `overflow: auto` here
9
+ would not. #435 */
10
10
  .ui-seg {
11
11
  display: inline-flex;
12
12
  /* `inline-flex` sizes the track to its pills, but a flex or grid parent stretches a
@@ -14,7 +14,7 @@
14
14
  states its own alignment; --block and --underline ask for the width back. */
15
15
  align-self: start;
16
16
  justify-self: start;
17
- background: var(--surface); --ring-gap: var(--surface);
17
+ background: var(--surface);
18
18
  flex-wrap: wrap;
19
19
  max-width: 100%;
20
20
  border-radius: var(--radius-2xl);
@@ -37,12 +37,19 @@
37
37
  .ui-seg button:hover { color: var(--strong); }
38
38
  /* aria-pressed is what segmented() emits now; aria-selected is kept so markup
39
39
  copied from an older release keeps painting its active pill. */
40
+ /* The chosen pill is its fill and its ink. The accent outline it also drew was an
41
+ outline used for selection, which is the property and the shape the focus band
42
+ takes — on a chosen pill the two sat one pixel apart. Artur separated them on #578
43
+ round r34, and the fill left behind has to be the mark: the track is --surface, and
44
+ --surface on --surface is 1.000:1, so the pill read as its ink alone. --surface-3 is
45
+ the kit's quiet non-text fill and steps off the track in both themes — 1.140:1 light,
46
+ 1.160:1 dark — which stories/selected-fill.test.js measures.
47
+ why: docs/foundations.md#the-focus-ring */
40
48
  .ui-seg button.is-active,
41
49
  .ui-seg button[aria-pressed="true"],
42
50
  .ui-seg button[aria-selected="true"] {
43
51
  color: var(--strong);
44
- background: var(--surface); /* ring-gap: inherit — the button ring meets its containing track. */
45
- outline: 1px solid var(--accent);
52
+ background: var(--surface-3); /* code-bg: inherit — a control's own selected fill; nothing nested reads a ground from it. */
46
53
  }
47
54
 
48
55
  /* Standard pills tighten on phones so six short month names fit one row. */
@@ -65,7 +72,11 @@
65
72
  cursor: pointer;
66
73
  position: relative;
67
74
  background: var(--swatch, var(--accent));
68
- box-shadow: 0 0 0 2px var(--surface), 0 0 0 2px var(--surface);
75
+ /* One band of the surface the strip stands on, so a swatch reads as a circle
76
+ rather than as a tile edge-to-edge with its neighbour. #472 took the selected
77
+ swatch's own ring off the second layer and left the layer behind, restating
78
+ this one; two layers at the same spread paint once. */
79
+ box-shadow: 0 0 0 2px var(--surface);
69
80
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
70
81
  }
71
82
  .ui-accent-picker button:hover { transform: scale(1.08); }
@@ -88,12 +99,12 @@
88
99
  border-width: 0 2px 2px 0;
89
100
  transform: translate(-50%, -50%) rotate(45deg); /* motion: still — the turn is the tick's shape, not travel, and the mark lands with the press that asked for it. Nothing else on the swatch changes with selection, so there is no paint for it to arrive with. */
90
101
  }
91
- .ui-accent-picker button:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); }
102
+ .ui-accent-picker button:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
92
103
 
93
104
  /* Underline tabs wrap for the reason the pills above do — #435 — and draw no
94
105
  rule of their own: the chosen tab carries the selection. #527, #545
95
106
  why: docs/components.md#the-chosen-tab-in-an-underline-strip */
96
- .ui-seg--underline { flex-wrap: wrap; overflow: visible; row-gap: var(--space-1); align-self: stretch; justify-self: stretch; background: transparent; --ring-gap: inherit; border-radius: 0; padding: var(--space-1); max-width: 100%; }
107
+ .ui-seg--underline { flex-wrap: wrap; overflow: visible; row-gap: var(--space-1); align-self: stretch; justify-self: stretch; background: transparent; border-radius: 0; padding: var(--space-1); max-width: 100%; }
97
108
  /* `anywhere` is the half `break-word` cannot do: it lowers the tab's min-content
98
109
  width, so one unbreakable word narrows rather than widening the page. The
99
110
  padding is the scale's own step and the height is the tap floor, so the tab
@@ -104,15 +115,16 @@
104
115
  why: guidelines/layout-and-density.md, the spacing scale */
105
116
  .ui-seg--underline button { position: relative; border-radius: var(--radius-sm); padding: var(--space-3); min-height: var(--tap-min, 44px); white-space: normal; overflow-wrap: anywhere; font-weight: var(--weight-medium); }
106
117
  /* The chosen tab is its label and one bar under it: no plate, no hairline, no
107
- upright rail — those read as a list-row grip. `outline: 0` cancels the accent
108
- outline the pill rule gives every chosen button, which is #544's second mark.
109
- #527 r31. why: docs/components.md#the-chosen-tab-in-an-underline-strip */
118
+ upright rail — those read as a list-row grip. #527 r31. The `outline: 0` that
119
+ stood here cancelled the accent outline the pill rule gave every chosen button;
120
+ #578 round r34 took that outline off, so there is nothing left to cancel — and
121
+ nothing outranking the kit's focus rule, which is why the restatement under the
122
+ bar is gone with it. why: docs/components.md#the-chosen-tab-in-an-underline-strip */
110
123
  .ui-seg--underline button.is-active,
111
124
  .ui-seg--underline button[aria-pressed="true"] {
112
125
  background: none;
113
126
  color: var(--strong);
114
127
  font-weight: var(--weight-semibold);
115
- outline: 0;
116
128
  }
117
129
  /* Every tab reserves the bar and hides it, so the mark grows in place when the
118
130
  choice moves rather than appearing — the structure and the timing
@@ -133,15 +145,11 @@
133
145
  }
134
146
  .ui-seg--underline button.is-active::before,
135
147
  .ui-seg--underline button[aria-pressed="true"]::before { opacity: 1; transform: scaleX(1); }
136
- /* `outline: 0` above outranks the kit's :focus-visible rule — (0,3,0) against
137
- (0,2,1) — so the chosen tab would focus with no indicator. Restated here. */
138
- .ui-seg--underline button.is-active:focus-visible,
139
- .ui-seg--underline button[aria-pressed="true"]:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); }
140
148
  /* The mode repaints an author colour, so the bar comes back as the labels' own
141
149
  ink. `Highlight` is kept where it is named: one mark the mode cannot flatten. */
142
150
  @media (forced-colors: active) {
143
151
  .ui-seg--underline button.is-active::before,
144
152
  .ui-seg--underline button[aria-pressed="true"]::before { background: Highlight; }
145
153
  }
146
- .ui-seg button:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); }
154
+ .ui-seg button:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
147
155
  .ui-seg button:disabled { /* muted-ink: state — unavailable choice */ color: var(--disabled-ink); cursor: not-allowed; }
@@ -16,7 +16,7 @@
16
16
  position: relative;
17
17
  overflow: hidden;
18
18
  border-radius: 20px;
19
- background: var(--bg-elevated); --ring-gap: var(--bg-elevated); /* Elevated surface for the confirmation and its actions. */
19
+ background: var(--bg-elevated); /* Elevated surface for the confirmation and its actions. */
20
20
  /* The floating treatment, like every other surface on that step.
21
21
  why: docs/foundations.md#elevation */
22
22
  border: 1px solid var(--float-edge);
@@ -50,7 +50,7 @@
50
50
  }
51
51
  .ui-sx--split .ui-sx__visual {
52
52
  display: grid; place-items: center; padding: 40px 24px;
53
- background: color-mix(in srgb, var(--green) 8%, transparent); /* ring-gap: inherit — decorative illustration has no nested focus target. */
53
+ background: color-mix(in srgb, var(--green) 8%, transparent); /* code-bg: inherit — decorative illustration has no nested focus target. */
54
54
  border-right: 1px solid var(--border);
55
55
  }
56
56
  .ui-sx--split .ui-sx__check { width: 72px; height: 72px; }
@@ -119,7 +119,7 @@
119
119
  .ui-sx--hero .ui-sx__count { justify-content: center; }
120
120
  .ui-sx__count-ring {
121
121
  flex: none; width: 16px; height: 16px; border-radius: 50%;
122
- background: conic-gradient(var(--green) var(--sx-a, 360deg), var(--surface-2) 0); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */
122
+ background: conic-gradient(var(--green) var(--sx-a, 360deg), var(--surface-2) 0); /* code-bg: inherit — decorative or text-only paint; nothing nested reads a ground from it. */
123
123
  mask: radial-gradient(circle, transparent 5px, #000 6px);
124
124
  -webkit-mask: radial-gradient(circle, transparent 5px, #000 6px);
125
125
  animation: ui-sx-sweep var(--sx-secs, 5s) linear forwards; /* motion: ambient — the caller sets the countdown; the ring just spends it */
@@ -132,7 +132,7 @@
132
132
  @media (prefers-reduced-motion: reduce) {
133
133
  .ui-sx__check--line .ui-sx__tick { animation: none; stroke-dashoffset: 0; }
134
134
  .ui-sx__confetti { display: none; }
135
- .ui-sx__count-ring { animation: none; background: var(--surface-2); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ }
135
+ .ui-sx__count-ring { animation: none; background: var(--surface-2); /* code-bg: inherit — decorative or text-only paint; nothing nested reads a ground from it. */ }
136
136
  }
137
137
 
138
138
  /* ---- Narrow — split stacks -------------------------------------------- */
@@ -67,7 +67,7 @@
67
67
  border-spacing: 0;
68
68
  padding: 0 var(--space-2);
69
69
  }
70
- .ui-table--hover:not(.ui-table--zebra) tbody tr:hover td { background: var(--surface-2); --ring-gap: var(--surface-2); }
70
+ .ui-table--hover:not(.ui-table--zebra) tbody tr:hover td { background: var(--surface-2); }
71
71
  .ui-table--hover:not(.ui-table--zebra) tbody tr:hover td:first-child {
72
72
  border-top-left-radius: var(--radius-sm); border-bottom-left-radius: var(--radius-sm); }
73
73
  .ui-table--hover:not(.ui-table--zebra) tbody tr:hover td:last-child {
@@ -90,7 +90,7 @@
90
90
  .ui-table--zebra thead th { border-bottom-width: 2px; }
91
91
  .ui-table--zebra td,
92
92
  .ui-table--zebra :is(tbody, tfoot) th { border-bottom: 0; }
93
- .ui-table--zebra tbody tr:nth-child(even) td { background: var(--surface-2); --ring-gap: var(--surface-2); }
93
+ .ui-table--zebra tbody tr:nth-child(even) td { background: var(--surface-2); }
94
94
  /* The stripe stays full-bleed (the #71 inset above is hover only), but it only reads right
95
95
  * if the end cells are inset from the row's own edge, and `.ui-table td` sets
96
96
  * `padding-left: 0`. Only `--dense` supplied that inset, so `--zebra` without `--dense` —
@@ -102,7 +102,7 @@
102
102
  .ui-table--zebra th:last-child,
103
103
  .ui-table--zebra td:last-child { padding-right: var(--space-3); }
104
104
  .ui-table--zebra.ui-table--hover tbody tr:hover td,
105
- .ui-table--zebra tbody tr:hover td { --ring-gap: inherit; background: color-mix(in srgb, var(--accent) 8%, transparent); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ }
105
+ .ui-table--zebra tbody tr:hover td { background: color-mix(in srgb, var(--accent) 8%, transparent); /* code-bg: inherit — a wash paints over a ground and behind a chip, so the opaque ground below it is the step. */ }
106
106
 
107
107
  /* A link in a cell is a value that happens to open something: the row's ink, underlined
108
108
  on hover — what .ui-identity below has always done. Without it, base.css's bare
@@ -150,8 +150,8 @@
150
150
  why: guidelines/state-set.md#focus-rings
151
151
  held by: src/styles/table-focus.test.js */
152
152
  .ui-table a:not(.ui-btn):focus-visible {
153
- outline: 2px solid transparent;
154
- box-shadow: var(--ring);
153
+ outline: var(--ring);
154
+ outline-offset: var(--ring-offset);
155
155
  }
156
156
 
157
157
  .ui-table__num { text-align: right; font-variant-numeric: tabular-nums; }
@@ -175,12 +175,12 @@
175
175
  .ui-card { --table-bg: var(--surface); --table-code-bg: var(--bg); }
176
176
 
177
177
  /* White in light, base canvas in dark; never a grey or tinted data surface. */
178
- .ui-table { background: var(--table-bg); --ring-gap: var(--table-bg); }
178
+ .ui-table { background: var(--table-bg); }
179
179
  .ui-table--zebra tbody tr:nth-child(even) td,
180
180
  .ui-table--hover:not(.ui-table--zebra) tbody tr:hover td,
181
181
  .ui-table--zebra tbody tr:hover td,
182
182
  .ui-table--zebra.ui-table--hover tbody tr:hover td {
183
- background: var(--table-bg); --ring-gap: var(--table-bg);
183
+ background: var(--table-bg);
184
184
  }
185
185
  .ui-table tbody tr:hover { outline: 1px solid var(--border-strong); outline-offset: -1px; }
186
186
 
@@ -215,8 +215,8 @@
215
215
  why: docs/foundations.md#the-focus-ring */
216
216
  .ui-table-scroll:focus-visible { outline: var(--ring-scroll); outline-offset: var(--ring-scroll-offset); }
217
217
  .ui-table--sticky { border-collapse: separate; border-spacing: 0; }
218
- .ui-table--sticky thead th { position: sticky; top: 0; z-index: var(--z-sticky); background: var(--table-bg); --ring-gap: var(--table-bg); padding-top: var(--space-2); }
219
- .ui-table--pinned .ui-table__identity, .ui-table--pinned .ui-table__selection { position: sticky; left: 0; z-index: var(--z-base); background: var(--table-bg); --ring-gap: var(--table-bg); border-right: 1px solid var(--border); }
218
+ .ui-table--sticky thead th { position: sticky; top: 0; z-index: var(--z-sticky); background: var(--table-bg); padding-top: var(--space-2); }
219
+ .ui-table--pinned .ui-table__identity, .ui-table--pinned .ui-table__selection { position: sticky; left: 0; z-index: var(--z-base); background: var(--table-bg); border-right: 1px solid var(--border); }
220
220
  .ui-table--pinned thead .ui-table__identity, .ui-table--pinned thead .ui-table__selection { z-index: calc(var(--z-sticky) + 1); }
221
221
  .ui-value, .ui-delta { white-space: nowrap; font-variant-numeric: tabular-nums; }
222
222
  .ui-value__unit { margin-left: var(--space-1); font-size: var(--text-xs); color: var(--text); }
@@ -229,7 +229,7 @@
229
229
  .ui-identity__logo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
230
230
  .ui-identity__logo img[hidden] { display: none; /* motion: still — a failed resource is replaced without animating the error. */ }
231
231
  a.ui-identity:hover { text-decoration: underline; }
232
- .ui-identity:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); border-radius: var(--radius-xs); }
232
+ .ui-identity:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); border-radius: var(--radius-xs); }
233
233
  @media (max-width: 720px) {
234
234
  .ui-table--pinned .ui-table__identity { width: 1%; }
235
235
  .ui-table--pinned .ui-identity__logo { display: none; }
@@ -22,7 +22,7 @@
22
22
  }
23
23
  .ui-tabs__tab:hover { color: var(--strong); }
24
24
  .ui-tabs__tab.is-active { color: var(--strong); border-bottom-color: var(--accent); }
25
- .ui-tabs__tab:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); border-radius: 7px 7px 0 0; }
25
+ .ui-tabs__tab:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); border-radius: 7px 7px 0 0; }
26
26
 
27
27
  .ui-tabs__panels { padding-top: 20px; }
28
28
  .ui-tabs__panel[hidden] { display: none; }
@@ -31,4 +31,4 @@
31
31
  .ui-tabs__panel.is-entering { animation: m-fade var(--dur-fast) var(--ease-out) both; }
32
32
  /* The panel is focusable (tabindex="0", see tabs.js) so a keyboard user can
33
33
  reach text-only content. Show the ring when they land on it. */
34
- .ui-tabs__panel:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); border-radius: 8px; }
34
+ .ui-tabs__panel:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); border-radius: 8px; }
@@ -25,7 +25,7 @@
25
25
  width: max-content;
26
26
  max-width: var(--prose-caption);
27
27
  padding: var(--space-2) var(--space-3);
28
- background: var(--ui-tip-bg); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */
28
+ background: var(--ui-tip-bg); /* code-bg: inherit — decorative or text-only paint; nothing nested reads a ground from it. */
29
29
  /* The two-step edge and the drop, through the level's own names: in DARK that is
30
30
  --border-strong outside and --border one pixel inside it, then the drop; in LIGHT
31
31
  both lines are transparent and the drop carries the whole separation.