/* app/set-core.css — the Settings design layer.
   ============================================================================================
   NAMESPACE: every selector here starts `.e8-set-`. Grep before adding a new one; this app has a
   single global stylesheet namespace and a duplicate class name silently overrides across features
   (later definition wins), which has broken unrelated screens before.

   WHY THE MEASUREMENTS ARE LOCAL CUSTOM PROPERTIES
   The whole surface is 20 pages assembled from six primitives. The reference's polish is mostly
   dimensional consistency, so every number that repeats is a variable declared once on `.e8-set`
   below. Changing the row rhythm is then one edit, not 20, and a page CANNOT drift by hardcoding a
   different padding without it being obvious in review.

   COLOURS ARE TOKENS ONLY. No hex. `--ui-*` or `color-mix()` on them, so dark mode inverts for free
   and the accent derivation (Sam Dever Mode) reaches this surface like everywhere else.
   ============================================================================================ */

.e8-set {
  /* rhythm */
  /* 176px, not the 232px this shipped at. The reference rail is ~172px at a 1500px viewport, and the
     longest label we have - `Notifications` - ends 122px in, so 232px was carrying 110px of empty
     rail AND taking it out of the content column (1048px of shell for a 960px column left 44px
     gutters). Everything else about the rail measured correct, so this is the one number. */
  --set-rail-w: 176px;
  --set-col-max: 960px;
  --set-card-pad-x: 20px;
  --set-row-pad-y: 16px;
  --set-gap-row: 12px;
  /* shape */
  --set-radius-card: var(--ui-radius-card);
  --set-radius-ctl: var(--ui-radius-md);
  --set-radius-pill: var(--ui-radius-pill);
  /* surfaces, all token-derived */
  --set-line: var(--ui-border);
  /* Measured, not guessed. At 55% this composited to rgb(248,248,250) over a white card — 7 levels
     of separation, which reads as "slightly off-white" rather than as a header. The reference's
     header strips sit around 9-10 levels down. 80% of --ui-fill lands at 245/246, which separates
     without turning into a grey band. Both the notifications column header and the Features master
     row depend on this reading as a distinct register, so it is one variable, not per-page. */
  --set-tint: color-mix(in srgb, var(--ui-fill) 80%, transparent);
  --set-glyph-bg: color-mix(in srgb, var(--ui-fill) 60%, transparent);

  display: flex;
  align-items: stretch;
  min-height: 0;
  flex: 1;
  background: var(--ui-bg-app);
}

/* ---------- rail ---------------------------------------------------------------------------- */
.e8-set-railwrap { flex: 0 0 var(--set-rail-w); width: var(--set-rail-w); }
.e8-set-rail {
  position: sticky; top: 0; height: 100vh; width: var(--set-rail-w);
  display: flex; flex-direction: column; gap: 2px;
  padding: 12px 10px; background: var(--ui-bg-app);
  border-right: 1px solid var(--set-line);
}
.e8-set-rail-back,
.e8-set-rail-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 9px; border: 0; border-radius: 7px; background: transparent;
  color: var(--ui-text-secondary); font: inherit; font-size: var(--ui-text-base);
  text-align: left; cursor: pointer;
}
.e8-set-rail-back { margin-bottom: 6px; }
.e8-set-rail-back .material-symbols-outlined,
.e8-set-rail-item .material-symbols-outlined { font-size: var(--ui-icon-sm); color: var(--ui-icon-quiet); flex: none; }
.e8-set-rail-back:hover,
.e8-set-rail-item:hover { background: color-mix(in srgb, var(--ui-fill) 55%, transparent); color: var(--ui-text); }
.e8-set-rail-item.is-on { background: var(--ui-fill); color: var(--ui-text); font-weight: 500; }
.e8-set-rail-item.is-on .material-symbols-outlined { color: var(--ui-text); }

