/* ── OCTOPONG · settings ─────────────────────────────────────
   Built from References/Settings: a breadcrumb title, a chunky
   category rail down the left with a gold shard on the active
   item, a scrolling list of setting rows in the middle, and a LIVE
   PREVIEW panel on the right.

   Everything structural comes from theme.css (.panel, .panel-head,
   .btn, .pill, .chip, .meter). Only what does not exist there is
   defined here, and it is all prefixed .set- or scoped inside
   .settings so nothing leaks into another screen.

   The one deliberate exception is the block at the bottom marked
   GLOBAL ACCESSIBILITY. Those rules are keyed off classes on
   <html> and are meant to reach the whole shell — this screen is
   where the switches live, so this is where they are honoured.

   TWO TRAPS, both already paid for once on this project:

     1. Do NOT outline a clipped shape with a ::before at
        z-index:-1. clip-path and filter each open a stacking
        context, and a negative-z child of one paints ABOVE its
        parent's background — the outline layer floods the face.
        Use the chained zero-blur drop-shadow chain instead
        (theme.css .edged), which follows the clipped silhouette
        exactly and sits outside the element.

     2. `outline` is painted BY the element, so a clip-path clips
        it away and a chevron button gets no focus ring at all.
        Focus on every clipped control here is drawn by swapping
        --edge in that same drop-shadow chain, plus an inset
        highlight. Unclipped controls (sliders, switches) use a
        real outline, which is fine because nothing clips them.
   ─────────────────────────────────────────────────────────── */

.settings{
  /* local tokens — nothing here overrides a theme token */
  --s-label:#a9c7dd;         /* 10.0:1 on the row face   */
  --s-row:#0b1734;
  --s-row-hi:#122349;
  --s-rose:#ff8fbc;          /* 5.8:1 — the readable magenta */
  --s-cut:12px;
  grid-template-rows:auto minmax(0,1fr) auto;
  font-size:calc(16px * var(--op-ui-scale,1));
}

/* the arena keeps rendering behind this, so hold it down hard
   enough that 12px body text still reads over it */
.settings::before{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    /* The .70 band at 74% was authored to "let the arena read through
       the lower third". On a phone the lower third is where the SETTING
       ROWS are — the body scrolls, so the whole list passes through that
       window — and 30% of a live, moving attract match under 12px body
       copy is what "menus showing other menus behind them" means.
       Raised to .90; the arena is still visible, it just stopped
       competing with the text. Composite alpha, measured. */
    linear-gradient(180deg, rgba(4,7,18,.96) 0%, rgba(4,7,18,.94) 44%,
                    rgba(4,7,18,.90) 74%, rgba(4,7,18,.93) 100%),
    radial-gradient(ellipse 70% 60% at 50% 34%, rgba(20,40,86,.5), rgba(4,7,18,0) 70%);
  /* NO backdrop-filter here. pause.css can afford one because the
     simulation is frozen behind it; these two screens sit over a LIVE
     attract match, so a full-screen blur would be re-evaluated against
     a 4K WebGL backdrop every frame for a difference the dim gradient
     above already hides. The 60fps floor is not worth it. */
}

/* ── head ─────────────────────────────────────────────────── */

/* wrap, like .lb-head and .bd-head already do. BACK + crumb + the LIVE
   chip measure 559px flat, which is wider than every phone in the
   matrix; unwrapped they set the screen's min-content width and pushed
   the chip clean off the right edge. */
.set-head{
  display:flex; align-items:center; gap:16px 12px; flex-wrap:wrap;
  padding:14px 22px 6px; min-width:0;
  zoom:var(--op-ui-scale,1);
}
.set-crumb{
  margin:0; display:flex; align-items:baseline; gap:9px;
  font:900 clamp(20px,2.5vw,34px)/1 var(--display); text-transform:uppercase;
  letter-spacing:.02em;
  -webkit-text-stroke:5px var(--outline); paint-order:stroke fill;
  filter:drop-shadow(0 4px 0 rgba(3,6,16,.6));
  color:var(--ink);
}
.set-crumb i{ color:var(--ink-faint); font-style:normal; -webkit-text-stroke-width:4px; }
.set-crumb b{ color:var(--hot); }

