/* ── OCTOPONG · character select ─────────────────────────────
   select.js appends a second copy of this sheet at the end of
   <head> — after theme.css AND ui.css — so every rule here wins a
   specificity tie against both. See the TRAP 3 note at the top of
   theme.css for why that matters.

   The screen borrows the shell's TEXT controls verbatim: `.btn`,
   `.btn.back` and `.btn.play` are theme.css's, so BACK and the gold
   hero CTA are literally the same objects the menu and mode select
   use. Everything else is `sel-` parts of its own, because a chip
   whose whole face is delivered artwork has nothing in common with
   a chevron slab.

   THREE RULES INHERITED FROM THE REST OF THE SHELL
   ────────────────────────────────────────────────
   1. NEVER outline a clipped or filtered box with a z-index:-1
      pseudo-element. Both clip-path and filter open a stacking
      context, and a negative-z child of one paints ABOVE its
      parent's background — it floods the face. Chained zero-blur
      drop-shadows outline the clipped silhouette instead.
   2. `outline` is painted BY the element, so clip-path clips it
      away and a clipped control gets NO focus ring from it. Clipped
      things here take focus by swapping --sel-edge inside that same
      drop-shadow chain, plus an inset highlight. Unclipped things
      (the colour swatches) use a real outline, which is safe.
   3. The background is a real element (`.sel-bg`), not a
      z-index:-1 pseudo, for exactly reason 1 — and because this
      screen sets `isolation:isolate`, under which a negative-z
      pseudo lands somewhere different at rest than it does
      mid-transition.
   ─────────────────────────────────────────────────────────── */