.e8-set-rail-search {
  position: relative; display: flex; align-items: center; margin: 2px 0 10px;
}
.e8-set-rail-search .material-symbols-outlined {
  position: absolute; left: 9px; font-size: var(--ui-icon-xs); color: var(--ui-text-tertiary); pointer-events: none;
}
.e8-set-rail-search input {
  width: 100%; height: 32px; padding: 0 10px 0 30px;
  border: 1px solid var(--set-line); border-radius: var(--set-radius-ctl);
  background: var(--ui-surface); color: var(--ui-text);
  font: inherit; font-size: var(--ui-text-base);
}
.e8-set-rail-search input::placeholder { color: var(--ui-text-tertiary); }
.e8-set-rail-search input::-webkit-search-cancel-button { cursor: pointer; }

.e8-set-rail-scroll { flex: 1; min-height: 0; overflow-y: auto; margin: 0 -4px; padding: 0 4px; }
.e8-set-rail-group + .e8-set-rail-group { margin-top: 16px; }
.e8-set-rail-cap {
  padding: 0 9px 6px; font-size: var(--ui-text-xs); font-weight: 500;
  color: var(--ui-text-tertiary); letter-spacing: 0.01em;
}
.e8-set-rail-none { padding: 10px 9px; font-size: var(--ui-text-base); color: var(--ui-text-tertiary); }

/* ---------- body + top bar ------------------------------------------------------------------ */
.e8-set-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* `position: relative` is load-bearing, not tidiness: at 640px and below the help popover drops its
   own containing block so it can span the bar instead of overflowing off the right edge. */