.set-livechip{ gap:7px; letter-spacing:.14em; font-size:11px; color:var(--ink); }
.set-livechip svg{ flex:none; }

/* ── body ─────────────────────────────────────────────────── */

.set-body{
  display:grid;
  grid-template-columns:minmax(190px,15vw) minmax(0,1fr) minmax(268px,23vw);
  /* AND THE ROW HAS TO BE BOUNDED TOO. Without this the single
     implicit row is `auto`, which floors at the tallest column's
     min-content — so at 844x390 (a phone in landscape, and any short
     laptop) the row grew to the full height of the GRAPHICS list,
     .set-mid's `max-height:100%` resolved against that overflowing row
     instead of the window, .set-list never scrolled, and FULL SCREEN
     sat 210px below a <body> that clips: unreachable at any scroll
     position. Same class of bug as the .screen note in theme.css, one
     level further in. Reset to `auto` in the one-column block below,
     where .set-body is itself the scroller. */
  grid-template-rows:minmax(0,1fr);
  /* start, not stretch: no section has twelve rows, and a panel sized
     for twelve with five in it reads as a screen that failed to load.
     The space under the panels is not wasted — the arena is still
     rendering down there, and ::before below deliberately thins out
     over the lower third so it reads through, the same trick
     .menu::before uses to keep the game visible behind the shell. */
  gap:18px; padding:6px 22px 4px; min-height:0; align-items:start;
  /* UI SCALE: zoom actually resizes everything, where a font-size on
     the wrapper would not — nearly every rule below is authored in px.
     max-height has to be divided back out or the columns overflow. */
  zoom:var(--op-ui-scale,1);
  max-height:calc(100% / var(--op-ui-scale,1));
}

/* ── the category rail ───────────────────────────────────── */

/* stretch + min-height:0 + its own scroller, for the same reason as
   .set-mid below: five 52px categories are 296px, and a 390px-tall
   window only has 255px of body. Start-aligned and unscrollable, the
   rail simply grew down through the DONE / RESET footer. */
.set-rail{ display:flex; flex-direction:column; gap:9px; min-width:0;
  align-self:stretch; min-height:0; overflow-y:auto; overflow-x:hidden;
  /* the active category slides 4px right (.set-nav.on), and a
     scroll container clips on BOTH axes whatever you ask for — so it
     gets 6px of room, taken straight back with a negative margin so
     no other column moves. */
  padding-right:6px; margin-right:-6px; }