.sel{
  isolation:isolate;
  grid-template-rows:auto minmax(0,1fr) auto;
  overflow:hidden;

  --sel-ink:#f4fbff;
  /* MEASURED against the panel plate's LIGHT end (#172a52), which is
     the worst backdrop either of them ever gets:
       --sel-dim   #c6dded  10.0:1   body copy, blurbs, the one-liner
       --sel-faint #9fc0d8   7.4:1   small caps labels and eyebrows
     Both clear AA for small text with room to spare. Do not reach
     for --ink-faint here: it is tuned for the modes scrim, which is
     darker than this plate. */
  --sel-dim:#c6dded;
  --sel-faint:#9fc0d8;
  --sel-edge:var(--outline,#050814);
  --sel-gold:var(--gold,#ffc63d);
  --sel-aqua:var(--aqua-hi,#7ff5ea);

  --sel-plate:linear-gradient(180deg,#172a52,#0b1839);
  --sel-cut:12px;
  --sel-pad:clamp(10px,1.4vw,22px);
  --sel-gap:clamp(8px,1.1vw,16px);

  /* the current character's measured identity colour; select.js
     rewrites it on every change so the whole screen re-tints at
     once instead of one component at a time */
  --sel-tint:#f5488f;
}

/* the outline chain, once. Every clipped plate on this screen calls
   it with its own --sel-edge and --sel-lift. */
.sel-edged{
  --sel-lift:0 4px 0 rgba(3,6,16,.55);
  filter:
    drop-shadow(2px 0 0 var(--sel-edge))  drop-shadow(-2px 0 0 var(--sel-edge))
    drop-shadow(0 2px 0 var(--sel-edge))  drop-shadow(0 -2px 0 var(--sel-edge))
    drop-shadow(var(--sel-lift));
}

/* ══ background ═════════════════════════════════════════════
   The live attract match is still rendering behind this layer, and
   it should read as depth rather than as noise under a grid of
   sixteen bright chips. Same scrim family as the menu and mode
   select — edges down hard, centre left open — plus a wash of the
   current character's colour from the left, so choosing somebody
   changes the ROOM and not just the portrait. */
.sel-bg{ position:absolute; inset:0; z-index:0; pointer-events:none; overflow:hidden; }
.sel-scrim{
  position:absolute; inset:0;
  background:
    /* the open centre band was .58 x .66 — a composite .857, i.e. 14%
       of a live attract match reading up through the character grid,
       which is the busiest thing on the screen already. .74 x .80
       composites to .948 and the arena is still legibly back there. */
    linear-gradient(90deg, rgba(5,8,20,.96) 0%, rgba(5,8,20,.86) 22%,
                    rgba(5,8,20,.74) 44%, rgba(5,8,20,.74) 58%,
                    rgba(5,8,20,.88) 80%, rgba(5,8,20,.97) 100%),
    linear-gradient(180deg, rgba(5,8,20,.95) 0%, rgba(5,8,20,.80) 24%,
                    rgba(5,8,20,.80) 68%, rgba(5,8,20,.97) 100%);
}
.sel-wash{
  position:absolute; inset:0;
  background:
    radial-gradient(ellipse 46% 62% at 14% 54%, var(--sel-tint), transparent 68%),
    radial-gradient(ellipse 40% 50% at 88% 78%, var(--sel-tint), transparent 72%);
  opacity:.13;
  transition:opacity var(--dur-slow,.3s) var(--ease-out,ease),
             background var(--dur-slow,.3s) var(--ease-out,ease);
}
/* everything above the background */
.sel-top, .sel-body, .sel-foot{ position:relative; z-index:1; min-width:0; }

/* ══ header ═════════════════════════════════════════════════ */
.sel-top{
  display:flex; align-items:center; gap:var(--sel-gap);
  padding:clamp(8px,1.4vh,16px) var(--sel-pad) clamp(4px,.8vh,10px);
}
.sel-title{ flex:1; min-width:0; text-align:center; }
.sel-title h2{
  margin:0; font:900 clamp(20px,3.4vh,40px)/1 var(--display,sans-serif);
  text-transform:uppercase; letter-spacing:.01em;
  -webkit-text-stroke:var(--stroke-lg,5px) var(--sel-edge); paint-order:stroke fill;
  filter:drop-shadow(0 5px 0 rgba(3,6,16,.6));
  white-space:nowrap;
}
.sel-title h2 .a{ color:var(--sel-aqua); }
.sel-title h2 .b{ color:var(--sel-gold); }
.sel-title p{
  margin:clamp(1px,.5vh,6px) 0 0;
  font:700 clamp(10px,1.4vh,12.5px)/1.3 var(--ui,sans-serif);
  letter-spacing:.14em; text-transform:uppercase; color:var(--sel-faint);
}
/* BACK and RANDOM are the same width so the title stays optically
   centred instead of drifting with the longer label */
.sel-top .btn{ flex:none; min-width:clamp(96px,10vw,132px); }

/* ══ body ═══════════════════════════════════════════════════ */
.sel-body{
  display:grid;
  grid-template-columns:minmax(250px,23vw) minmax(0,1fr) minmax(230px,20vw);
  gap:var(--sel-gap);
  padding:0 var(--sel-pad) clamp(4px,.8vh,10px);
  align-items:stretch; min-height:0;
}

/* ── the plate every column sits on ───────────────────────── */
.sel-panel{
  position:relative; min-width:0; min-height:0;
  display:flex; flex-direction:column;
  padding:clamp(9px,1.2vh,15px) clamp(10px,.9vw,16px) clamp(10px,1.3vh,16px);
  background:var(--sel-plate);
  clip-path:polygon(var(--sel-cut) 0,100% 0,100% calc(100% - var(--sel-cut)),
                    calc(100% - var(--sel-cut)) 100%,0 100%,0 var(--sel-cut));
  --sel-lift:0 6px 0 rgba(3,6,16,.55);
  filter:
    drop-shadow(2px 0 0 var(--sel-edge))  drop-shadow(-2px 0 0 var(--sel-edge))
    drop-shadow(0 2px 0 var(--sel-edge))  drop-shadow(0 -2px 0 var(--sel-edge))
    drop-shadow(var(--sel-lift)) drop-shadow(0 14px 24px rgba(0,0,0,.5));
}
.sel-h{
  margin:0 0 clamp(6px,.9vh,11px); flex:none;
  font:800 clamp(9.5px,1.3vh,12px)/1 var(--display,sans-serif);
  letter-spacing:.16em; text-transform:uppercase; color:var(--sel-aqua);
}

/* ══ LEFT — the hero card ═══════════════════════════════════ */
.sel-hero{ gap:0; }

/* The portrait sits IN the card rather than on it: a tinted pool of
   light behind it and an elliptical contact shadow under it, so the
   octopus is lit by the plate instead of pasted onto it. */
.sel-stage{
  position:relative; flex:1 1 auto; min-height:0;
  display:grid; place-items:center;
  margin-bottom:clamp(4px,.7vh,9px);
}
.sel-stage::before{
  content:""; position:absolute; left:50%; top:46%;
  width:106%; aspect-ratio:1; transform:translate(-50%,-50%);
  background:radial-gradient(circle at 50% 50%, var(--sel-tint), transparent 62%);
  opacity:.30; pointer-events:none;
  transition:background var(--dur-slow,.3s) var(--ease-out,ease);
}
.sel-stage::after{
  content:""; position:absolute; left:50%; bottom:2%;
  width:64%; height:9%; transform:translateX(-50%);
  background:radial-gradient(ellipse at 50% 50%, rgba(3,6,16,.72), transparent 70%);
  pointer-events:none;
}
.sel-portrait{
  position:relative; display:block;
  max-width:100%; max-height:100%; width:auto; height:auto;
  object-fit:contain;
  filter:drop-shadow(0 10px 16px rgba(3,6,16,.6));
  animation:sel-bob 5.2s cubic-bezier(.45,0,.55,1) infinite;
}
/* a fresh pick lands rather than cross-fades — the reference sheets
   all stage the portrait as an arrival */
.sel-portrait.sel-pop{ animation:sel-bob 5.2s cubic-bezier(.45,0,.55,1) infinite,
                                 sel-land .34s cubic-bezier(.3,1.5,.5,1) 1; }
@keyframes sel-bob{
  0%,100%{ transform:translateY(0) rotate(-.5deg); }
  50%    { transform:translateY(-2.2%) rotate(.5deg); }
}
@keyframes sel-land{
  0%  { opacity:0; transform:translateY(9%) scale(.9); }
  100%{ opacity:1; transform:none; }
}

/* Every one of the ten reference sheets stamps the hero card with a
   SELECTED tag. It is not decoration: the grid, the colour row and
   the arena rail all show a selected state, and without this the
   biggest thing on the screen is the only one that does not say
   whether it is a preview or the choice. */
.sel-badge{
  position:absolute; right:0; top:0; z-index:2;
  display:flex; align-items:center; gap:5px; padding:4px 9px;
  background:linear-gradient(180deg,var(--gold-hi,#ffe08a),var(--gold,#ffc63d));
  color:#2a1500; font:900 clamp(8.5px,1.1vh,10px)/1 var(--ui,sans-serif);
  letter-spacing:.14em; text-transform:uppercase;
  clip-path:polygon(6px 0,100% 0,100% 100%,0 100%,0 6px);
  box-shadow:0 0 0 2px var(--sel-edge),0 3px 0 rgba(3,6,16,.5);
}
.sel-badge svg{ width:11px; height:11px; display:block; }

.sel-look{
  flex:none; display:block;
  font:800 clamp(8.5px,1.15vh,10.5px)/1 var(--ui,sans-serif);
  letter-spacing:.17em; text-transform:uppercase; color:var(--sel-faint);
}
.sel-name{
  flex:none; margin:clamp(2px,.5vh,6px) 0 clamp(4px,.7vh,9px);
  font:900 clamp(21px,3.5vh,40px)/.95 var(--display,sans-serif);
  letter-spacing:-.005em; color:var(--sel-tint);
  -webkit-text-stroke:var(--stroke-md,3px) var(--sel-edge); paint-order:stroke fill;
  text-shadow:0 3px 0 rgba(3,6,16,.5);
  transition:color var(--dur-mid,.2s) var(--ease-out,ease);
}
.sel-desc{
  flex:none; margin:0 0 clamp(7px,1.1vh,13px);
  font:600 clamp(11px,1.45vh,13px)/1.5 var(--ui,sans-serif);
  color:var(--sel-dim);
}

/* ── colour, and why it is here ───────────────────────────────
   Colour and character are independent choices — every reference
   sheet puts the swatch row under the portrait for the same reason:
   it is YOUR colour, so it belongs beside your face, not filed away
   in a settings rail. The row is a real radiogroup; arrow keys move
   and select, which is what a radiogroup is supposed to do. */
.sel-crow{ flex:none; }
.sel-crow .sel-h{ display:flex; align-items:baseline; gap:7px; margin-bottom:6px; }
.sel-cname{ color:var(--sel-ink); letter-spacing:.1em; }
.sel-swatches{
  display:grid; grid-template-columns:repeat(8,minmax(0,1fr));
  gap:clamp(4px,.5vw,8px);
}
.sel-sw{
  position:relative; border:0; cursor:pointer; padding:0;
  aspect-ratio:1; border-radius:6px;
  background:var(--seat);
  box-shadow:0 0 0 2px var(--sel-edge), 0 3px 0 rgba(3,6,16,.5),
             inset 0 3px 0 rgba(255,255,255,.32);
  transition:transform var(--dur-fast,.12s) var(--ease-pop,ease),
             box-shadow var(--dur-fast,.12s);
}
.sel-sw:hover{ transform:translateY(var(--lift-y,-3px)); }
/* nothing here is clipped, so a real outline is safe and is the
   clearest ring the platform has */
.sel-sw:focus{ outline:3px solid var(--sel-aqua); outline-offset:3px; }
.sel-sw.on{
  box-shadow:0 0 0 2px var(--sel-edge), 0 0 0 5px #fff8de,
             0 0 0 7px var(--sel-edge), 0 3px 0 rgba(3,6,16,.5),
             inset 0 3px 0 rgba(255,255,255,.32);
  transform:translateY(var(--lift-y,-3px));
}
.sel-sw.on::after{
  content:""; position:absolute; inset:0; margin:auto;
  width:42%; height:26%; border:0 solid #0b1226;
  border-left-width:3.5px; border-bottom-width:3.5px;
  transform:rotate(-45deg) translate(6%,-24%);
}

/* ══ CENTRE — the roster ════════════════════════════════════ */
.sel-roster{ min-height:0; }
/* The grid is shorter than its column on a tall window, and mode
   select already learned what that looks like: content packed at the
   top of a full-height panel reads as a web form, not a stage. It
   centres — and `safe` so centring can never push the first row out
   of reach once the grid outgrows the panel and has to scroll. */
.sel-gridwrap{
  flex:1 1 auto; min-height:0; overflow:auto; padding:2px 2px 4px;
  display:flex; flex-direction:column; justify-content:center;
  justify-content:safe center;
}
/* ── the chip size is handed down from the HEIGHT ─────────────
   Four columns of whatever the centre column happens to be wide is
   how the fourth row ended up cut in half at 1350x900: the grid was
   sized by width alone and the panel is sized by height.

   menu.css solved the same problem for the button stack by making
   the fold the input. Here the lever is the grid's max-width: a
   chip is square plus a ~22px name plate, so four rows cost about
   4 x (w + 27) and w is a quarter of this box. Capping the box at
   60vh puts four rows at roughly 74vh, inside the ~80vh the roster
   panel gets, at every height — and on a wide, short window the
   100% term binds instead and the cap does nothing. `margin:auto`
   then centres whichever one won. */
.sel-grid{
  display:grid; grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(6px,.8vw,13px); flex:none;
  width:100%; max-width:min(100%, 60vh); margin:0 auto;
}

.sel-chip{
  position:relative; border:0; padding:0; cursor:pointer; color:var(--sel-ink);
  display:flex; flex-direction:column; align-items:stretch;
  background:linear-gradient(180deg,#1d3465,#0d1b3d);
  clip-path:polygon(9px 0,calc(100% - 9px) 0,100% 9px,100% calc(100% - 9px),
                    calc(100% - 9px) 100%,9px 100%,0 calc(100% - 9px),0 9px);
  --sel-lift:0 4px 0 rgba(3,6,16,.55);
  filter:
    drop-shadow(2px 0 0 var(--sel-edge))  drop-shadow(-2px 0 0 var(--sel-edge))
    drop-shadow(0 2px 0 var(--sel-edge))  drop-shadow(0 -2px 0 var(--sel-edge))
    drop-shadow(var(--sel-lift));
  transition:transform var(--dur-fast,.12s) var(--ease-pop,ease),
             background var(--dur-fast,.12s), filter var(--dur-fast,.12s);
}
/* the chip's own pool of light, in ITS character's colour, so the
   grid reads as sixteen lit portraits rather than sixteen stickers */
.sel-chip::before{
  content:""; position:absolute; left:0; right:0; top:0; height:74%;
  background:radial-gradient(ellipse 62% 62% at 50% 46%, var(--chip), transparent 70%);
  opacity:.20; pointer-events:none;
  transition:opacity var(--dur-fast,.12s);
}
.sel-chip img{
  position:relative; display:block; width:100%; height:auto;
  aspect-ratio:1; object-fit:contain;
  padding:clamp(3px,.4vw,7px) clamp(3px,.4vw,7px) 0;
  filter:drop-shadow(0 3px 4px rgba(3,6,16,.55));
}
.sel-chip b{
  position:relative; display:block;
  padding:0 3px clamp(5px,.7vh,8px);
  font:800 clamp(8px,1.05vh,10.5px)/1.1 var(--ui,sans-serif);
  letter-spacing:.08em; text-align:center; color:var(--sel-dim);
  text-shadow:0 2px 0 rgba(3,6,16,.6);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.sel-chip:hover{ transform:translateY(var(--lift-y,-3px));
                 background:linear-gradient(180deg,#274a91,#152c5c); }
.sel-chip:hover::before{ opacity:.34; }

/* ── ONE "this one is picked" language ────────────────────────
   The same one mode select settled on: the rim goes to full weight
   in the accent colour, a wash lifts the face, the cut corner gets
   sealed, and the whole thing sits forward. The accent here is the
   CHARACTER's measured tint rather than gold, because sixteen chips
   all carrying gold rims would fight the one gold thing on the
   screen — the CONFIRM button. */
.sel-chip.on{
  --sel-edge:var(--chip);
  background:
    linear-gradient(180deg,rgba(255,255,255,.14),rgba(255,255,255,0) 58%),
    linear-gradient(180deg,#27509b,#152c5c);
  transform:translateY(var(--lift-y,-3px));
  filter:
    drop-shadow(3px 0 0 var(--sel-edge))  drop-shadow(-3px 0 0 var(--sel-edge))
    drop-shadow(0 3px 0 var(--sel-edge))  drop-shadow(0 -3px 0 var(--sel-edge))
    drop-shadow(var(--sel-lift)) drop-shadow(0 0 18px var(--chip));
}
.sel-chip.on::before{ opacity:.42; }
.sel-chip.on b{ color:var(--sel-ink); }
.sel-chip.on:hover{ transform:translateY(calc(var(--lift-y,-3px) * 1.6)); }
/* the sealed corner — the chip's version of a filled pill */
.sel-chip.on .sel-tick{
  position:absolute; right:0; bottom:0; width:26px; height:26px;
  background:linear-gradient(135deg,transparent 49%,var(--chip) 50%);
  pointer-events:none;
}
.sel-chip .sel-tick{ display:none; }
.sel-chip.on .sel-tick{ display:block; }

/* clip-path eats `outline`, so the ring is drawn with the same
   chain that draws the edge (theme.css, "the outline") */
.sel-chip:focus{
  outline:none; --sel-edge:var(--sel-aqua);
  box-shadow:inset 0 0 0 2px rgba(127,245,234,.9);
}
.sel-chip.on:focus{ box-shadow:inset 0 0 0 2px rgba(127,245,234,.9); }

/* ══ RIGHT — the arena rail ═════════════════════════════════ */
.sel-rail{ min-height:0; }
.sel-arenas{ flex:1 1 auto; min-height:0; overflow:auto; display:flex;
             flex-direction:column; gap:clamp(5px,.8vh,10px); padding:2px;
             justify-content:center; justify-content:safe center; }
.sel-ar{
  position:relative; flex:none; border:0; padding:0; cursor:pointer;
  display:grid; grid-template-columns:clamp(74px,7vw,112px) minmax(0,1fr);
  align-items:center; gap:9px; text-align:left; color:var(--sel-ink);
  background:linear-gradient(180deg,#1d3465,#0d1b3d);
  clip-path:polygon(8px 0,100% 0,100% calc(100% - 8px),
                    calc(100% - 8px) 100%,0 100%,0 8px);
  --sel-lift:0 3px 0 rgba(3,6,16,.55);
  filter:
    drop-shadow(2px 0 0 var(--sel-edge))  drop-shadow(-2px 0 0 var(--sel-edge))
    drop-shadow(0 2px 0 var(--sel-edge))  drop-shadow(0 -2px 0 var(--sel-edge))
    drop-shadow(var(--sel-lift));
  transition:transform var(--dur-fast,.12s) var(--ease-pop,ease),
             background var(--dur-fast,.12s), filter var(--dur-fast,.12s);
}
/* Three layers, bottom to top: the arena's own `swatch` gradient,
   the generated octagon stage, and the delivered still. The still
   stays at opacity 0 until it has decoded and removes itself on
   error, so the four 404ing thumbnail paths that ship today show the
   fallback rather than a broken-image glyph. */
.sel-ar-plate{
  position:relative; display:block; width:100%; aspect-ratio:16/10;
  overflow:hidden;
  background:linear-gradient(155deg, var(--a1,#08122c), var(--a2,#12244a) 58%, var(--a3,#1f7f8f));
  box-shadow:inset 0 0 0 2px rgba(3,6,16,.8);
}
.sel-ar-plate svg{ position:relative; display:block; width:100%; height:100%; }
.sel-ar-shot{
  position:absolute; inset:0; display:block; width:100%; height:100%;
  object-fit:cover; opacity:0;
  transition:opacity var(--dur-mid,.2s) var(--ease-out,ease);
}
.sel-ar-shot.ok{ opacity:1; }
.sel-ar-txt{ min-width:0; padding:clamp(6px,.9vh,10px) 10px clamp(6px,.9vh,10px) 0; }
/* ── the arena name cannot be the raw tint ────────────────────
   MEASURED against the selected row's lightest gradient stop
   (#27509b): CORAL COLOSSEUM 4.95, GILDED SANCTUM 4.95, THE GEODE
   1.83, MAELSTROM RIG 2.49. Two of the four failed badly, and this
   is a ~14px heading — not big enough to claim the large-text 3:1,
   so it needs 4.5. The tints come from palette.js via arenas.js and
   are not mine to move, so the LIFT HAPPENS HERE: each name is its
   arena's colour blended toward the ink until it clears, which
   keeps the four rows telling themselves apart by hue while making
   all four readable. The flat colour above it is the fallback for
   an engine without color-mix. */
.sel-ar-txt b{
  display:block; font:900 clamp(11px,1.5vh,14px)/1.05 var(--display,sans-serif);
  letter-spacing:.03em;
  color:#dcebff;
  color:color-mix(in srgb, var(--ar-tint,#7ff5ea) 38%, #f4fbff);
  /* NOT var(--sel-edge): .sel-ar.on rebinds that to the arena tint so
     the ROW gets a coloured rim, and the name was inheriting it as a
     coloured halo — the selected arena's text looked highlighted while
     every other name sat flat. The rim belongs to the row. */
  -webkit-text-stroke:2px var(--outline,#050814); paint-order:stroke fill;
}
.sel-ar-txt span{
  display:block; margin-top:3px;
  font:600 clamp(9.5px,1.2vh,11.5px)/1.35 var(--ui,sans-serif);
  color:var(--sel-dim);
}
.sel-ar:hover{ transform:translateY(var(--lift-y,-3px));
               background:linear-gradient(180deg,#274a91,#152c5c); }
.sel-ar.on{
  --sel-edge:var(--ar-tint,var(--sel-aqua));
  background:
    linear-gradient(180deg,rgba(255,255,255,.13),rgba(255,255,255,0) 60%),
    linear-gradient(180deg,#27509b,#152c5c);
  filter:
    drop-shadow(3px 0 0 var(--sel-edge))  drop-shadow(-3px 0 0 var(--sel-edge))
    drop-shadow(0 3px 0 var(--sel-edge))  drop-shadow(0 -3px 0 var(--sel-edge))
    drop-shadow(var(--sel-lift)) drop-shadow(0 0 16px var(--ar-tint,#7ff5ea));
}
.sel-ar:focus{ outline:none; --sel-edge:var(--sel-aqua);
               box-shadow:inset 0 0 0 2px rgba(127,245,234,.9); }
.sel-ar[disabled]{ cursor:not-allowed; filter:none; opacity:.42; }
.sel-ar[disabled]:hover{ transform:none; }
.sel-lockrow{
  position:absolute; right:8px; top:8px; display:flex; align-items:center;
  gap:4px; padding:3px 6px; background:rgba(5,8,20,.82);
  border-radius:4px; font:800 8.5px/1 var(--ui,sans-serif);
  letter-spacing:.12em; color:var(--sel-faint);
}
.sel-lockrow svg{ width:11px; height:11px; display:block; }

/* the one-arena state. Honest rather than padded out with three
   greyed-out "COMING SOON" slots that nothing can deliver yet. */
.sel-solo{
  flex:none; margin:clamp(6px,1vh,11px) 0 0;
  font:600 clamp(9.5px,1.2vh,11.5px)/1.45 var(--ui,sans-serif);
  color:var(--sel-faint);
}

/* ══ footer ═════════════════════════════════════════════════ */
.sel-foot{
  display:flex; align-items:center; justify-content:space-between;
  gap:var(--sel-gap); padding:clamp(5px,.9vh,12px) var(--sel-pad) clamp(8px,1.4vh,18px);
  background:linear-gradient(180deg,rgba(5,8,20,0),rgba(5,8,20,.80) 55%,rgba(5,8,20,.93));
}
.sel-keys{
  display:flex; flex-wrap:wrap; align-items:center; gap:clamp(8px,1.2vw,20px);
  font:700 clamp(9px,1.15vh,11px)/1 var(--ui,sans-serif);
  letter-spacing:.11em; text-transform:uppercase; color:var(--sel-faint);
  min-width:0;
}
.sel-keys b{ color:var(--sel-dim); }
.sel-keys kbd{
  display:inline-block; min-width:19px; padding:3px 5px; margin-right:5px;
  background:#1d3465; color:#eaf6ff; border-radius:4px;
  font:800 9.5px/1 var(--ui,sans-serif); letter-spacing:.04em;
  box-shadow:0 0 0 2px var(--sel-edge),0 2px 0 rgba(3,6,16,.6);
}
/* the summary of what CONFIRM is about to do — the screen makes
   three choices and the button has to be able to say so */
.sel-sum{
  display:flex; align-items:center; gap:clamp(6px,.9vw,14px); flex:none;
  font:800 clamp(9.5px,1.2vh,11.5px)/1 var(--ui,sans-serif);
  letter-spacing:.1em; text-transform:uppercase; color:var(--sel-faint);
}
.sel-sum b{ color:var(--sel-dim); }
.sel-sum i{ width:13px; height:13px; border-radius:3px; background:var(--seat);
            box-shadow:0 0 0 2px var(--sel-edge); display:inline-block;
            vertical-align:-2px; margin-right:5px; }
.sel-foot .btn.play{ flex:none; font-size:clamp(17px,2.6vh,30px);
                     padding:clamp(10px,1.5vh,18px) clamp(20px,2vw,32px)
                             clamp(10px,1.5vh,18px) clamp(14px,1.4vw,22px); }

/* a screen-reader-only running commentary on what changed */
.sel-live{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* ══ TALL — 1350x1270 and any portrait desktop ══════════════
   THE ROW LAYOUT IS THE ONLY ONE. A stacked "big banner" variant
   (plate full width, name underneath) was built here first because
   it matches the reference sheets, and it was WRONG: four stacked
   banners are ~875px tall, so at 950px of window the fourth card
   was cut off behind a scrollbar and at 1270 it fit — a picker
   whose last option disappears at some window heights and not
   others. The row scales instead: the plate column grows with the
   viewport height, which fills a tall rail without ever changing
   how many cards are reachable. */
@media (min-height:1000px) and (min-width:1181px){
  /* The rail has to WIDEN before the card is allowed to grow. Growing
     the plate and the type on a 240px rail is what made CORAL
     COLOSSEUM break across two lines at 1350x1270 while it sat on one
     at 1350x560 — the same card, wrapping only on the taller window,
     which reads as a bug. Extra height buys extra width here because
     the roster grid is capped at 60vh anyway and does not want it. */
  .sel-body{ grid-template-columns:minmax(250px,22vw) minmax(0,1fr) minmax(260px,23vw); }
  .sel-ar{ grid-template-columns:clamp(86px,7.5vw,124px) minmax(0,1fr); gap:12px; }
  .sel-ar-txt b{ font-size:clamp(13px,1.35vh,16px); }
  .sel-ar-txt span{ font-size:clamp(10.5px,1.1vh,12.5px); }
}

/* ══ SHORT — 1400x560 and any laptop in half-height ═════════
   Two rows of eight rather than four of four: the grid is the
   thing that has to stay legible, and at 560px tall a 4x4 grid
   would put 28px chips on screen. */
/* ── 4-up or 8-up, and where the line is ──────────────────────
   MEASURED, not guessed. A chip is its own width plus a ~22px name
   plate, so on a 1350px window the centre column runs ~700px and
   four columns make 187px-tall chips: four rows plus gaps plus the
   heading is ~820px, and the roster panel has ~1100px at 1270 tall.
   It fits. At 900 tall the same panel has ~730px and the fourth row
   was CUT MID-CHIP at the scroll edge — the exact complaint mode
   select's footer ramp was written for. So the switch to two rows
   of eight happens at 1040px of height, not at the 760 this
   originally guessed, and eight 87px cells is also the size the
   reference sheets' own bottom grids use. */
/* Below ~700px of height four rows cannot be worth looking at
   whatever the cap does, so the grid goes two rows of eight —
   which is also the shape the reference sheets' own bottom grids
   use. The cap goes up with it: eight columns at 150vh is the
   width term binding again, i.e. no cap in practice. */
@media (min-width:1000px) and (max-height:700px){
  /* no height cap in the 8-up case: two rows cannot overflow even a
     560px window, so the column width is allowed to set the chip
     size and the chips get as big as the room allows */
  .sel-grid{ grid-template-columns:repeat(8,minmax(0,1fr)); max-width:100%; }
  .sel-title p{ display:none; }
}
/* THE CAST IS two rows of eight on any WIDE screen, not only a short
   one. The rule above fires at max-height:700px, so a normal
   1920x1080 browser - the common case - still laid out four rows of
   four. The ask was 4x4 on mobile and 2x8 on a browser or any
   16:9-ish ratio, which is an ASPECT question rather than a height
   one. Portrait and narrow keep the 4x4 the base rule gives them. */
@media (min-width:820px) and (min-aspect-ratio:5/4){
  .sel-grid{ grid-template-columns:repeat(8,minmax(0,1fr)); max-width:100%; }
}

@media (max-height:620px){
  .sel-title h2{ font-size:clamp(18px,3.2vh,26px); -webkit-text-stroke-width:4px; }
  .sel-portrait{ animation:none; }        /* nothing to bob into */
  .sel-keys{ display:none; }              /* the footer belongs to CONFIRM */
}

/* ══ NARROW ═════════════════════════════════════════════════
   The rail folds under the roster first — arena is the smallest of
   the three choices and the only one with a default worth keeping. */
@media (max-width:1180px){
  .sel-body{ grid-template-columns:minmax(210px,30%) minmax(0,1fr); }
  .sel-rail{ grid-column:1 / -1; }
  .sel-arenas{ flex-direction:row; overflow-x:auto; }
  .sel-ar{ flex:0 0 clamp(210px,26vw,280px); }
}

/* ══ MOBILE — 375x812 ═══════════════════════════════════════
   One column, and the body scrolls. `.screen` is inset-locked so
   its grid rows can never grow past the viewport; the scroll has to
   live on the BODY row, the same pattern .modes-body and .menu-body
   already use. The hero goes horizontal — a portrait tall enough to
   read would push the grid off the fold otherwise. */
@media (max-width:760px){
  .sel-body{
    grid-template-columns:minmax(0,1fr); grid-auto-rows:min-content;
    overflow-y:auto; gap:10px; padding-bottom:14px;
  }
  .sel-rail{ grid-column:auto; }
  .sel-hero{ display:grid; grid-template-columns:minmax(0,116px) minmax(0,1fr);
             grid-template-rows:auto; gap:0 12px; align-items:center; }
  .sel-stage{ grid-row:1 / span 5; align-self:center; height:130px; margin:0; }
  .sel-look, .sel-name, .sel-desc{ grid-column:2; }
  .sel-crow{ grid-column:1 / -1; margin-top:9px; }
  .sel-name{ font-size:26px; }
  .sel-desc{ font-size:12px; margin-bottom:0; }
  .sel-gridwrap{ overflow:visible; }
  .sel-arenas{ flex-direction:column; overflow:visible; }
  .sel-ar{ flex:none; }
  .sel-top{ flex-wrap:wrap; }
  .sel-title{ order:-1; flex-basis:100%; }
  .sel-top .btn{ flex:1; }
  .sel-foot{ flex-direction:column; align-items:stretch; gap:8px; }
  .sel-foot .btn.play{ width:100%; justify-content:center; font-size:20px; }
  .sel-keys{ display:none; }
  .sel-sum{ justify-content:center; }
}

/* ══ reduced motion / accessibility modes ═══════════════════ */
@media (prefers-reduced-motion:reduce){
  .sel-portrait{ animation:none; }
  .sel-chip, .sel-ar, .sel-sw, .sel-wash, .sel-name{ transition:none; }
  .sel-chip:hover, .sel-ar:hover, .sel-sw:hover{ transform:none; }
}
html.op-a11y-still .sel-portrait{ animation:none; }
html.op-a11y-still .sel *{ transition:none !important; }
html.op-a11y-still .sel :is(.sel-chip,.sel-ar,.sel-sw):hover{ transform:none; }
/* high contrast: the scrim becomes a plate and the dim ramp goes up */
html.op-a11y-contrast .sel .sel-scrim{
  background:
    linear-gradient(90deg, rgba(2,4,12,.97) 0%, rgba(2,4,12,.94) 34%, rgba(2,4,12,.88) 50%,
                           rgba(2,4,12,.94) 66%, rgba(2,4,12,.97) 100%),
    linear-gradient(180deg, rgba(2,4,12,.96), rgba(2,4,12,.9));
}
html.op-a11y-contrast .sel{ --sel-dim:#eaf6ff; --sel-faint:#d3e6f5; }
html.op-a11y-contrast .sel .sel-wash{ opacity:.06; }

/* ── touch targets ── see theme.css. The colour hexes were 37px. */
@media (pointer:coarse){
  .sel .sel-sw{ width:44px; height:44px; }
}