.e8-set-topbar {
  position: relative;
  display: flex; align-items: center; gap: 8px; flex: none;
  height: 52px; padding: 0 20px; border-bottom: 1px solid var(--set-line);
  background: var(--ui-bg-app);
}
.e8-set-crumbs { display: flex; align-items: center; gap: 2px; min-width: 0; }
.e8-set-crumbs button {
  border: 0; background: transparent; padding: 4px 6px; border-radius: 6px; cursor: pointer;
  font: inherit; font-size: var(--ui-text-base); color: var(--ui-text-secondary);
}
.e8-set-crumbs button:hover { background: var(--ui-fill); color: var(--ui-text); }
.e8-set-crumbs .material-symbols-outlined { font-size: var(--ui-icon-xs); color: var(--ui-text-tertiary); }
.e8-set-crumb-on {
  padding: 4px 8px; border-radius: 6px; background: var(--ui-fill);
  font-size: var(--ui-text-base); font-weight: 500; color: var(--ui-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* The only colour in the top bar, per the reference - so it has to be worth the colour. The popover
   it opens is anchored to the button here and re-anchored to the whole bar at 640px and below. */
/* `align-self: stretch` is what makes `top: 100%` on the popover mean "below the top BAR" rather
   than "below the 24px button", which cleared the bar's bottom hairline by -6px and painted over it.
   Stretching the wrapper to the bar's height puts the two edges in the same coordinate space, so the
   8px gap stays 8px if the bar height ever changes. */
.e8-set-helpwrap { position: relative; flex: none; display: inline-flex; align-items: center; align-self: stretch; }
.e8-set-help {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0; border: 0; border-radius: var(--set-radius-pill);
  background: transparent; color: var(--ui-accent); cursor: pointer;
}
.e8-set-help .material-symbols-outlined { font-size: var(--ui-icon-sm); }
.e8-set-help:hover { background: var(--ui-wash); }
.e8-set-help[aria-expanded="true"] { background: var(--ui-wash); }

.e8-set-helppop {
  position: absolute; top: calc(100% + 8px); left: -8px; z-index: 40;
  width: 320px; max-width: calc(100vw - 32px);
  padding: 14px 16px 12px; border: 1px solid var(--set-line);
  border-radius: var(--set-radius-card); background: var(--ui-surface);
  box-shadow: var(--ui-shadow-pop); text-align: left;
}
.e8-set-helppop-t { font-size: var(--ui-text-md); font-weight: 600; color: var(--ui-text); }
.e8-set-helppop-b {
  margin-top: 5px; font-size: var(--ui-text-base); line-height: 1.5; color: var(--ui-text-secondary);
}
.e8-set-helppop-link {
  display: inline-flex; align-items: center; gap: 4px; margin-top: 10px;
  padding: 4px 8px 4px 0; border: 0; border-radius: 6px; background: transparent;
  font: inherit; font-size: var(--ui-text-base); font-weight: 500; color: var(--ui-accent);
  cursor: pointer;
}
.e8-set-helppop-link:hover { text-decoration: underline; }
.e8-set-helppop-link .material-symbols-outlined { font-size: var(--ui-icon-xs); }

/* Shown only at drawer widths - see the narrow block at the foot of this file. */
.e8-set-pagesel { display: none; }

.e8-set-scroll { flex: 1; min-height: 0; overflow-y: auto; }
.e8-set-col { max-width: var(--set-col-max); margin: 0 auto; padding: 36px 24px 96px; }

/* ---------- page + section ------------------------------------------------------------------ */
.e8-set-pagehead { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 4px; }
.e8-set-pagehead-txt { flex: 1; min-width: 0; }
.e8-set-pagehead h1 {
  margin: 0; font-size: var(--ui-text-display); font-weight: 600;
  letter-spacing: -0.02em; color: var(--ui-text);
}
.e8-set-pagehead p {
  margin: 6px 0 0; font-size: var(--ui-text-md); color: var(--ui-text-secondary);
}
.e8-set-pagehead-act { flex: none; padding-top: 4px; }

.e8-set-section { margin-top: 30px; }
.e8-set-sectionhead { display: flex; align-items: flex-end; gap: 16px; margin-bottom: 12px; }
.e8-set-sectionhead > div:first-child { flex: 1; min-width: 0; }
.e8-set-sectionhead h2 {
  margin: 0; font-size: var(--ui-text-xl); font-weight: 600; color: var(--ui-text);
  letter-spacing: -0.01em;
}
.e8-set-sectionhead p {
  margin: 4px 0 0; font-size: var(--ui-text-base); color: var(--ui-text-secondary);
}
.e8-set-section > .e8-set-card + .e8-set-card { margin-top: 14px; }

/* ---------- card + row ----------------------------------------------------------------------- */
.e8-set-card {
  background: var(--ui-surface); border: 1px solid var(--set-line);
  border-radius: var(--set-radius-card); overflow: hidden;
}
/* The divider is INSET to the card padding rather than run edge-to-edge — an edge-to-edge hairline
   is one of the named tells that a surface was not built to the grammar.

   One mechanism, deliberately. The first cut used three at once (an inset box-shadow for the line,
   a ::before painting surface colour over it, and a ::after drawing the inset line on top). Three
   overlapping hairlines at subpixel offsets is how you get a divider that looks slightly grey on
   one card and slightly double on another depending on scroll position.

   `> * + *` means no line above the first child or below the last, for free. Banners opt out
   because .e8-set-banner.is-incard draws its own full-bleed top and bottom rules — an inset
   hairline immediately above a full-bleed one reads as a mistake. */
.e8-set-card > * { position: relative; }
.e8-set-card > * + *:not(.e8-set-banner)::before {
  content: ''; position: absolute; top: 0; height: 1px; background: var(--set-line);
  left: var(--set-card-pad-x); right: var(--set-card-pad-x);
}
/* A row that follows a banner gets no line either, for the same reason, from the other side. */
.e8-set-card > .e8-set-banner + *::before { display: none; }

.e8-set-row {
  display: flex; align-items: center; gap: 14px; width: 100%;
  padding: var(--set-row-pad-y) var(--set-card-pad-x);
  background: transparent; border: 0; text-align: left; font: inherit; color: inherit;
}
.e8-set-row.is-tinted { background: var(--set-tint); }
.e8-set-row-txt { flex: 1; min-width: 0; display: block; }
.e8-set-row-label {
  display: block; font-size: var(--ui-text-md); font-weight: 500; color: var(--ui-text);
  line-height: 1.35;
}
.e8-set-row-desc {
  display: block; margin-top: 2px; font-size: var(--ui-text-base);
  color: var(--ui-text-secondary); line-height: 1.45;
}
/* Sizes to content on purpose. Forcing a uniform control width is a named failure mode - the
   reference lets a "Central European Summer Time" select be wide and a "Monday" select be narrow. */
.e8-set-row-ctl { flex: none; display: flex; align-items: center; gap: 8px; }
.e8-set-row-meta { flex: none; font-size: var(--ui-text-base); color: var(--ui-text-secondary); }

.e8-set-navrow { cursor: pointer; }
.e8-set-navrow:hover { background: color-mix(in srgb, var(--ui-fill) 45%, transparent); }
.e8-set-chev { font-size: var(--ui-icon-sm); color: var(--ui-text-tertiary); flex: none; }

.e8-set-cardhead {
  display: flex; align-items: center; gap: 12px;
  padding: 14px var(--set-card-pad-x); background: var(--set-tint);
}
.e8-set-cardhead-txt { flex: 1; min-width: 0; }
.e8-set-cardhead-t { font-size: var(--ui-text-md); font-weight: 600; color: var(--ui-text); }
.e8-set-cardhead-d { margin-top: 2px; font-size: var(--ui-text-base); color: var(--ui-text-secondary); }
.e8-set-cardhead-act { flex: none; }

.e8-set-glyph {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 9px;
  background: var(--set-glyph-bg); border: 1px solid var(--set-line);
}
.e8-set-glyph .material-symbols-outlined { font-size: var(--ui-icon-md); color: var(--ui-icon-quiet); }

/* One class dims a whole dependent block. Doing this per-control is the tell-tale half-state where
   the label stays full-strength and only the select greys - a named failure mode in the spec. */
.e8-set-card.is-locked,
.e8-set-row.is-locked { opacity: 0.42; pointer-events: none; }
.e8-set-card.is-locked .e8-set-navrow,
.e8-set-card.is-locked .e8-set-row:not(.is-locked) { opacity: 1; }

/* ---------- controls -------------------------------------------------------------------------- */
.e8-set-toggle {
  position: relative; flex: none; width: 40px; height: 22px; padding: 0;
  border: 0; border-radius: var(--set-radius-pill); cursor: pointer;
  background: color-mix(in srgb, var(--ui-border-strong) 80%, transparent);
  transition: background 160ms ease;
}
.e8-set-toggle.is-on { background: var(--ui-accent); }
.e8-set-toggle-knob {
  position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%;
  background: var(--ui-surface); box-shadow: var(--ui-shadow-1);
  transition: transform 160ms cubic-bezier(0.2, 0, 0, 1);
}
.e8-set-toggle.is-on .e8-set-toggle-knob { transform: translateX(18px); }
.e8-set-toggle:disabled { cursor: not-allowed; opacity: 0.5; }

.e8-set-check {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; padding: 0; border-radius: 5px; cursor: pointer;
  border: 1px solid var(--ui-border-strong); background: var(--ui-surface);
  transition: background 120ms ease, border-color 120ms ease;
}
.e8-set-check.is-on { background: var(--ui-accent); border-color: var(--ui-accent); }
.e8-set-check .material-symbols-outlined { font-size: var(--ui-icon-xs); color: var(--ui-accent-text); }
.e8-set-check:disabled { cursor: not-allowed; opacity: 0.5; }

.e8-set-select {
  position: relative; display: inline-flex; align-items: center; gap: 6px;
  height: 34px; padding: 0 30px 0 11px;
  border: 1px solid var(--set-line); border-radius: var(--set-radius-ctl);
  background: var(--ui-surface); color: var(--ui-text); font-size: var(--ui-text-base);
  max-width: 100%;
}
.e8-set-select:hover { border-color: var(--ui-border-strong); }
.e8-set-select select {
  appearance: none; -webkit-appearance: none;
  border: 0; background: transparent; color: inherit; font: inherit;
  padding: 0; margin: 0; cursor: pointer; max-width: 100%;
  text-overflow: ellipsis;
}
.e8-set-select select:focus { outline: none; }
.e8-set-select-chev {
  position: absolute; right: 9px; font-size: var(--ui-icon-sm); color: var(--ui-text-tertiary); pointer-events: none;
}
.e8-set-select-prefix { color: var(--ui-text-secondary); flex: none; }
.e8-set-select-flag { flex: none; }
.e8-set-select.is-disabled { opacity: 0.45; }
.e8-set-select.is-disabled select { cursor: not-allowed; }
.e8-set-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; }

.e8-set-input {
  display: inline-flex; align-items: center; gap: 0;
  height: 34px; padding: 0 11px; max-width: 100%;
  border: 1px solid var(--set-line); border-radius: var(--set-radius-ctl);
  background: var(--ui-surface); font-size: var(--ui-text-md); color: var(--ui-text);
}
.e8-set-input.is-sm { width: 120px; }
.e8-set-input.is-md { width: 190px; }
.e8-set-input.is-lg { width: 300px; }
.e8-set-input.is-full { width: 100%; }
.e8-set-input input {
  flex: 1; min-width: 0; border: 0; background: transparent; color: inherit; font: inherit;
  padding: 0; outline: none;
}
.e8-set-input input::placeholder { color: var(--ui-text-tertiary); }
.e8-set-input-prefix { flex: none; color: var(--ui-text-secondary); }
.e8-set-input:focus-within { border-color: var(--ui-accent); }
.e8-set-input.is-disabled { opacity: 0.45; }

.e8-set-seg {
  display: inline-flex; gap: 2px; padding: 2px; border-radius: var(--set-radius-ctl);
  background: var(--ui-fill);
}
.e8-set-seg button {
  border: 0; background: transparent; cursor: pointer; font: inherit;
  font-size: var(--ui-text-base); color: var(--ui-text-secondary);
  padding: 5px 12px; border-radius: 6px;
}
.e8-set-seg button[aria-pressed="true"] {
  background: var(--ui-surface); color: var(--ui-text); font-weight: 500; box-shadow: var(--ui-shadow-1);
}

.e8-set-radiocard {
  display: flex; align-items: center; gap: 14px; width: 100%; text-align: left;
  padding: 13px 15px; border: 1px solid var(--set-line); border-radius: var(--set-radius-card);
  background: var(--ui-surface); cursor: pointer; font: inherit; color: inherit;
}
.e8-set-radiocard + .e8-set-radiocard { margin-top: 10px; }
.e8-set-radiocard-txt { flex: 1; min-width: 0; }
.e8-set-radiocard-t { display: block; font-size: var(--ui-text-md); font-weight: 500; color: var(--ui-text); }
.e8-set-radiocard-d { display: block; margin-top: 2px; font-size: var(--ui-text-base); color: var(--ui-text-secondary); }
.e8-set-radio {
  flex: none; width: 18px; height: 18px; border-radius: 50%;
  border: 1px solid var(--ui-border-strong); background: var(--ui-surface);
}
.e8-set-radiocard.is-on { border-color: var(--ui-accent); box-shadow: inset 0 0 0 1px var(--ui-accent); }
.e8-set-radiocard.is-on .e8-set-radio {
  border-color: var(--ui-accent);
  background: radial-gradient(circle, var(--ui-accent) 0 4.5px, var(--ui-surface) 5px 100%);
}

.e8-set-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 34px; padding: 0 13px; border-radius: var(--set-radius-ctl);
  border: 1px solid transparent; cursor: pointer; white-space: nowrap;
  font: inherit; font-size: var(--ui-text-base); font-weight: 500; text-decoration: none;
}
/* `color: inherit` is the whole fix for a measured defect, not tidiness. `product.css:267`
   (`.elev8 .material-symbols-outlined`) gives every glyph in the app a secondary-ink colour. This
   rule set only font-size, so a glyph inside a filled accent button kept that grey — measured at
   1.45:1 against the accent fill while the label beside it sat at 7.31:1. Seven hero CTAs shipped
   with an effectively invisible icon: Invite user, Create team, Continue to payment, Create API key,
   Add domain, New role, Add endpoint.
   Both selectors are (0,2,0), so this wins purely on source order — set-core.css is linked after
   styles.css. Inheriting rather than naming a colour is what makes it correct for every button
   variant at once: white on primary, primary ink on secondary, danger ink on danger. */