.set-nav{
  position:relative; display:flex; align-items:center; gap:11px;
  padding:12px 14px; border:0; cursor:pointer; width:100%; text-align:left;
  background:linear-gradient(180deg,#1b3364,#101f42);
  color:var(--ink); font:800 14px/1 var(--display); letter-spacing:.06em;
  text-transform:uppercase; text-shadow:0 2px 0 rgba(0,0,0,.5);
  clip-path:polygon(10px 0,100% 0,100% calc(100% - 10px),calc(100% - 10px) 100%,0 100%,0 10px);
  --edge:var(--outline); --lift:0 4px 0 rgba(3,6,16,.55);
  filter:
    drop-shadow(2px 0 0 var(--edge))  drop-shadow(-2px 0 0 var(--edge))
    drop-shadow(0 2px 0 var(--edge))  drop-shadow(0 -2px 0 var(--edge))
    drop-shadow(var(--lift));
  transition:transform .13s cubic-bezier(.3,1.5,.5,1), background .13s;
}
.set-nav:hover{ transform:translateX(4px); background:linear-gradient(180deg,#25478a,#152c5c); }
.set-nav-ico{
  width:30px; height:30px; flex:none; display:grid; place-items:center;
  background:linear-gradient(180deg,#2b4d8f,#16305f); border-radius:7px;
  box-shadow:inset 0 0 0 2px rgba(0,0,0,.45); color:var(--aqua);
}
.set-nav-txt{ min-width:0; overflow:hidden; text-overflow:ellipsis; }

/* the active item: hot face, gold edge, and the reference's jagged
   shard on the trailing edge. The shard is cut into the element's own
   clip-path, so the drop-shadow outline chain follows it exactly —
   which a separate pseudo-element could never do. */
.set-nav.on{
  background:linear-gradient(180deg,#ff5d9f,#c8206a);
  color:#fff; text-shadow:0 2px 0 rgba(0,0,0,.45);
  --edge:var(--gold);
  clip-path:polygon(10px 0, calc(100% - 26px) 0, calc(100% - 12px) 16%,
                    100% 26%, calc(100% - 16px) 48%, calc(100% - 4px) 66%,
                    calc(100% - 22px) 88%, calc(100% - 10px) 100%,
                    10px 100%, 0 calc(100% - 10px), 0 10px);
  transform:translateX(4px);
}
.set-nav.on .set-nav-ico{
  background:linear-gradient(180deg,#7d0e3f,#4d0525); color:#ffe08a;
}

/* ── the middle column ───────────────────────────────────── */

/* `align-self:stretch` is what makes the `max-height:100%` on .set-list
   below mean anything. A percentage max-height resolves against the
   parent's DEFINITE height, and a start-aligned grid item's height is
   `auto` — so .set-list's cap computed to `none`, it took its content
   height (551px against a 255px body at 844x390), and FULL SCREEN ended
   up under the fold with nothing able to scroll to it. Stretched, this
   box is exactly the grid row, the cap resolves, and the list scrolls.
   `align-items:flex-start` INSIDE is untouched on purpose: that is what
   keeps a five-row section from stretching into a twelve-row panel,
   which is the look the original comment is protecting. */
.set-mid{ display:flex; align-items:flex-start; min-width:0; min-height:0;
  align-self:stretch; max-height:100%; }
.set-list{
  flex:1; display:flex; flex-direction:column; max-height:100%;
  min-width:0; min-height:0; overflow-y:auto; overflow-x:hidden;
  padding:0 16px 16px; --cut:var(--s-cut);
  scrollbar-width:thin; scrollbar-color:#2c4a86 transparent;
}
.set-list::-webkit-scrollbar{ width:9px; }
.set-list::-webkit-scrollbar-thumb{ background:#2c4a86; border-radius:99px; }
.set-list .panel-head{
  position:sticky; top:0; z-index:3;
  margin:0 -16px 12px; padding:10px 18px; font-size:13px;
}

/* ── a settings row ──────────────────────────────────────── */

.set-row{
  display:flex; align-items:center; gap:13px; margin-bottom:7px;
  padding:12px 14px; background:var(--s-row);
  clip-path:polygon(8px 0,100% 0,100% calc(100% - 8px),calc(100% - 8px) 100%,0 100%,0 8px);
  box-shadow:inset 0 0 0 2px rgba(120,170,220,.14);
}
.set-row:hover{ background:var(--s-row-hi); }
.set-row-ico{
  width:34px; height:34px; flex:none; display:grid; place-items:center;
  background:linear-gradient(180deg,#22417c,#132a55); border-radius:8px;
  box-shadow:inset 0 0 0 2px rgba(0,0,0,.45);
  color:var(--aqua);
}
.set-row-txt{ flex:1; min-width:0; }
.set-row-txt b{
  display:block; font:800 13.5px/1.25 var(--ui); letter-spacing:.05em;
  text-transform:uppercase; color:var(--ink);
}
.set-row-txt small{
  display:block; margin-top:3px; font:600 12px/1.4 var(--ui);
  color:var(--s-label); letter-spacing:.01em;
}
.set-row-ctl{
  flex:none; display:flex; align-items:center; gap:9px; flex-wrap:wrap;
  justify-content:flex-end;
}

/* ── OFF | ON switch ─────────────────────────────────────────
   The reference draws a two-cell segmented control, not an iOS
   pill, and it is the better shape here: both states are labelled
   in text, so the meaning does not rest on a knob position. */
.set-sw{
  position:relative; flex:none; display:flex; align-items:stretch;
  width:126px; height:34px; padding:3px; border:0; cursor:pointer;
  background:#08122c; border-radius:9px;
  box-shadow:inset 0 0 0 2.5px var(--outline), 0 3px 0 rgba(0,0,0,.5);
}
.set-sw-cell{
  position:relative; z-index:2; flex:1; display:grid; place-items:center;
  font:900 11.5px/1 var(--ui); letter-spacing:.12em;
  color:var(--s-label); transition:color .14s;
}
.set-sw-knob{
  position:absolute; z-index:1; top:3px; left:3px; bottom:3px; width:calc(50% - 3px);
  border-radius:6px; background:linear-gradient(180deg,#93b2d6,#55749f);
  box-shadow:0 0 0 2px var(--outline);
  transition:transform .16s cubic-bezier(.3,1.5,.5,1), background .14s;
}
.set-sw[aria-checked="false"] .set-sw-cell:first-child{ color:#08122c; }
/* The switch is OFF-cell, ON-cell, knob — so :last-child matched the KNOB
   and never a label, leaving the ON text at 1.36:1 against the lit track
   whenever the switch was actually on. Adjacent-sibling picks the second
   cell by structure rather than by counting. */
.set-sw[aria-checked="true"] .set-sw-cell + .set-sw-cell{ color:#05221f; }
.set-sw[aria-checked="true"] .set-sw-knob{
  transform:translateX(100%);
  background:linear-gradient(180deg,var(--aqua-hi),var(--aqua-lo));
}

/* ── slider ──────────────────────────────────────────────────
   The gold fill is a gradient stop driven by --f, which the module
   rewrites on every input event. A native range gives no way to
   paint the "done" half of the track otherwise, and a hand-built
   div slider would lose the keyboard support that comes free. */
.set-rngwrap{ display:flex; align-items:center; gap:10px; }
.set-rng{
  flex:none; width:clamp(110px,13vw,168px); height:24px;
  -webkit-appearance:none; appearance:none; background:transparent; cursor:pointer;
}
.set-rng::-webkit-slider-runnable-track{
  height:13px; border-radius:99px;
  background:linear-gradient(90deg,var(--gold) 0 calc(var(--f,50) * 1%),
                             #0a1430 calc(var(--f,50) * 1%) 100%);
  box-shadow:inset 0 0 0 2.5px var(--outline);
}
.set-rng::-moz-range-track{
  height:13px; border-radius:99px;
  background:linear-gradient(90deg,var(--gold) 0 calc(var(--f,50) * 1%),
                             #0a1430 calc(var(--f,50) * 1%) 100%);
  box-shadow:inset 0 0 0 2.5px var(--outline);
}
/* the thumb is the octopus from icons.js, not a bare circle — the
   reference puts the mascot on the fader and it is the cheapest bit
   of charm on the screen */
.set-rng::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none; width:26px; height:26px; margin-top:-6.5px;
  border-radius:50%; border:0;
  background:var(--thumb) center/17px no-repeat,
             linear-gradient(180deg,var(--gold-hi),var(--gold-lo));
  box-shadow:0 0 0 2.5px var(--outline), 0 2px 0 rgba(0,0,0,.45);
}
.set-rng::-moz-range-thumb{
  width:26px; height:26px; border:0; border-radius:50%;
  background:var(--thumb) center/17px no-repeat,
             linear-gradient(180deg,var(--gold-hi),var(--gold-lo));
  box-shadow:0 0 0 2.5px var(--outline), 0 2px 0 rgba(0,0,0,.45);
}
.set-val{
  flex:none; min-width:48px; text-align:right;
  font:900 15px/1 var(--display); color:var(--gold);
  text-shadow:0 2px 0 rgba(0,0,0,.5);
}
/* --ink-faint (#5f83a4) measures 4.44:1 on the row face and misses AA
   by a hair, which at 10.5px is exactly where it matters most.
   --s-label is the same family at 10.0:1. */
.set-note{
  flex:none; width:100%; text-align:right;
  font:700 10.5px/1 var(--ui); letter-spacing:.1em; color:var(--s-label);
}
.set-sub{ font:700 10.5px/1 var(--ui); letter-spacing:.1em; color:var(--s-label); }

/* ── ‹ VALUE › stepper ───────────────────────────────────── */

.set-step{ display:flex; align-items:center; gap:7px; flex-wrap:wrap; justify-content:flex-end; }
.set-nudge{
  width:28px; height:30px; flex:none; border:0; cursor:pointer; padding:0;
  display:grid; place-items:center; border-radius:6px;
  background:linear-gradient(180deg,#25478a,#152c5c); color:var(--aqua);
  box-shadow:0 0 0 2px var(--outline), 0 3px 0 rgba(0,0,0,.5);
  transition:transform .12s;
}
.set-nudge:hover{ transform:translateY(-2px); color:var(--gold); }
/* at the end of the range, not broken — the stepper clamps rather
   than wrapping, and a disabled arrow says which end you are on */
.set-nudge[disabled]{ opacity:.34; cursor:default; }
.set-nudge[disabled]:hover{ transform:none; color:var(--aqua); }
.set-stepval{
  min-width:104px; padding:8px 12px; text-align:center;
  background:linear-gradient(180deg,var(--gold),var(--gold-lo)); color:#2a1500;
  font:900 12.5px/1 var(--ui); letter-spacing:.1em;
  clip-path:polygon(7px 0,100% 0,calc(100% - 7px) 100%,0 100%);
  box-shadow:0 0 0 2px var(--outline);
}
.set-dots{ display:flex; gap:5px; width:100%; justify-content:center; }
.set-dots i{ width:6px; height:6px; border-radius:99px; background:#2b4270;
             box-shadow:0 0 0 1.5px var(--outline); }
.set-dots i.on{ background:var(--hot); }

.set-seg{ display:flex; gap:6px; flex:none; }
.set-seg .pill{ min-width:40px; padding:9px 12px; font-size:12.5px; }

/* the chevron glyph, mirrored — used for the "previous" stepper arrow */
.settings .flip{ transform:scaleX(-1); }

/* ── notes, warnings, leads ──────────────────────────────── */

.set-lead{
  margin:0 0 12px; font:600 13px/1.55 var(--ui); color:var(--ink);
}
.set-lead b{ color:var(--aqua); }
.set-foot-note{
  margin:14px 0 2px; padding:11px 13px; background:rgba(8,18,44,.7);
  border-left:4px solid var(--aqua-lo);
  font:600 12px/1.6 var(--ui); color:var(--s-label);
}
.set-foot-note b{ color:var(--ink); }
.set-warn{
  display:flex; align-items:flex-start; gap:9px; margin:0 0 12px;
  padding:11px 13px; background:rgba(84,52,4,.5);
  border-left:4px solid var(--gold);
  font:700 12px/1.55 var(--ui); color:#ffe3ac;
}
.set-warn svg{ flex:none; margin-top:1px; }

/* ── controls page ───────────────────────────────────────── */

.set-binds{ display:flex; flex-direction:column; gap:7px; }
.set-bind{
  display:flex; align-items:center; gap:13px; padding:10px 13px;
  background:var(--s-row);
  clip-path:polygon(8px 0,100% 0,100% calc(100% - 8px),calc(100% - 8px) 100%,0 100%,0 8px);
  box-shadow:inset 0 0 0 2px rgba(120,170,220,.14);
}
.set-keys{ flex:none; display:flex; gap:5px; min-width:118px; }
.set-kbd{
  display:grid; place-items:center; min-width:36px; height:32px; padding:0 9px;
  background:linear-gradient(180deg,#e9f4ff,#a9c2da); color:#0a1430;
  font:900 12px/1 var(--ui); letter-spacing:.06em; border-radius:6px;
  box-shadow:0 0 0 2.5px var(--outline), 0 3px 0 rgba(0,0,0,.55);
}
.set-kbd.aqua{ background:linear-gradient(180deg,var(--aqua-hi),var(--aqua)); color:#05221f; }
.set-kbd.gold{ background:linear-gradient(180deg,var(--gold-hi),var(--gold)); color:#2a1500; }
.set-kbd.rose{ background:linear-gradient(180deg,#ffb0d0,var(--hot)); color:#3d0018; }
.set-bind-txt b{ display:block; font:800 13px/1.3 var(--ui); letter-spacing:.03em; color:var(--ink); }
.set-bind-txt small{ display:block; margin-top:3px; font:600 11.5px/1.45 var(--ui); color:var(--s-label); }

/* ── about page ──────────────────────────────────────────── */

.set-kv{
  display:grid; grid-template-columns:auto 1fr; gap:8px 18px; margin:0 0 14px;
}
.set-kv dt{ font:800 11px/1.5 var(--ui); letter-spacing:.14em; text-transform:uppercase;
            color:var(--s-label); }
.set-kv dd{ margin:0; font:800 13px/1.5 var(--ui); color:var(--ink); word-break:break-word; }
.set-aboutbtns{ display:flex; gap:10px; flex-wrap:wrap; }

/* ── the seat-glyph strip on the accessibility page ──────── */

.set-glyphstrip{
  display:flex; flex-wrap:wrap; gap:7px; margin-top:12px;
  padding:11px; background:rgba(8,18,44,.7);
}
.set-seat{
  display:flex; align-items:center; gap:6px; padding:6px 10px 6px 7px;
  background:#0a1430; border-radius:6px;
  box-shadow:inset 0 0 0 2px var(--outline);
}
.set-seat i{
  font-style:normal; font-size:15px; line-height:1; color:var(--c);
  text-shadow:0 0 0 var(--outline);
  /* the glyph channel is only visible when the switch is on — that is
     the whole point of the option, so the strip demonstrates it */
  display:none;
}
html.op-a11y-glyphs .set-seat i{ display:inline; }
.set-seat b{ font:800 10px/1 var(--ui); letter-spacing:.1em; color:var(--c); }
.set-seat::before{
  content:""; width:12px; height:12px; border-radius:3px; background:var(--c);
  box-shadow:0 0 0 2px var(--outline);
}

/* ── the preview panel ───────────────────────────────────── */

.set-side{
  display:flex; flex-direction:column; gap:12px; min-width:0; min-height:0;
  max-height:100%;
  overflow-y:auto; --cut:var(--s-cut); padding:0 16px 16px;
  scrollbar-width:thin; scrollbar-color:#2c4a86 transparent;
}
.set-side::-webkit-scrollbar{ width:9px; }
.set-side::-webkit-scrollbar-thumb{ background:#2c4a86; border-radius:99px; }
.set-side .panel-head{ margin:0 -16px 0; padding:10px 18px; font-size:13px; }
.set-arena{
  width:100%; height:auto; max-height:min(300px,34vh); display:block;
  background:radial-gradient(ellipse at 50% 45%,#0d2244,#050a18 72%);
  box-shadow:inset 0 0 0 3px var(--outline);
}
.set-ball{ transform-origin:100px 96px; animation:setOrbit 7s linear infinite; }
.set-ball.still{ animation:none; }
@keyframes setOrbit{ to{ transform:rotate(360deg); } }

.set-side-note{
  margin:0; font:600 12px/1.6 var(--ui); color:var(--s-label);
}
.set-side-note b{ color:var(--ink); }
.set-side-note b.warn{ color:var(--s-rose); }

.set-meters{ display:flex; flex-direction:column; gap:9px; }
.set-meters[data-muted]{ opacity:.45; }
.set-meter{ display:grid; grid-template-columns:64px 1fr 44px; align-items:center; gap:9px; }
.set-meter span:first-child{ font:800 10px/1 var(--ui); letter-spacing:.12em; color:var(--s-label); }
.set-meter b{ font:900 12px/1 var(--display); color:var(--gold); text-align:right; }
.set-meter .meter{ height:12px; }

/* ── foot ─────────────────────────────────────────────────── */

.set-foot{
  display:flex; flex-direction:column; align-items:center; gap:6px;
  padding:8px 22px 16px; zoom:var(--op-ui-scale,1);
}
.set-say{
  margin:0; min-height:17px; text-align:center;
  font:800 12px/1.4 var(--ui); letter-spacing:.1em; text-transform:uppercase;
  color:var(--gold);
}
.set-foot-btns{ display:flex; gap:14px; align-items:center; flex-wrap:wrap; justify-content:center; }
.set-foot-btns .btn{ padding:12px 26px 12px 18px; font-size:15px; }

/* theme.css has .btn.play (gold) and .btn.danger (rose) but no plain
   gold or confirm-green slab. Scoped so no other screen shifts. */
.settings .btn.gold{
  background:linear-gradient(180deg,var(--gold-hi),var(--gold),var(--gold-lo));
  color:#2a1500; text-shadow:0 1px 0 rgba(255,255,255,.35);
}
.settings .btn.gold:hover{ background:linear-gradient(180deg,#fff0b8,var(--gold-hi),var(--gold)); }
.settings .btn.ok{
  background:linear-gradient(180deg,var(--aqua-hi),var(--aqua),var(--aqua-lo));
  color:#05221f; text-shadow:0 1px 0 rgba(255,255,255,.3);
}
.settings .btn.ok:hover{ background:linear-gradient(180deg,#b6fbf3,var(--aqua-hi),var(--aqua)); }
.settings .btn.small{ padding:9px 18px 9px 12px; font-size:12.5px; }
.settings .set-fullscreen{
  min-width:182px; justify-content:center;
}
.settings .set-fullscreen[aria-pressed="true"]{
  --edge:var(--gold);
  background:linear-gradient(180deg,#294d92,#162d61);
  box-shadow:inset 0 0 0 2px rgba(255,198,61,.5);
}
.settings .btn[disabled]{ opacity:.5; cursor:not-allowed; }
.settings .btn[disabled]:hover{ transform:none; }
.settings .btn.back{ padding:9px 16px; font-size:13px;
  clip-path:polygon(16px 0,100% 0,100% 100%,16px 100%,0 50%); }
.settings .btn.back svg{ transform:scaleX(-1); }

/* ── focus ────────────────────────────────────────────────
   Clipped controls cannot show an `outline` (trap 2 at the top), so
   they get a brighter --edge in the drop-shadow chain plus an inset
   ring. Unclipped ones get a real outline. :focus, not
   :focus-visible: Chrome leaves focus-visible false when focus moves
   by keyboard after a click, which hides the current item. */
.settings .btn:focus,
.settings .pill:focus,
.set-nav:focus,
.set-stepval:focus{
  outline:none; --edge:var(--aqua);
  box-shadow:inset 0 0 0 2.5px rgba(47,230,214,.9);
}
.set-nav.on:focus{ --edge:#fff3c4; }
.set-row:focus-within{ box-shadow:inset 0 0 0 2px rgba(47,230,214,.55); }
.set-sw:focus,
.set-nudge:focus,
.set-rng:focus{
  outline:3px solid var(--aqua); outline-offset:3px;
}
.set-rng:focus::-webkit-slider-thumb{ box-shadow:0 0 0 2.5px var(--aqua), 0 2px 0 rgba(0,0,0,.45); }

/* ── the FPS readout ──────────────────────────────────────
   On <body>, not inside a screen, because it has to survive every
   screen change. Corner-pinned and click-through. */
#opFps{
  position:fixed; right:10px; bottom:10px; z-index:60; pointer-events:none;
  padding:5px 10px; background:rgba(4,7,18,.85);
  font:800 11px/1 var(--ui,system-ui); letter-spacing:.08em; color:var(--lime,#9dff4d);
  box-shadow:0 0 0 2px var(--outline,#04060f);
  clip-path:polygon(7px 0,100% 0,calc(100% - 7px) 100%,0 100%);
}

/* ── narrow / short ──────────────────────────────────────── */

@media (max-width:1180px){
  .set-body{ grid-template-columns:minmax(170px,20vw) minmax(0,1fr); }
  .set-side{ display:none; }
}
@media (max-width:820px){
  /* the body IS the scroller here, so the row goes back to `auto` —
     the rail and the list stack and the whole column scrolls as one */
  .set-body{ grid-template-columns:1fr; grid-template-rows:auto;
             overflow-y:auto; max-height:none; }
  .set-rail{ flex-direction:row; flex-wrap:wrap; }
  .set-nav{ width:auto; flex:1 1 140px; }
  .set-row{ flex-wrap:wrap; }
  .set-row-ctl{ width:100%; justify-content:flex-start; }
}
/* PHONE. Everything is reachable above this line; this block is about
   how much of the screen is left for the SETTINGS once the chrome has
   had its share. At 360x740 the head took 131px, the five-item rail
   243px and the foot 196px — 74% of the window — and the list you came
   for showed a single row. Trimming the parts that are not the content
   gets that back without hiding anything. */
@media (max-width:560px){
  .set-head{ padding:10px 14px 2px; gap:8px 10px; }
  .set-crumb{ font-size:clamp(19px,6.4vw,26px); -webkit-text-stroke-width:4px; }
  .set-body{ padding:4px 14px; gap:12px; }
  /* three across instead of two, and shorter */
  .set-nav{ flex:1 1 98px; padding:9px 10px; gap:8px; font-size:12px; }
  .set-nav-ico{ width:24px; height:24px; }
  .set-nav-ico svg{ width:16px; height:16px; }
  .set-rail{ gap:7px; }
  .set-foot{ padding:6px 14px 12px; }
  .set-foot-btns{ gap:8px; }
  .set-foot-btns .btn{ padding:10px 15px 10px 11px; font-size:13px; }
}
@media (max-height:720px){
  .set-head{ padding:8px 22px 2px; }
  .set-row{ padding:7px 12px; }
  .set-foot-btns .btn{ padding:9px 20px 9px 14px; font-size:13.5px; }
}

/* ════════════════════════════════════════════════════════════
   GLOBAL ACCESSIBILITY
   Keyed off classes this screen writes onto <html>. They are here,
   rather than scoped to .settings, because the switches that set
   them promise to change the whole shell — a "reduce motion" option
   that only quietened its own settings page would be a lie.

   pause.css and results.css already honour op-a11y-* inside their
   own screens; these rules cover everything else in #ui and are
   written so they cannot fight those (same intent, wider scope).
   ══════════════════════════════════════════════════════════ */

/* REDUCE MOTION — and it has to be genuine. Transitions, keyframes,
   the hover lifts, and the screen cross-fade all stop. */
html.op-a11y-still #ui *,
html.op-a11y-still #ui *::before,
html.op-a11y-still #ui *::after,
html.op-a11y-still #opFps{
  transition:none !important;
  animation:none !important;
  scroll-behavior:auto !important;
}
html.op-a11y-still #ui .btn:hover,
html.op-a11y-still #ui .tile:hover,
html.op-a11y-still #ui .pill:hover,
html.op-a11y-still #ui .modecard:hover,
html.op-a11y-still #ui .iconbtn:hover,
html.op-a11y-still #ui .set-nav:hover,
html.op-a11y-still #ui .set-nudge:hover{ transform:none !important; }
html.op-a11y-still #ui .screen{ transition:none !important; }

@media (prefers-reduced-motion:reduce){
  #ui *,#ui *::before,#ui *::after{ transition:none !important; animation:none !important; }
  #ui .btn:hover,#ui .tile:hover,#ui .pill:hover,#ui .modecard:hover{ transform:none !important; }
}

/* COLOURBLIND SEAT GLYPHS — the second identity channel. Any screen
   that emits a .seat-glyph gets it for free. */
html.op-a11y-glyphs .seat-glyph{ display:inline; }

/* HIGH CONTRAST — flatten the panels, brighten the ink and the
   outlines. These are the theme's own tokens, redefined at higher
   specificity than :root so they reach every screen at once. */
html.op-a11y-contrast{
  --ink:#ffffff;
  --ink-dim:#e2f4ff;      /* 15.6:1 on the panel face */
  --ink-faint:#b9d8ec;
  --panel:#0a1836; --panel-hi:#122349; --panel-lo:#040a1c;
  --outline:#000000;
  --stroke:4px;
}
html.op-a11y-contrast #ui .panel{ background:linear-gradient(180deg,#0f1f42,#050d22); }
html.op-a11y-contrast #ui .btn::after,
html.op-a11y-contrast #ui .tile::after{ display:none; }
html.op-a11y-contrast .settings{ --s-label:#e2f4ff; --s-row:#050d22; --s-row-hi:#0e1c3e; }
html.op-a11y-contrast .settings::before{
  background:rgba(2,4,10,.97); backdrop-filter:none;
}
html.op-a11y-contrast #ui .set-row,
html.op-a11y-contrast #ui .set-bind{ box-shadow:inset 0 0 0 2px rgba(190,225,250,.45); }

/* ── touch targets ── see theme.css. Before: the category rail 42px,
   the ± nudges 28x30, the OFF/ON switch 34px and the slider track
   24px. The slider grows its TRACK, not its thumb — the thumb is
   already 26px and centring it in a 44px row is what makes the
   control catchable without changing how it looks. */
@media (pointer:coarse){
  .settings .set-nav{ min-height:44px; }
  .settings .set-nudge{ width:44px; height:44px; }
  .settings .set-sw{ min-height:44px; }
  .settings .set-rng{ height:44px; }
}