.e8-set-btn .material-symbols-outlined { font-size: var(--ui-icon-sm); color: inherit; }
.e8-set-btn.is-secondary { background: var(--ui-surface); border-color: var(--set-line); color: var(--ui-text); }
.e8-set-btn.is-secondary:hover { background: var(--ui-fill); }
.e8-set-btn.is-primary { background: var(--ui-accent); color: var(--ui-accent-text); }
.e8-set-btn.is-primary:hover { background: var(--ui-accent-hover); }
.e8-set-btn.is-quiet { background: transparent; color: var(--ui-text-secondary); }
.e8-set-btn.is-quiet:hover { background: var(--ui-fill); color: var(--ui-text); }
.e8-set-btn.is-danger { background: transparent; color: var(--ui-danger); border-color: transparent; }
.e8-set-btn.is-danger:hover { background: color-mix(in srgb, var(--ui-danger) 10%, transparent); }
.e8-set-btn:disabled { opacity: 0.42; cursor: not-allowed; }
.e8-set-btn-ext { font-size: var(--ui-icon-xs) !important; color: var(--ui-text-tertiary); }

.e8-set-pill {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px;
  border-radius: var(--set-radius-pill); font-size: var(--ui-text-sm); font-weight: 500;
  background: var(--ui-fill); color: var(--ui-text-secondary);
}
.e8-set-pill.is-ok { background: color-mix(in srgb, var(--ui-success) 14%, transparent); color: var(--ui-success); }
.e8-set-pill.is-warn { background: color-mix(in srgb, var(--ui-warning) 16%, transparent); color: var(--ui-warning); }
.e8-set-pill.is-info { background: var(--ui-wash); color: var(--ui-daybreak-text); }
.e8-set-pill.is-danger { background: color-mix(in srgb, var(--ui-danger) 12%, transparent); color: var(--ui-danger); }

.e8-set-banner {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px; border-radius: var(--set-radius-ctl); border: 1px solid transparent;
  font-size: var(--ui-text-base); line-height: 1.45; margin-bottom: 12px;
}
.e8-set-banner .material-symbols-outlined { font-size: var(--ui-icon-sm); flex: none; margin-top: 1px; }
.e8-set-banner.is-warn {
  background: color-mix(in srgb, var(--ui-warning) 12%, transparent);
  border-color: color-mix(in srgb, var(--ui-warning) 26%, transparent);
  color: var(--ui-text);
}
.e8-set-banner.is-warn .material-symbols-outlined { color: var(--ui-warning); }
.e8-set-banner.is-info {
  background: var(--ui-wash); border-color: color-mix(in srgb, var(--ui-accent) 18%, transparent);
  color: var(--ui-text);
}
.e8-set-banner.is-info .material-symbols-outlined { color: var(--ui-accent); }
.e8-set-banner.is-incard { margin: 0; border-radius: 0; border-width: 1px 0; }

.e8-set-empty { padding: 56px 24px; text-align: center; }
.e8-set-empty-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 60px; height: 60px; border-radius: 50%; margin-bottom: 14px;
  background: var(--ui-fill); border: 1px solid var(--set-line);
}
.e8-set-empty-badge .material-symbols-outlined { font-size: var(--ui-icon-xl); color: var(--ui-text-tertiary); }
.e8-set-empty-t { font-size: var(--ui-text-xl); font-weight: 600; color: var(--ui-text); }
.e8-set-empty-d { margin-top: 5px; font-size: var(--ui-text-base); color: var(--ui-text-secondary); }
.e8-set-empty-a { margin-top: 16px; }
.e8-set-empty-inline {
  padding: 15px var(--set-card-pad-x); font-size: var(--ui-text-base); color: var(--ui-text-secondary);
}

/* ---------- focus ----------------------------------------------------------------------------
   One rule for the whole surface. The reference is keyboard-complete and a missing ring is a named
   failure mode, so this is deliberately broad rather than per-component. */
.e8-set :focus-visible { outline: none; box-shadow: var(--ui-focus-ring); border-radius: 6px; }
.e8-set .e8-set-toggle:focus-visible,
.e8-set .e8-set-pill:focus-visible { border-radius: var(--set-radius-pill); }

/* The ring belongs on the control the reader can SEE. `.e8-set-select` and `.e8-set-input` are
   wrappers: the focusable element inside each is the bare <select>/<input>, which is only as tall as
   its own text and does not include the prefix word, the flag, the colour dot or the chevron. So the
   broad rule above drew the ring 14px short and 76px narrow, cutting through the middle of a 34px
   field and excluding its ornaments. Ring the wrapper, mute the inner element.

   Wrapped in @supports so the two halves stand or fall together. Without it, a browser that cannot
   do :has() would drop the wrapper rule, keep the muting rule, and leave these controls with NO
   focus ring at all - trading an ugly ring for a missing one, which is the named failure mode. */
@supports selector(:has(*)) {
  .e8-set .e8-set-select select:focus-visible,
  .e8-set .e8-set-input input:focus-visible { box-shadow: none; }
  .e8-set .e8-set-select:has(select:focus-visible),
  .e8-set .e8-set-input:has(input:focus-visible) {
    box-shadow: var(--ui-focus-ring); border-radius: var(--set-radius-ctl);
  }
}

/* ---------- narrow ---------------------------------------------------------------------------
   Placed AFTER every rule it overrides. A conditional at-rule adds no specificity, so a @media
   block written above its own base rule never applies - that has shipped here three times. */
.e8-set-scrim { display: none; }

@media (max-width: 840px) {
  .e8-set-railwrap {
    position: fixed; inset: 0 auto 0 0; z-index: 60;
    transform: translateX(-100%); transition: transform 200ms cubic-bezier(0.2, 0, 0, 1);
  }
  .e8-set.is-drawer .e8-set-railwrap { transform: translateX(0); }
  .e8-set-rail { box-shadow: var(--ui-shadow-pop); }
  .e8-set-scrim {
    display: block; position: fixed; inset: 0; z-index: 55; border: 0;
    background: var(--ui-scrim); cursor: pointer;
  }
  /* The drawer is fixed to the viewport, so 100vh is a lie while the mobile URL bar is showing - it
     puts the foot of the list below the fold. 100% of a viewport-fixed wrapper is the honest height.
     Then reserve the app's own bottom tab bar inside the SCROLLER, not around it: `.e8-tabbar`
     (app/app.css) is fixed at z-index 60, the same layer as this drawer and later in the DOM, so it
     wins the tie and swallows whatever sits under it. Billing was at y 798-832 with the tab bar
     starting at 786 and the scroller already at its maximum - unreachable, not merely obscured.
     58px is the tab bar's own height; the extra 12px is so the last item clears it rather than
     touching it. */
  .e8-set-rail { height: 100%; }
  .e8-set-rail-scroll { padding-bottom: calc(70px + env(safe-area-inset-bottom, 0px)); }

  /* The page name as a select, replacing the hamburger that used to stack under the app's own. */
  .e8-set-crumbs { display: none; }
  .e8-set-pagesel {
    display: inline-flex; align-items: center; gap: 6px;
    flex: 0 1 auto; min-width: 0; height: 32px; padding: 0 8px 0 10px;
    border: 1px solid var(--set-line); border-radius: var(--set-radius-ctl);
    background: var(--ui-surface); color: var(--ui-text);
    font: inherit; font-size: var(--ui-text-base); font-weight: 500;
    text-align: left; cursor: pointer;
  }
  .e8-set-pagesel:hover { border-color: var(--ui-border-strong); }
  .e8-set-pagesel:focus-visible { border-radius: var(--set-radius-ctl); }
  .e8-set-pagesel-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .e8-set-pagesel-chev { font-size: var(--ui-icon-sm); color: var(--ui-text-tertiary); flex: none; }

  .e8-set-col { padding: 24px 16px 80px; }
  .e8-set-topbar { padding: 0 16px; }

  /* THE ONE EXCEPTION TO THE BROAD FOCUS RULE, and it lives HERE — after `.e8-set-rail`'s own
     `box-shadow` two dozen lines up, and inside the only width where the rail can be focused at all.
     The rail is `tabindex="-1"` purely so the drawer can put focus on the region when it opens
     (app/set-core.jsx); nothing can ever TAB to it, so there is no keyboard journey for a ring to
     describe, and `.e8-set :focus-visible` was painting a 4px accent ring down the full 812px edge
     of the drawer on every open, mouse or keyboard. Suppressing the indicator on a script-only
     focus target is the ARIA-practices pattern for this move.
     It re-states `--ui-shadow-pop` rather than saying `box-shadow: none`: the ring and the drawer's
     own elevation are the same property, so muting one without naming the other flattened the open
     drawer against the page. Every control INSIDE the rail keeps the broad rule. */
  .e8-set .e8-set-rail:focus,
  .e8-set .e8-set-rail:focus-visible { outline: none; box-shadow: var(--ui-shadow-pop); }
}

@media (max-width: 640px) {
  /* The card HEADER has to agree with the row about what narrow means. `.e8-set-row` wraps here and
     `.e8-set-cardhead` had no rule at all, so the two primitives disagreed: measured at 390px the
     seven headers on Stages and Labels grew from 71px to 130-171px tall, with the description
     crushed into a ~132px column beside the action button, while the rows underneath wrapped
     cleanly. Same breakpoint, same behaviour - the action drops to its own line rather than
     squeezing the text it sits beside. */
  .e8-set-cardhead { flex-wrap: wrap; }
  .e8-set-cardhead-txt { flex: 1 1 100%; min-width: 0; }
  .e8-set-cardhead-act { flex: 0 0 auto; margin-top: 10px; }
  .e8-set-pagehead { flex-direction: column; gap: 12px; }
  .e8-set-pagehead-act { padding-top: 0; }
  /* Rows stack rather than squeeze: a 34px select beside a two-line description at 390px leaves the
     label ~120px wide and the description unreadable. */
  .e8-set-row { align-items: flex-start; flex-wrap: wrap; }
  .e8-set-row-ctl { width: 100%; padding-left: 0; }
  .e8-set-row.e8-set-navrow { flex-wrap: nowrap; align-items: center; }
  .e8-set-select, .e8-set-input { width: 100%; }
  .e8-set-select select { flex: 1; }

  /* Drop the wrapper's containing block so the popover resolves against `.e8-set-topbar` and spans
     the bar. Anchored to the button it would run off the right edge at 390px: the button sits
     ~170px in and the card is 320px wide. */
  .e8-set-helpwrap { position: static; }
  .e8-set-helppop { left: 16px; right: 16px; width: auto; max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
  .e8-set-toggle, .e8-set-toggle-knob, .e8-set-railwrap { transition: none; }
}
