/* ===========================================================================
   cabinet.css — the display cabinet a shelf of kits stands in (cabinet.js),
   and its Appearance dialog (cabinet-settings.js).

   Built the way binder.css builds the binder: ONE LIGHT from the top left for
   every bevel and wash, materials made of layered gradients with the shared
   noise tile (`--grain`, backdrop.js applyGrain) blended `overlay` into them,
   no `backdrop-filter` anywhere, and only transform / opacity ever animate.

   HOW THE CABINET IS BUILT (cabinet.js renders it)

     .cab                         the object: a size container (`cab`), data-*
                                  for every Appearance choice
       .cab-case                  the carcass: padding = the frame's thickness
         .cab-piece.is-top/.is-bot  rails, horizontal grain (between the stiles)
         .cab-piece.is-l/.is-r      stiles, vertical grain, full height
         .cab-body                the interior: the back panel
           .cab-rows > .cab-row   one compartment per shelf (contain: layout paint)
             .cab-board           the shelf the row stands on: deck, lip, rail
             .cab-lamp            LED strip, downlight cones, pools on the deck
             .cab-track           the kits, side by side (scrolls sideways)
               .cab-item          one kit: .cab-kit (the button) + its plate
               .cab-add           "+" slot (Arrange) · .cab-gap (drop point)
           .cab-doors             glass doors over the opening (never hit-tested)
       .cab-plinth                the base the carcass stands on

   SIZE. The cabinet is its own container, so everything is sized in `cqi` of
   the cabinet and a mini cabinet in the Appearance dialog is the same object
   at a smaller size. A row is `--cab-h` tall for kits; a kit stands at `--k`
   of that (collectibles.js SIZE_HEIGHT: s .58, m .76, l .94), and its width
   follows its photo's own proportions (`--ar`), so nothing moves as it loads.

   The prefix is `.cab-*` throughout (`.shelf-art*` belongs to shell.css).
   =========================================================================== */

/* ================================================================ the object */
.cab {
  container: cab / inline-size;
  --cab-light: #ffcf8f;
  --cab-back-c: #1f2633;
  --cab-ink: #fff;                  /* what reads on the back panel */
  position: relative;
  isolation: isolate;
  width: 100%;
  max-width: 1100px;
  margin: 0 auto;
  padding-bottom: 26px;             /* room for the shadow on the floor */
  -webkit-tap-highlight-color: transparent;
  color: #fff;
}

/* Everything inside is sized against the cabinet. */
.cab-case {
  /* the frame */
  --cab-fw: clamp(8px, 1.6cqi, 18px);
  --cab-ft: calc(var(--cab-fw) * 1.2);
  --cab-fb: calc(var(--cab-fw) * 1.45);
  --cab-r: clamp(3px, .5cqi, 6px);
  /* a row: kit height, the head room its LED strip lives in, the shelf */
  --cab-h: clamp(150px, 20cqi, 236px);
  --cab-head: max(9px, calc(var(--cab-h) * .075));
  --cab-deck: max(7px, calc(var(--cab-h) * .062));
  --cab-df: calc(var(--cab-deck) * .5);         /* how far in front of a kit the deck runs */
  --cab-edge: max(3px, calc(var(--cab-h) * .022));
  --cab-pz: 32px;                               /* the label rail under the shelf */
  --cab-plate-h: 26px;
  --cab-plate-min: 88px;
  --cab-plate-max: 184px;
  --cab-gap: max(8px, calc(var(--cab-h) * .07));
  --cab-pad-x: max(12px, calc(var(--cab-h) * .1));
  --cab-spot: max(170px, calc(var(--cab-h) * 1.55));
  position: relative;
  z-index: 1;
  padding: var(--cab-ft) var(--cab-fw) var(--cab-fb);
  border-radius: var(--cab-r);
  background: var(--cab-mat-c, #3a2418);
  box-shadow:
    0 34px 60px -26px rgba(0,0,0,.7),
    0 14px 26px -12px rgba(0,0,0,.5),
    0 0 0 1px rgba(0,0,0,.35);
}
:root[data-theme="light"] .cab-case {
  box-shadow:
    0 30px 50px -24px rgba(20,24,32,.42),
    0 12px 22px -10px rgba(20,24,32,.26),
    0 0 0 1px rgba(20,24,32,.22);
}

/* The shadow the cabinet throws on the floor, under the plinth. */
.cab::after {
  content: ""; position: absolute; z-index: 0; pointer-events: none;
  left: 4%; right: 4%; bottom: 8px; height: 26px;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(0,0,0,.55), rgba(0,0,0,.18) 60%, rgba(0,0,0,0));
}
:root[data-theme="light"] .cab::after {
  background: radial-gradient(closest-side, rgba(20,24,32,.3), rgba(20,24,32,.08) 60%, rgba(0,0,0,0));
}

/* ============================================================== materials
   Each frame choice sets the same few custom properties — the material with
   its grain running along (`-h`) and up (`-v`), each with its layer sizes and
   blend modes — and every piece of the cabinet paints itself from them. The
   same holds for anything with `.cab-mat[data-frame]` (the swatches in the
   Appearance dialog; a shelf tile can use it too). */

/* ---- woods: walnut, oak, ebony. Colour, then a figure of long arcs (a flat-
   sawn board's cathedral grain), straight pores, a slow light-and-dark run
   along the board, the lacquer's gloss and the shared noise. */
.cab[data-frame="walnut"], .cab-mat[data-frame="walnut"] {
  --w-base: #5e3c27; --w-dark: #3b2517; --w-light: #7a4c30;
  --w-line: rgba(30,14,5,.36); --w-fleck: rgba(255,214,170,.075); --w-gloss: .15;
}
.cab[data-frame="oak"], .cab-mat[data-frame="oak"] {
  --w-base: #b3874f; --w-dark: #8e663a; --w-light: #c99d63;
  --w-line: rgba(96,60,24,.3); --w-fleck: rgba(255,244,214,.14); --w-gloss: .2;
}
.cab[data-frame="ebony"], .cab-mat[data-frame="ebony"] {
  --w-base: #241a15; --w-dark: #120c0a; --w-light: #36271f;
  --w-line: rgba(0,0,0,.5); --w-fleck: rgba(255,196,160,.06); --w-gloss: .3;
}
.cab:is([data-frame="walnut"], [data-frame="oak"], [data-frame="ebony"]),
.cab-mat:is([data-frame="walnut"], [data-frame="oak"], [data-frame="ebony"]) {
  --cab-mat-c: var(--w-base);
  --cab-mat-h:
    var(--grain, none),
    linear-gradient(180deg, rgba(255,255,255,var(--w-gloss)) 0, rgba(255,255,255,0) 46%, rgba(0,0,0,.16) 100%),
    repeating-radial-gradient(2600px 230px at 34% -150px,
      transparent 0 31px, var(--w-line) 33px 36px, transparent 38px 57px, var(--w-fleck) 58px 60px, transparent 61px 83px),
    repeating-linear-gradient(180deg,
      transparent 0 2px, var(--w-line) 2px 3px, transparent 3px 6px, var(--w-fleck) 6px 7px, transparent 7px 11px),
    linear-gradient(90deg, rgba(0,0,0,.1), rgba(0,0,0,0) 18%, rgba(255,255,255,.05) 41%, rgba(0,0,0,.07) 63%, rgba(0,0,0,0) 81%, rgba(0,0,0,.08)),
    linear-gradient(90deg, var(--w-dark), var(--w-base) 20%, var(--w-light) 50%, var(--w-base) 78%, var(--w-dark));
  --cab-mat-h-size: 96px 96px, auto, auto, auto, auto, auto;
  --cab-mat-v:
    var(--grain, none),
    linear-gradient(90deg, rgba(255,255,255,var(--w-gloss)) 0, rgba(255,255,255,0) 50%, rgba(0,0,0,.2) 100%),
    repeating-radial-gradient(230px 2600px at -150px 38%,
      transparent 0 31px, var(--w-line) 33px 36px, transparent 38px 57px, var(--w-fleck) 58px 60px, transparent 61px 83px),
    repeating-linear-gradient(90deg,
      transparent 0 2px, var(--w-line) 2px 3px, transparent 3px 6px, var(--w-fleck) 6px 7px, transparent 7px 11px),
    linear-gradient(180deg, rgba(0,0,0,.08), rgba(0,0,0,0) 22%, rgba(255,255,255,.05) 46%, rgba(0,0,0,.06) 70%, rgba(0,0,0,.1)),
    linear-gradient(180deg, var(--w-light), var(--w-base) 30%, var(--w-dark) 100%);
  --cab-mat-v-size: 96px 96px, auto, auto, auto, auto, auto;
  --cab-mat-blend: overlay, normal, normal, normal, normal, normal;
}

/* ---- white lacquer: near solid, a hard gloss along the top, a whisper of grain */
.cab[data-frame="white"], .cab-mat[data-frame="white"] {
  --cab-mat-c: #efede8;
  --cab-mat-h:
    var(--grain, none),
    linear-gradient(180deg, rgba(255,255,255,.95) 0 1px, rgba(255,255,255,.6) 1px, rgba(255,255,255,0) 48%, rgba(0,0,0,.06) 100%),
    linear-gradient(90deg, #e8e5df, #f6f4f0 40%, #f1efea 70%, #e4e1da);
  --cab-mat-h-size: 96px 96px, auto, auto;
  --cab-mat-v:
    var(--grain, none),
    linear-gradient(90deg, rgba(255,255,255,.9) 0 1px, rgba(255,255,255,.5) 1px, rgba(255,255,255,0) 55%, rgba(0,0,0,.08) 100%),
    linear-gradient(180deg, #faf9f6, #eceae5 55%, #dcd9d2);
  --cab-mat-v-size: 96px 96px, auto, auto;
  --cab-mat-blend: soft-light, normal, normal;
}

/* ---- metals: aluminium and gunmetal. Brushed — the noise stretched along the
   stroke and fine hairlines — with a specular stripe and a lit top edge. */
.cab[data-frame="aluminium"], .cab-mat[data-frame="aluminium"] {
  --m-hi: #eef1f4; --m-base: #c4c9cf; --m-lo: #959ca5;
  --m-line: rgba(255,255,255,.2); --m-dark: rgba(0,0,0,.06); --m-spec: .42;
}
.cab[data-frame="gunmetal"], .cab-mat[data-frame="gunmetal"] {
  --m-hi: #737a84; --m-base: #464c54; --m-lo: #2a2e34;
  --m-line: rgba(255,255,255,.07); --m-dark: rgba(0,0,0,.16); --m-spec: .2;
}
.cab:is([data-frame="aluminium"], [data-frame="gunmetal"]),
.cab-mat:is([data-frame="aluminium"], [data-frame="gunmetal"]) {
  --cab-mat-c: var(--m-base);
  --cab-mat-h:
    var(--grain, none),
    linear-gradient(180deg, rgba(255,255,255,.55) 0 1px, rgba(255,255,255,0) 1px),
    linear-gradient(180deg, rgba(255,255,255,0) 16%, rgba(255,255,255,var(--m-spec)) 34%, rgba(255,255,255,.05) 48%, rgba(255,255,255,0) 64%),
    repeating-linear-gradient(180deg, var(--m-line) 0 1px, var(--m-dark) 1px 2px, transparent 2px 4px),
    linear-gradient(180deg, var(--m-hi), var(--m-base) 42%, var(--m-lo));
  --cab-mat-h-size: 720px 40px, auto, auto, auto, auto;
  --cab-mat-v:
    var(--grain, none),
    linear-gradient(90deg, rgba(255,255,255,.5) 0 1px, rgba(255,255,255,0) 1px),
    linear-gradient(90deg, rgba(255,255,255,0) 14%, rgba(255,255,255,var(--m-spec)) 32%, rgba(255,255,255,.05) 46%, rgba(255,255,255,0) 62%),
    repeating-linear-gradient(90deg, var(--m-line) 0 1px, var(--m-dark) 1px 2px, transparent 2px 4px),
    linear-gradient(90deg, var(--m-hi), var(--m-base) 42%, var(--m-lo));
  --cab-mat-v-size: 40px 720px, auto, auto, auto, auto;
  --cab-mat-blend: overlay, normal, normal, normal, normal;
}

/* The wood a wooden shelf is cut from, and the metal of a metal one, follow the
   frame: its own wood, else oak under white or aluminium and walnut under
   gunmetal; brushed steel, else gunmetal's own darker metal. The nameplates
   are brass on the darker woods, silver on the pale frames, titanium on gunmetal. */
.cab[data-frame="walnut"] { --sw-base: #5e3c27; --sw-dark: #3b2517; --sw-light: #7a4c30; --sw-line: rgba(30,14,5,.36); --sw-fleck: rgba(255,214,170,.08); }
.cab:is([data-frame="oak"], [data-frame="white"], [data-frame="aluminium"]) {
  --sw-base: #b3874f; --sw-dark: #8e663a; --sw-light: #c99d63; --sw-line: rgba(96,60,24,.3); --sw-fleck: rgba(255,244,214,.14);
}
.cab[data-frame="ebony"] { --sw-base: #241a15; --sw-dark: #120c0a; --sw-light: #36271f; --sw-line: rgba(0,0,0,.5); --sw-fleck: rgba(255,196,160,.06); }
.cab[data-frame="gunmetal"] { --sw-base: #5a3a26; --sw-dark: #3a2418; --sw-light: #74492f; --sw-line: rgba(30,14,5,.36); --sw-fleck: rgba(255,214,170,.08); }

.cab { --sm-hi: #dfe3e8; --sm-base: #a4aab2; --sm-lo: #6a7179; --sm-line: rgba(255,255,255,.1); }
.cab:is([data-frame="gunmetal"], [data-frame="ebony"]) { --sm-hi: #7a818b; --sm-base: #4b5159; --sm-lo: #2a2e34; --sm-line: rgba(255,255,255,.06); }

.cab {
  --plate-hi: #fff5da; --plate-a: #f2d992; --plate-b: #cfa551; --plate-c: #a57b33;
  --plate-ink: #3a2807; --plate-ink-hi: rgba(255,244,214,.55);
}
.cab:is([data-frame="oak"], [data-frame="white"], [data-frame="aluminium"]) {
  --plate-hi: #ffffff; --plate-a: #f1f3f5; --plate-b: #c9ced4; --plate-c: #a3a9b1;
  --plate-ink: #22262d; --plate-ink-hi: rgba(255,255,255,.6);
}
.cab[data-frame="gunmetal"] {
  --plate-hi: #8b929c; --plate-a: #555c65; --plate-b: #393e45; --plate-c: #25292e;
  --plate-ink: #eef0f3; --plate-ink-hi: rgba(0,0,0,.55);
}

/* ================================================================== frame */
.cab-piece {
  position: absolute; z-index: 3; pointer-events: none;
  background-color: var(--cab-mat-c);
  background-blend-mode: var(--cab-mat-blend);
  /* bevel: lit top and left edges, shade along the bottom and right */
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.26),
    inset 1px 0 0 rgba(255,255,255,.1),
    inset 0 -1px 0 rgba(0,0,0,.42),
    inset -1px 0 0 rgba(0,0,0,.28);
}
.cab-piece.is-top, .cab-piece.is-bot {
  left: var(--cab-fw); right: var(--cab-fw);
  background-image: var(--cab-mat-h);
  background-size: var(--cab-mat-h-size);
}
.cab-piece.is-top { top: 0; height: var(--cab-ft); }
.cab-piece.is-bot { bottom: 0; height: var(--cab-fb); }
.cab-piece.is-l, .cab-piece.is-r {
  top: 0; bottom: 0; width: var(--cab-fw);
  background-image: var(--cab-mat-v);
  background-size: var(--cab-mat-v-size);
}
.cab-piece.is-l { left: 0; border-radius: var(--cab-r) 0 0 var(--cab-r); }
.cab-piece.is-r { right: 0; border-radius: 0 var(--cab-r) var(--cab-r) 0; }
/* the right-hand stile is further from the light */
.cab-piece.is-r::after, .cab-piece.is-bot::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: rgba(0,0,0,.12);
}
/* where each rail butts into a stile: a hairline joint */
.cab-piece.is-top::before, .cab-piece.is-bot::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: 0; right: 0;
  box-shadow: inset 1px 0 0 rgba(0,0,0,.4), inset -1px 0 0 rgba(0,0,0,.4);
}
/* the top of the carcass catches the light */
.cab-piece.is-top {
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.4),
    inset 0 -1px 0 rgba(0,0,0,.45),
    inset 0 -6px 8px -6px rgba(0,0,0,.35);
}

/* The base: a recessed plinth in the same material, in its own shadow. */
.cab-plinth {
  position: relative; z-index: 0;
  height: clamp(8px, 2.1cqi, 22px);
  margin: 0 clamp(8px, 2.6cqi, 30px);
  border-radius: 0 0 3px 3px;
  background-color: var(--cab-mat-c);
  /* in the carcass's shadow at the top, a little light along its lower edge */
  background-image: linear-gradient(180deg, rgba(0,0,0,.7), rgba(0,0,0,.32) 55%, rgba(0,0,0,.4)), var(--cab-mat-h);
  background-size: auto, var(--cab-mat-h-size);
  background-blend-mode: normal, var(--cab-mat-blend);
  box-shadow: inset 0 -1px 0 rgba(255,255,255,.12), 0 6px 10px -4px rgba(0,0,0,.6);
}
.cab:is([data-frame="aluminium"], [data-frame="gunmetal"]) .cab-plinth {
  margin: 0 clamp(12px, 3.4cqi, 38px);
  background-image: linear-gradient(180deg, rgba(0,0,0,.78), rgba(0,0,0,.5)), var(--cab-mat-h);
}
/* Metal frames are slimmer; lacquer and wood keep their board thickness. */
.cab:is([data-frame="aluminium"], [data-frame="gunmetal"]) .cab-case {
  --cab-fw: clamp(6px, 1.15cqi, 13px);
  --cab-ft: var(--cab-fw);
  --cab-fb: calc(var(--cab-fw) * 1.2);
}

/* ============================================================== interior
   The back panel, the side walls in perspective, and the depth where the
   frame shades the opening (over the kits: the frame is in front of them). */
.cab-body {
  position: relative; z-index: 1;
  overflow: hidden;
  border-radius: 2px;
  background-color: #0f1013;
}
.cab-body::before {       /* side walls and the ceiling, behind everything */
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background:
    linear-gradient(90deg, rgba(0,0,0,.5), rgba(0,0,0,.18) 1.8%, rgba(0,0,0,0) 4.5%),
    linear-gradient(270deg, rgba(0,0,0,.58), rgba(0,0,0,.22) 1.8%, rgba(0,0,0,0) 4.5%);
}
.cab-body::after {        /* the frame's own shade into the opening */
  content: ""; position: absolute; inset: 0; z-index: 5; pointer-events: none;
  box-shadow:
    inset 0 0 0 1px rgba(0,0,0,.55),
    inset 0 12px 14px -10px rgba(0,0,0,.75),
    inset 9px 0 12px -9px rgba(0,0,0,.55),
    inset -9px 0 12px -9px rgba(0,0,0,.65),
    inset 0 -6px 10px -6px rgba(0,0,0,.5);
}
/* An unlit cabinet is a little dimmer throughout. */
.cab[data-light="off"] .cab-body::after {
  background: rgba(0,0,0,.14);
}

/* ---- back panels */
.cab[data-back="dark"] .cab-body {
  background-image:
    var(--grain, none),
    radial-gradient(120% 55% at 30% 0, rgba(255,255,255,.05), rgba(255,255,255,0) 70%),
    linear-gradient(180deg, #17191e, #0d0e11);
  background-size: 96px 96px, auto, auto;
  background-blend-mode: overlay, normal, normal;
}
/* felt: a dense, fibrous slate cloth — two scales of the noise make the nap */
.cab[data-back="felt"] .cab-body {
  background-color: #2a2f39;
  background-image:
    var(--grain, none), var(--grain, none),
    radial-gradient(120% 55% at 30% 0, rgba(255,255,255,.06), rgba(255,255,255,0) 70%),
    linear-gradient(180deg, #313744, #20242d);
  background-size: 29px 29px, 96px 96px, auto, auto;
  background-blend-mode: overlay, overlay, normal, normal;
}
/* mirror: silvered glass — soft streaks and the room's light in it */
.cab[data-back="mirror"] .cab-body {
  background-image:
    linear-gradient(104deg, rgba(255,255,255,0) 18%, rgba(255,255,255,.08) 26%, rgba(255,255,255,.02) 31%, rgba(255,255,255,0) 36%,
      rgba(255,255,255,0) 58%, rgba(255,255,255,.06) 63%, rgba(255,255,255,0) 70%),
    radial-gradient(90% 40% at 50% 0, rgba(255,255,255,.14), rgba(255,255,255,0) 70%),
    linear-gradient(180deg, #6b727c, #41464e 38%, #2d3137 68%, #474c55);
}
.cab[data-back="light"] .cab-body {
  --cab-ink: #1d2230;
  background-image:
    var(--grain, none),
    radial-gradient(120% 55% at 30% 0, rgba(255,255,255,.4), rgba(255,255,255,0) 70%),
    linear-gradient(180deg, #efece6, #dcd8cf);
  background-size: 96px 96px, auto, auto;
  background-blend-mode: soft-light, normal, normal;
}
.cab[data-back="color"] .cab-body {
  background-color: var(--cab-back-c);
  background-image:
    var(--grain, none),
    radial-gradient(120% 55% at 30% 0, rgba(255,255,255,.1), rgba(255,255,255,0) 70%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--cab-back-c) 94%, #fff),
      var(--cab-back-c) 40%,
      color-mix(in srgb, var(--cab-back-c) 72%, #000));
  background-size: 96px 96px, auto, auto;
  background-blend-mode: overlay, normal, normal;
}
.cab[data-back="color"][data-back-tone="light"] .cab-body { --cab-ink: #1d2230; }
/* On a pale back the frame's shade reads lighter. */
.cab:is([data-back="light"], [data-back-tone="light"]) .cab-body::after {
  box-shadow:
    inset 0 0 0 1px rgba(0,0,0,.3),
    inset 0 12px 14px -10px rgba(0,0,0,.4),
    inset 9px 0 12px -9px rgba(0,0,0,.28),
    inset -9px 0 12px -9px rgba(0,0,0,.34),
    inset 0 -6px 10px -6px rgba(0,0,0,.25);
}

/* ================================================================== rows */
.cab-rows { position: relative; z-index: 1; display: flex; flex-direction: column; }

.cab-row {
  position: relative;
  height: calc(var(--cab-head) + var(--cab-h) + var(--cab-df) + var(--cab-edge) + var(--cab-pz));
  contain: layout paint;
  /* the shadow the shelf (or the carcass top) above throws on the back panel */
  background: linear-gradient(180deg, rgba(0,0,0,.34), rgba(0,0,0,.1) calc(var(--cab-head) * 1.2), rgba(0,0,0,0) calc(var(--cab-head) * 2.6));
}
.cab:is([data-back="light"], [data-back-tone="light"]) .cab-row {
  background: linear-gradient(180deg, rgba(0,0,0,.16), rgba(0,0,0,.04) calc(var(--cab-head) * 1.2), rgba(0,0,0,0) calc(var(--cab-head) * 2.6));
}

/* ---- the shelf a row stands on: the deck (its top, seen from a little above),
   the lip (its front edge) and the rail under it the nameplates are fixed to */
.cab-board {
  position: absolute; z-index: 0; left: 0; right: 0; bottom: 0;
  height: calc(var(--cab-deck) + var(--cab-edge) + var(--cab-pz));
  pointer-events: none;
}
.cab-deck, .cab-lip, .cab-rail { position: absolute; left: 0; right: 0; display: block; }
.cab-deck { top: 0; height: var(--cab-deck); }
.cab-lip { top: var(--cab-deck); height: var(--cab-edge); }
.cab-rail { bottom: 0; height: var(--cab-pz); }

/* glass: clear, a green-cyan front edge with a lit line along it */
.cab[data-shelf="glass"] .cab-deck {
  background:
    linear-gradient(180deg, rgba(255,255,255,.28) 0 1px, rgba(255,255,255,0) 1px),
    linear-gradient(180deg, rgba(200,236,224,.05), rgba(200,236,224,.16));
}
.cab[data-shelf="glass"] .cab-lip {
  background:
    linear-gradient(180deg, rgba(236,255,248,.9) 0 1px, rgba(150,214,192,.8) 1px, rgba(86,152,134,.82) 70%, rgba(52,98,86,.9));
  box-shadow: 0 1px 0 rgba(0,0,0,.35), 0 3px 6px -2px rgba(0,0,0,.45);
}
/* …under it, a slim channel of brushed dark aluminium holds the plates */
.cab[data-shelf="glass"] .cab-rail {
  top: calc(var(--cab-deck) + var(--cab-edge));
  background:
    linear-gradient(180deg, rgba(255,255,255,.22) 0 1px, rgba(255,255,255,0) 1px),
    repeating-linear-gradient(180deg, rgba(255,255,255,.035) 0 1px, rgba(0,0,0,.05) 1px 2px),
    linear-gradient(180deg, #3a3f46, #23272c 55%, #181a1e);
  box-shadow: inset 0 -1px 0 rgba(0,0,0,.6), 0 4px 8px -3px rgba(0,0,0,.55);
}
/* wood: a real board — lit along its front arris, darker toward the wall */
.cab[data-shelf="wood"] .cab-deck {
  background:
    linear-gradient(180deg, rgba(0,0,0,.4), rgba(0,0,0,.08) 70%, rgba(255,255,255,.08)),
    repeating-linear-gradient(180deg, transparent 0 2px, var(--sw-line) 2px 3px, transparent 3px 5px),
    linear-gradient(90deg, var(--sw-dark), var(--sw-base) 25%, var(--sw-light) 50%, var(--sw-base) 75%, var(--sw-dark));
}
.cab[data-shelf="wood"] .cab-lip,
.cab[data-shelf="wood"] .cab-rail {
  background-color: var(--sw-base);
  background-image:
    var(--grain, none),
    linear-gradient(180deg, rgba(255,255,255,.12), rgba(255,255,255,0) 40%, rgba(0,0,0,.2)),
    repeating-radial-gradient(2600px 230px at 40% -150px,
      transparent 0 31px, var(--sw-line) 33px 36px, transparent 38px 57px, var(--sw-fleck) 58px 60px, transparent 61px 83px),
    repeating-linear-gradient(180deg, transparent 0 2px, var(--sw-line) 2px 3px, transparent 3px 7px),
    linear-gradient(90deg, var(--sw-dark), var(--sw-base) 20%, var(--sw-light) 50%, var(--sw-base) 80%, var(--sw-dark));
  background-size: 96px 96px, auto, auto, auto, auto;
  background-blend-mode: overlay, normal, normal, normal, normal;
}
/* one board: the lip and the rail are its front face, lit edge on top */
.cab[data-shelf="wood"] .cab-case { --cab-edge: max(5px, calc(var(--cab-h) * .04)); }
.cab[data-shelf="wood"] .cab-lip { box-shadow: inset 0 1px 0 rgba(255,255,255,.3); }
.cab[data-shelf="wood"] .cab-rail {
  top: var(--cab-deck); height: auto; background-position: 0 calc(-1 * var(--cab-edge));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28), inset 0 -1px 0 rgba(0,0,0,.5), 0 5px 9px -3px rgba(0,0,0,.6);
}
.cab[data-shelf="wood"] .cab-lip { display: none; }
/* metal: a brushed plate folded down into a lip */
.cab[data-shelf="metal"] .cab-deck {
  background:
    linear-gradient(180deg, rgba(0,0,0,.42), rgba(0,0,0,.12) 70%, rgba(255,255,255,.14)),
    repeating-linear-gradient(90deg, var(--sm-line) 0 1px, rgba(0,0,0,.03) 1px 2px, rgba(0,0,0,0) 2px 5px),
    linear-gradient(180deg, var(--sm-lo), var(--sm-base));
}
.cab[data-shelf="metal"] .cab-lip,
.cab[data-shelf="metal"] .cab-rail {
  background:
    linear-gradient(180deg, rgba(255,255,255,.75) 0 1px, rgba(255,255,255,0) 1px),
    linear-gradient(180deg, rgba(255,255,255,0) 6%, rgba(255,255,255,.2) 22%, rgba(255,255,255,0) 44%),
    repeating-linear-gradient(180deg, var(--sm-line) 0 1px, rgba(0,0,0,.035) 1px 2px, rgba(0,0,0,0) 2px 3px),
    linear-gradient(180deg, var(--sm-hi), var(--sm-base) 30%, color-mix(in srgb, var(--sm-base) 72%, #000) 78%, var(--sm-lo));
}
.cab[data-shelf="metal"] .cab-rail {
  top: var(--cab-deck); height: auto;
  box-shadow: inset 0 -1px 0 rgba(0,0,0,.5), 0 4px 8px -3px rgba(0,0,0,.6);
}
.cab[data-shelf="metal"] .cab-lip { display: none; }

/* Nameplates off: no rail, only the shelf's own shade on the wall below it. */
.cab[data-plates="off"] .cab-case { --cab-pz: 6px; }
.cab[data-plates="off"][data-shelf="glass"] .cab-rail {
  background: linear-gradient(180deg, rgba(0,0,0,.35), rgba(0,0,0,0));
  box-shadow: none;
}

/* ---- the light: an LED strip along the front of the shelf above, a cone
   from each downlight, a pool where it lands on the deck. The layer goes on
   and off by opacity alone (cabinet.js: the lights come on row by row). */
.cab-lamp {
  --lc: var(--cab-light);
  position: absolute; z-index: 1; top: 0; left: 0; right: 0;
  bottom: calc(var(--cab-edge) + var(--cab-pz));
  pointer-events: none;
  opacity: 0;
  transition: opacity 420ms var(--ease-out);
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--lc) 35%, #fff) 0 1.5px,
      color-mix(in srgb, var(--lc) 85%, transparent) 1.5px 3px,
      rgba(0,0,0,0) 3px) top / 100% 3px no-repeat,
    linear-gradient(180deg,
      color-mix(in srgb, var(--lc) 30%, transparent),
      color-mix(in srgb, var(--lc) 9%, transparent) calc(var(--cab-head) * 2.2),
      rgba(0,0,0,0) calc(var(--cab-head) * 4.6)) top / 100% 100% no-repeat,
    radial-gradient(10px 3px at 50% 1px, #fff, color-mix(in srgb, var(--lc) 80%, transparent) 55%, rgba(0,0,0,0))
      top center / var(--cab-spot) 100% repeat-x,
    radial-gradient(44% 98% at 50% 0,
      color-mix(in srgb, var(--lc) calc(24% * var(--cab-glow, 1)), transparent),
      color-mix(in srgb, var(--lc) calc(8% * var(--cab-glow, 1)), transparent) 55%,
      rgba(0,0,0,0) 80%) top center / var(--cab-spot) 100% repeat-x,
    radial-gradient(38% 50% at 50% 100%,
      color-mix(in srgb, var(--lc) 50%, transparent),
      color-mix(in srgb, var(--lc) 14%, transparent) 55%,
      rgba(0,0,0,0)) bottom center / var(--cab-spot) calc(var(--cab-deck) * 1.6) repeat-x;
}
.cab-row.is-lit .cab-lamp { opacity: 1; }
.cab[data-light="off"] .cab-lamp { display: none; }
.cab[data-back="mirror"] { --cab-glow: 1.45; }
.cab:is([data-back="light"], [data-back-tone="light"]) { --cab-glow: 1.3; }

/* Full motion: each strip flickers on as its row's turn comes. */
:root[data-motion="full"] .cab.is-powering .cab-row.is-lit .cab-lamp {
  animation: cab-power 760ms linear both;
  animation-delay: var(--cab-power-delay, 0ms);
}
@keyframes cab-power {
  0% { opacity: 0; }
  7% { opacity: .85; }
  11% { opacity: .12; }
  19% { opacity: .95; }
  25% { opacity: .45; }
  36%, 100% { opacity: 1; }
}

/* ================================================================== track */
.cab-track {
  position: relative; z-index: 2;
  height: 100%;
  display: flex; align-items: flex-end;
  gap: var(--cab-gap);
  padding: 0 var(--cab-pad-x);
  overflow-x: auto; overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--cab-pad-x);
  scrollbar-width: none;
}
.cab-track::-webkit-scrollbar { display: none; }
/* a row that fits stands centred on its shelf; one that does not starts at the wall */
.cab-track > :first-child { margin-left: auto; }
.cab-track > :last-child { margin-right: auto; }
/* the ends of a row that runs on fade into the walls */
.cab-track.is-over {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--cab-fl, 0px), #000 calc(100% - var(--cab-fr, 0px)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 var(--cab-fl, 0px), #000 calc(100% - var(--cab-fr, 0px)), transparent 100%);
}
.cab-track.is-over:not(.at-start) { --cab-fl: clamp(26px, 7cqi, 56px); }
.cab-track.is-over:not(.at-end) { --cab-fr: clamp(26px, 7cqi, 56px); }
.cab.is-dragging .cab-track { scroll-snap-type: none; }

/* Pointer devices: a quiet arrow at each end of a row that runs on. */
.cab-nudge {
  position: absolute; z-index: 4; top: calc(var(--cab-head) + var(--cab-h) * .5 - 16px);
  display: none; place-items: center;
  width: 32px; height: 32px; padding: 0; border-radius: 50%;
  color: #fff; background: rgba(14,15,19,.62);
  border: 1px solid rgba(255,255,255,.18);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14), 0 4px 12px rgba(0,0,0,.45);
  cursor: pointer; opacity: 0;
  transition: opacity var(--t-1) var(--ease-out), transform var(--t-1) var(--ease-out);
}
.cab-nudge svg { width: 16px; height: 16px; }
.cab-nudge.is-prev { left: 8px; }
.cab-nudge.is-next { right: 8px; }
@media (hover: hover) and (pointer: fine) {
  .cab-row.is-over:not(.at-start) .cab-nudge.is-prev,
  .cab-row.is-over:not(.at-end) .cab-nudge.is-next { display: grid; }
  .cab-row:hover .cab-nudge { opacity: 1; }
  .cab-nudge:hover { transform: scale(1.08); background: rgba(14,15,19,.8); }
}
.cab.is-dragging .cab-nudge, .cab.is-preview .cab-nudge { display: none !important; }

/* =================================================================== kits */
.cab-item {
  --k: .76;
  --ar: .7;
  --fh: calc(var(--cab-h) * var(--k));
  --fw: calc(var(--fh) * var(--ar));
  position: relative; flex: none;
  width: max(var(--cab-plate-min), calc(var(--fw) + 12px));
  height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  padding-bottom: calc(var(--cab-df) + var(--cab-edge) + var(--cab-pz));
  scroll-snap-align: center;
  content-visibility: auto;
  contain-intrinsic-size: auto 100px auto 200px;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
/* The kit with the keyboard (or in hand) draws its ring over its neighbours,
   unclipped: content-visibility's paint containment is lifted for it alone. */
.cab-item:focus-within, .cab-item.is-held { content-visibility: visible; z-index: 3; }

/* A photo in an acrylic block: the block, its padding and its base. */
.cab-item[data-kind="block"], .cab-fig.is-block {
  --bh: max(3px, calc(var(--fh) * .075));
  --bp: max(2px, calc(var(--fh) * .03));
  --bw: calc((var(--fh) - var(--bh) - 2 * var(--bp)) * var(--ar) + 2 * var(--bp));
  --fw: calc(var(--bw) * 1.1);
}
/* No photo: the kit's box, standing on its end. */
.cab-item[data-kind="box"], .cab-fig.is-box { --fw: calc(var(--fh) * .78); }

.cab-kit {
  appearance: none; -webkit-appearance: none;
  display: block; position: static;
  margin: 0; padding: 0; border: 0; background: none;
  font: inherit; color: inherit; text-align: center;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.cab-kit:focus { outline: none; }
.cab.is-editable.is-arranging .cab-kit { cursor: grab; touch-action: none; }

/* What stands on the shelf; clipped at the shelf's front edge so a reflection
   stays in the glass and never runs down the lip. */
.cab-stand {
  position: relative; display: block;
  width: var(--fw); height: var(--fh);
  clip-path: inset(-45% -30% calc(-1 * (var(--cab-df) + var(--cab-edge))) -30%);
}
.cab-fig {
  position: absolute; z-index: 1; left: 0; bottom: 0;
  display: block;
  width: var(--fw); height: var(--fh);
  transition: transform var(--t-2) var(--ease-out), opacity var(--t-2) var(--ease-out);
}
.cab-fig img {
  display: block; pointer-events: none;
  -webkit-user-drag: none;
}

/* the contact shadow where it meets the deck */
.cab-shadow {
  position: absolute; z-index: 0; left: 50%; bottom: calc(var(--cab-df) * -.45);
  width: calc(var(--fw) * .92); height: max(6px, calc(var(--cab-deck) * .95));
  translate: -50% 0;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(0,0,0,.62), rgba(0,0,0,.24) 55%, rgba(0,0,0,0));
  transition: transform var(--t-2) var(--ease-out), opacity var(--t-2) var(--ease-out);
}
.cab:is([data-back="light"], [data-back-tone="light"]) .cab-shadow {
  background: radial-gradient(closest-side, rgba(0,0,0,.42), rgba(0,0,0,.14) 55%, rgba(0,0,0,0));
}

/* ---- a cut-out stands straight on the shelf */
.cab-fig.is-cutout img { width: 100%; height: 100%; object-fit: contain; object-position: 50% 100%; }

/* ---- a photo in a clear acrylic block on a black acrylic base */
.cab-block {
  position: absolute; left: 50%; bottom: var(--bh);
  width: var(--bw); height: calc(var(--fh) - var(--bh));
  translate: -50% 0;
  padding: var(--bp);
  border-radius: 2px;
  background:
    linear-gradient(135deg, rgba(255,255,255,.2), rgba(255,255,255,.04) 38%, rgba(255,255,255,.1));
  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,.32),
    inset 1px 1px 0 rgba(255,255,255,.45),
    inset -1px -1px 0 rgba(0,0,0,.25),
    0 8px 16px -6px rgba(0,0,0,.6);
}
.cab-block img {
  width: 100%; height: 100%; object-fit: cover; border-radius: 1px;
  background: rgba(0,0,0,.35);
  outline: 1px solid rgba(0,0,0,.35); outline-offset: -1px;
}
/* the face of the acrylic: a raking glare and a lit top edge, over the photo */
.cab-block::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background:
    linear-gradient(118deg, rgba(255,255,255,0) 22%, rgba(255,255,255,.16) 32%, rgba(255,255,255,.03) 40%, rgba(255,255,255,0) 48%),
    linear-gradient(180deg, rgba(255,255,255,.14), rgba(255,255,255,0) 14%);
}
.cab-base {
  position: absolute; left: 0; right: 0; bottom: 0; height: var(--bh);
  border-radius: 1.5px;
  background:
    linear-gradient(180deg, rgba(255,255,255,.4) 0 1px, rgba(255,255,255,.06) 1px, rgba(255,255,255,0) 60%),
    linear-gradient(180deg, #202126, #07080a);
  box-shadow: 0 2px 4px rgba(0,0,0,.5);
}

/* ---- no photo: its box, in the grade's own colour, the grade big on the front */
.cab-box {
  position: absolute; inset: 0;
  container-type: inline-size;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 10% 9% 9% 8%;
  border-radius: 2px 3px 3px 2px;
  color: #fff; text-align: left; overflow: hidden;
  background:
    linear-gradient(90deg, rgba(0,0,0,0) 90%, rgba(0,0,0,.34) 90.5%, rgba(0,0,0,.22)),
    linear-gradient(162deg, rgba(255,255,255,.22), rgba(255,255,255,0) 34%),
    linear-gradient(200deg, rgba(0,0,0,0) 52%, rgba(0,0,0,.28)),
    linear-gradient(180deg,
      color-mix(in srgb, var(--tone, #60a5fa) 78%, #fff),
      var(--tone, #60a5fa) 32%,
      color-mix(in srgb, var(--tone, #60a5fa) 52%, #000));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.45),
    inset 1px 0 0 rgba(255,255,255,.2),
    0 8px 16px -6px rgba(0,0,0,.6);
}
/* the band across the lid a kit box carries its line in */
.cab-box::before {
  content: ""; position: absolute; left: 0; right: 10%; top: 0; height: 7%;
  background: linear-gradient(180deg, rgba(10,12,18,.62), rgba(10,12,18,.4));
}
.cab-box-grade {
  position: relative;
  font-size: 30cqi; font-weight: 800; letter-spacing: -.04em; line-height: .9;
  text-shadow: 0 1px 0 rgba(0,0,0,.25), 0 0 1px rgba(0,0,0,.2);
  margin-top: 4%;
}
.cab-box-name {
  font-size: max(7px, 9.5cqi); font-weight: 700; line-height: 1.12;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
  overflow: hidden; overflow-wrap: anywhere;
  padding-right: 10%;
  text-shadow: 0 1px 2px rgba(0,0,0,.4);
}
.cab-box-scale {
  font-size: max(6px, 7.5cqi); font-weight: 700; letter-spacing: .06em; opacity: .85;
}
/* a box too small to letter: the grade alone */
@container (max-width: 52px) {
  .cab-box-name, .cab-box-scale { display: none; }
}

/* ==========================================================================
   Figures, games and consoles (cabinet.js figureOf). Each is drawn from the
   same few things as a kit's box — the item's `--tone` (a figure's size
   class, a platform's colour), the one light from the top left, a contact
   shadow — so a shelf of any kind reads as the same cabinet. Nothing here
   moves but by transform and opacity.
   ========================================================================== */

/* ---- the silhouette a figure stands in when it has no photo: a robot, feet
   apart, drawn as a mask the size class's colour shows through (on :root, so
   the Shelves page's little cabinets can stand one too) */
:root {
  --cab-sil: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 180'%3E%3Cpath d='M42 10L50 2L58 10L60 22L55 28H45L40 22Z M45 27H55V34H45Z M24 36L38 32H62L76 36L82 50L74 60L68 58L67 80L61 88H39L33 80L32 58L26 60L18 50Z M19 53L27 59L25 92L20 106L12 104L15 90Z M81 53L73 59L75 92L80 106L88 104L85 90Z M37 87H63L65 100H35Z M35 99H48L47 138L49 168L28 172L27 166L33 150Z M52 99H65L67 150L73 166L72 172L51 168L53 138Z'/%3E%3C/svg%3E");
}
.cab-sil {
  display: block;
  -webkit-mask: var(--cab-sil) 50% 100% / contain no-repeat;
  mask: var(--cab-sil) 50% 100% / contain no-repeat;
  background:
    radial-gradient(9% 2.4% at 50% 9.5%, color-mix(in srgb, var(--tone) 25%, #fff), rgba(255,255,255,0)),       /* the visor, lit */
    radial-gradient(55% 26% at 40% 30%, rgba(255,255,255,.42), rgba(255,255,255,0) 70%),                        /* the chest catches the light */
    repeating-linear-gradient(180deg, rgba(0,0,0,0) 0 19%, rgba(0,0,0,.16) 19% 19.8%),                          /* panel lines */
    linear-gradient(90deg, color-mix(in srgb, var(--tone) 58%, #fff), var(--tone) 36%, color-mix(in srgb, var(--tone) 42%, #000));
}
.cab-figure { position: absolute; inset: 0; filter: drop-shadow(0 6px 7px rgba(0,0,0,.45)); }
.cab-figure .cab-sil { position: absolute; left: 0; right: 0; top: 0; bottom: 5.5%; }
/* a round display base in black acrylic, its rim lit */
.cab-round-base {
  position: absolute; left: 8%; right: 8%; bottom: 0; height: 8%;
  border-radius: 50%;
  background:
    radial-gradient(60% 55% at 42% 30%, rgba(255,255,255,.28), rgba(255,255,255,0) 70%),
    linear-gradient(180deg, #2b2e36, #08090b);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 2px 4px rgba(0,0,0,.55);
}

/* ---- a package: a figure's window box or blister card, a console's box.
   With a photo, the photo is its face; without, it is drawn in the tone. */
.cab-pkg {
  position: absolute; inset: 0;
  display: block; overflow: hidden;
  border-radius: 2px;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.4),
    inset 0 0 0 1px rgba(0,0,0,.32),
    0 8px 16px -6px rgba(0,0,0,.6);
}
.cab-pkg.is-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* its printed face under the light, and its side falling into shade: the box has depth */
.cab-pkg::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background:
    linear-gradient(118deg, rgba(255,255,255,0) 24%, rgba(255,255,255,.13) 32%, rgba(255,255,255,.02) 39%, rgba(255,255,255,0) 46%),
    linear-gradient(90deg, rgba(0,0,0,0) 90%, rgba(0,0,0,.26) 90.6%, rgba(0,0,0,.16));
}
.cab-pkg[data-pkg] {
  container-type: inline-size;
  display: flex; flex-direction: column;
  padding: 8% 13% 8% 7%;
  color: #fff; text-align: left;
  background:
    linear-gradient(162deg, rgba(255,255,255,.24), rgba(255,255,255,0) 36%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--tone) 74%, #fff),
      var(--tone) 30%,
      color-mix(in srgb, var(--tone) 46%, #000));
}
.cab-pkg-head {
  flex: none; position: relative;
  font-size: max(6px, 8.5cqi); font-weight: 800; letter-spacing: .1em; line-height: 1.2; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-shadow: 0 1px 1px rgba(0,0,0,.35);
}
.cab-pkg-name {
  flex: none;
  font-size: max(6.5px, 9.5cqi); font-weight: 800; line-height: 1.1;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere;
  text-shadow: 0 1px 2px rgba(0,0,0,.45);
}
/* the window: dark inside, a film over it that catches the light, the figure standing in it */
.cab-pkg-window {
  position: relative; flex: 1; min-height: 0;
  margin: 7% 0;
  border-radius: 3px; overflow: hidden;
  background:
    radial-gradient(90% 55% at 50% 25%, color-mix(in srgb, var(--tone) 22%, rgba(255,255,255,.08)), rgba(0,0,0,0) 72%),
    linear-gradient(180deg, #1b1e25, #0a0b0f);
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.5), inset 0 0 0 3px rgba(0,0,0,.35), inset 0 7px 12px rgba(0,0,0,.55);
}
.cab-pkg-window .cab-sil { position: absolute; left: 12%; right: 12%; top: 8%; bottom: 3%; }
.cab-pkg-window::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(112deg, rgba(255,255,255,0) 18%, rgba(255,255,255,.26) 27%, rgba(255,255,255,.04) 36%, rgba(255,255,255,0) 44%);
}
/* a blister card: the card, a peg hole at the top, a clear bubble the figure stands in */
.cab-pkg[data-pkg="card"] { padding: 17% 8% 8%; border-radius: 3px; }
.cab-pkg[data-pkg="card"]::after { background: linear-gradient(118deg, rgba(255,255,255,0) 24%, rgba(255,255,255,.1) 32%, rgba(255,255,255,0) 44%); }
.cab-pkg-tab {
  position: absolute; left: 50%; top: 4.5%; width: 24%; height: 5%;
  translate: -50% 0; border-radius: 99px;
  background: rgba(0,0,0,.62);
  box-shadow: inset 0 1px 2px rgba(0,0,0,.7), 0 1px 0 rgba(255,255,255,.3);
}
.cab-pkg[data-pkg="card"] .cab-pkg-head { text-align: center; }
.cab-pkg[data-pkg="card"] .cab-pkg-window {
  margin: 6% 3%;
  border-radius: 24% 24% 14% 14% / 14% 14% 9% 9%;
  background:
    linear-gradient(135deg, rgba(255,255,255,.34), rgba(255,255,255,.05) 40%, rgba(255,255,255,.16)),
    color-mix(in srgb, var(--tone) 40%, #0d0f14);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.65), inset 0 -6px 10px rgba(0,0,0,.25), 0 5px 8px rgba(0,0,0,.35);
}
.cab-pkg[data-pkg="card"] .cab-pkg-name { text-align: center; }
/* a console's box: landscape, the console drawn on its face */
.cab-pkg[data-pkg="console"] { padding: 7% 9% 7% 6%; }
.cab-pkg-art {
  flex: 1; min-height: 0; display: grid; place-items: center;
  color: rgba(255,255,255,.88);
  filter: drop-shadow(0 2px 3px rgba(0,0,0,.35));
}
.cab-pkg-art svg { width: 62%; height: auto; max-height: 100%; stroke-width: 1.15; }
@container (max-width: 46px) {
  .cab-pkg-head, .cab-pkg-name { display: none; }
}

/* ---- sealed: shrink-wrap over whatever the package or case is — a crinkled
   film that catches the light in streaks */
.cab-fig.is-sealed:is(.is-case, .is-package, .is-pkg)::after {
  content: ""; position: absolute; inset: -.5px; z-index: 2; pointer-events: none;
  border-radius: 3px;
  background:
    linear-gradient(103deg, rgba(255,255,255,0) 7%, rgba(255,255,255,.3) 9.5%, rgba(255,255,255,0) 13%),
    linear-gradient(96deg, rgba(255,255,255,0) 57%, rgba(255,255,255,.2) 60.5%, rgba(255,255,255,0) 64%),
    linear-gradient(174deg, rgba(255,255,255,.2), rgba(255,255,255,0) 20%, rgba(255,255,255,0) 82%, rgba(255,255,255,.12)),
    radial-gradient(38% 16% at 76% 11%, rgba(255,255,255,.34), rgba(255,255,255,0));
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.22);
}

/* ---- a game in its case: the cover behind the case's clear sleeve, the
   case's rim in its platform's plastic, the hinge down the spine side */
.cab-gcase {
  --case: color-mix(in srgb, var(--tone) 16%, #121419);
  position: absolute; inset: 0;
  display: block;
  padding: 3.4% 3.4% 3.4% 7.5%;
  border-radius: 3px;
  background:
    linear-gradient(90deg, rgba(255,255,255,.12), rgba(255,255,255,0) 8%, rgba(0,0,0,0) 92%, rgba(0,0,0,.28)),
    linear-gradient(180deg, color-mix(in srgb, var(--case) 78%, #fff), var(--case) 10%, color-mix(in srgb, var(--case) 78%, #000));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.3),
    inset 0 0 0 1px rgba(0,0,0,.4),
    0 8px 16px -6px rgba(0,0,0,.62);
}
/* cases that are not black */
.cab-gcase:is([data-platform="wii"], [data-platform="ds"], [data-platform="3ds"]) { --case: #dfe3e8; }
.cab-gcase:is([data-platform="switch"], [data-platform="switch2"]) { --case: #cf2f3c; }
.cab-gcase:is([data-platform="ps4"], [data-platform="vita"]) { --case: #2a5fb3; }
.cab-gcase[data-platform="ps5"] { --case: #e8ebf0; }
.cab-gcase[data-platform="x360"] { --case: #5a9a30; }
.cab-gcase:is([data-platform="xone"], [data-platform="xseries"]) { --case: #1d7a2c; }
.cab-gcase[data-platform="wiiu"] { --case: #2b8fd0; }
.cab-gcase-hinge {
  position: absolute; left: 0; top: 0; bottom: 0; width: 7.5%;
  border-radius: 3px 0 0 3px;
  background: linear-gradient(90deg, rgba(0,0,0,.34), rgba(255,255,255,.14) 30%, rgba(0,0,0,.22) 56%, rgba(255,255,255,.08) 76%, rgba(0,0,0,.32));
}
/* the clear sleeve: a raking glare and a lit top edge over the cover */
.cab-gcase::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background:
    linear-gradient(114deg, rgba(255,255,255,0) 18%, rgba(255,255,255,.17) 28%, rgba(255,255,255,.03) 36%, rgba(255,255,255,0) 44%),
    linear-gradient(180deg, rgba(255,255,255,.15), rgba(255,255,255,0) 9%);
}
/* a CD jewel case: clear all round, the black tray behind, a ridged hinge */
.cab-gcase[data-material="jewel"] {
  padding: 2.4% 2.4% 2.4% 10%;
  border-radius: 1.5px;
  background: linear-gradient(180deg, rgba(222,230,238,.42), rgba(160,172,186,.3)), #101216;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.35), inset 1px 1px 0 rgba(255,255,255,.4), 0 7px 14px -6px rgba(0,0,0,.6);
}
.cab-gcase[data-material="jewel"] .cab-gcase-hinge {
  width: 10%; border-radius: 1.5px 0 0 1.5px;
  background:
    repeating-linear-gradient(180deg, rgba(255,255,255,.22) 0 1px, rgba(0,0,0,.18) 1px 3px),
    linear-gradient(90deg, rgba(255,255,255,.2), rgba(0,0,0,.35));
}
/* a cardboard box (NES, SNES, N64, Game Boy, a big PC box): no rim, square
   corners, printed to the edge, a paper edge catching the light */
.cab-gcase[data-material="card"] {
  padding: 0; border-radius: 1.5px;
  background: none;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.35), 0 8px 16px -6px rgba(0,0,0,.62);
}
.cab-gcase[data-material="card"] .cab-gcase-hinge { display: none; }
.cab-gcase[data-material="card"]::after {
  background:
    linear-gradient(118deg, rgba(255,255,255,0) 24%, rgba(255,255,255,.1) 32%, rgba(255,255,255,0) 42%),
    linear-gradient(90deg, rgba(0,0,0,0) 94%, rgba(0,0,0,.24)),
    linear-gradient(180deg, rgba(255,255,255,.2) 0 1px, rgba(255,255,255,0) 1px);
  box-shadow: inset 1px 1px 0 rgba(255,255,255,.28);
}

/* the cover itself: a photo, or art in the platform's colour with its band and the title */
.cab-cover {
  position: relative; display: block; width: 100%; height: 100%;
  overflow: hidden; border-radius: 1px;
}
.cab-cover.is-photo { background: #0c0d10; }
.cab-cover.is-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.cab-cover:not(.is-photo) {
  container-type: inline-size;
  display: flex; flex-direction: column;
  color: #fff; text-align: left;
  background:
    radial-gradient(110% 60% at 18% 8%, rgba(255,255,255,.3), rgba(255,255,255,0) 58%),
    linear-gradient(158deg, color-mix(in srgb, var(--tone) 72%, #fff), var(--tone) 42%, color-mix(in srgb, var(--tone) 42%, #000));
}
.cab-cover-band {
  flex: none; display: flex; align-items: center;
  height: max(8px, 12cqi); padding: 0 7%;
  font-size: max(5.5px, 7.5cqi); font-weight: 850; letter-spacing: .12em; text-transform: uppercase; white-space: nowrap; overflow: hidden;
  background: linear-gradient(180deg, rgba(10,12,16,.9), rgba(10,12,16,.74));
  box-shadow: 0 1px 0 rgba(255,255,255,.14);
}
/* a quiet emblem where the box art would be */
.cab-cover-art {
  flex: 1; min-height: 0;
  background:
    radial-gradient(circle at 64% 44%, rgba(255,255,255,.3) 0 13%, rgba(255,255,255,0) 13.6%),
    radial-gradient(circle at 64% 44%, rgba(255,255,255,0) 0 21%, rgba(255,255,255,.14) 21.6% 23%, rgba(255,255,255,0) 23.6%),
    linear-gradient(145deg, rgba(255,255,255,0) 52%, rgba(0,0,0,.14) 52.3%, rgba(0,0,0,0) 72%);
}
.cab-cover-title {
  flex: none; padding: 0 8% 9%;
  font-size: max(6.5px, 11cqi); font-weight: 850; line-height: 1.04; letter-spacing: -.01em;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere;
  text-shadow: 0 1px 2px rgba(0,0,0,.5);
}
/* a landscape box has room for the title beside its emblem, not under it */
.cab-gcase[data-box="land"] .cab-cover-title { font-size: max(6.5px, 8.5cqi); padding-right: 40%; }
@container (max-width: 40px) {
  .cab-cover-title, .cab-cover-band { display: none; }
}

/* ---- spines out: each game a spine packed against the next, as on a
   bookshelf — the platform's band at the head, the title reading down it */
.cab-item.is-spine {
  width: calc(var(--fw) + 1px);
  scroll-snap-align: none;
}
.cab-item.is-spine + .cab-item.is-spine { margin-left: calc(1.5px - var(--cab-gap)); }
.cab-item.is-spine .cab-plate { display: none; }
/* Arranging: spines stand apart, wide enough for their S / M / L chips */
.cab.is-arranging .cab-item.is-spine { width: max(74px, calc(var(--fw) + 12px)); }
.cab.is-arranging .cab-item.is-spine + .cab-item.is-spine { margin-left: 0; }
@media (hover: none) { .cab.is-arranging .cab-item.is-spine { width: max(108px, calc(var(--fw) + 12px)); } }
/* Arranging makes the row scroll-snap to its ends: spines, which never snap, snap then, so a row stays where it was. */
.cab.is-arranging .cab-item.is-spine { scroll-snap-align: center; }
/* A wanted spine's dashed outline reaches past its box: not clipped by the containment. */
.cab-item.is-spine.is-wanted { content-visibility: visible; }
.cab-spine {
  position: absolute; inset: 0;
  container-type: size;
  display: flex; flex-direction: column; align-items: center;
  overflow: hidden;
  border-radius: 1.5px;
  color: #fff;
  background: linear-gradient(90deg, color-mix(in srgb, var(--tone) 64%, #fff), var(--tone) 24%, color-mix(in srgb, var(--tone) 50%, #000));
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.4), 0 6px 12px -6px rgba(0,0,0,.6);
}
.cab-spine[data-material="plastic"] { border-radius: 2.5px; }
.cab-spine-photo { position: absolute; inset: 0; overflow: hidden; }
.cab-spine-photo img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: 0 50%;
  transform: scaleX(6); transform-origin: 0 50%;
  filter: blur(.6px) saturate(1.2) brightness(.72);
}
/* round the spine: lit on the light's side, into shade on the other */
.cab-spine::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(90deg, rgba(255,255,255,.3), rgba(255,255,255,0) 32%, rgba(0,0,0,0) 58%, rgba(0,0,0,.42)),
    linear-gradient(180deg, rgba(255,255,255,.16) 0 1px, rgba(255,255,255,0) 1px);
}
.cab-spine-band, .cab-spine-title {
  position: relative; z-index: 1;
  writing-mode: vertical-rl;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-shadow: 0 1px 2px rgba(0,0,0,.6);
}
.cab-spine-band {
  flex: none; width: 100%; max-height: 30%;
  display: flex; align-items: center; justify-content: center;
  padding: 16cqw 0;
  font-size: clamp(5px, 40cqw, 9px); font-weight: 850; letter-spacing: .08em;
  background: linear-gradient(90deg, rgba(8,10,14,.72), rgba(8,10,14,.9));
}
.cab-spine-title {
  flex: 1 1 auto; min-height: 0;
  padding: 14cqw 0 18cqw;
  font-size: clamp(6.5px, 50cqw, 13px); font-weight: 750; letter-spacing: .02em; line-height: 1;
}
/* too thin to read: the colour alone */
@container (max-width: 11px) {
  .cab-spine-band, .cab-spine-title { display: none; }
}
/* a spine pulled a little way out under the pointer, as a book is */
@media (hover: hover) {
  :root[data-motion="full"] .cab:not(.is-dragging) .cab-item.is-spine .cab-kit:hover .cab-fig { transform: translateY(-8px); }
}

/* ---- a game on its own: a cartridge or game card on a small acrylic easel,
   or a disc standing label out */
.cab-easel {
  position: absolute; left: 18%; right: 18%; bottom: 0; height: 8%;
  clip-path: polygon(12% 0, 88% 0, 100% 100%, 0 100%);
  background: linear-gradient(180deg, rgba(255,255,255,.5) 0 1px, #2a2d34 1px, #07080a);
}
.cab-cart {
  position: absolute; left: 6%; right: 6%; top: 0; bottom: 6%;
  container-type: inline-size;
  display: block;
  padding: 10% 10% 24%;
  border-radius: 7% 7% 4% 4% / 5% 5% 3% 3%;
  background:
    linear-gradient(90deg, rgba(255,255,255,.14), rgba(255,255,255,0) 18%, rgba(0,0,0,0) 82%, rgba(0,0,0,.3)),
    linear-gradient(180deg, color-mix(in srgb, var(--tone) 14%, #464a53), color-mix(in srgb, var(--tone) 10%, #1d1f25));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.26), inset 0 0 0 1px rgba(0,0,0,.35), 0 6px 12px -5px rgba(0,0,0,.6);
}
/* the grip moulded into its bottom edge */
.cab-cart::after {
  content: ""; position: absolute; left: 20%; right: 20%; bottom: 7%; height: 10%;
  border-radius: 2px;
  background: repeating-linear-gradient(90deg, rgba(0,0,0,.4) 0 1.5px, rgba(255,255,255,.08) 1.5px 3.5px);
}
.cab-cart[data-media="card"] { padding: 9% 9% 14%; border-radius: 9% / 7%; }
.cab-cart[data-media="card"]::after { display: none; }
.cab-cart-label {
  display: flex; flex-direction: column; height: 100%;
  overflow: hidden; border-radius: 2px;
  color: #fff; text-align: left;
  background:
    radial-gradient(110% 60% at 18% 8%, rgba(255,255,255,.3), rgba(255,255,255,0) 58%),
    linear-gradient(158deg, color-mix(in srgb, var(--tone) 72%, #fff), var(--tone) 42%, color-mix(in srgb, var(--tone) 42%, #000));
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.28);
}
.cab-cart-band {
  flex: none; padding: 5% 8%;
  font-size: max(5px, 9cqi); font-weight: 850; letter-spacing: .12em; text-transform: uppercase; white-space: nowrap; overflow: hidden;
  background: rgba(10,12,16,.78);
}
.cab-cart-title {
  margin-top: auto; padding: 0 8% 9%;
  font-size: max(6px, 12cqi); font-weight: 850; line-height: 1.04;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere;
  text-shadow: 0 1px 2px rgba(0,0,0,.45);
}
.cab-disc { position: absolute; inset: 0; }
.cab-disc-face {
  position: absolute; left: 0; top: 0; width: 100%; aspect-ratio: 1;
  container-type: inline-size;
  border-radius: 50%;
  background:
    radial-gradient(circle, #0a0b0d 0 6.5%, rgba(236,240,246,.88) 7% 15%, rgba(150,160,172,.95) 15.4% 16.4%, rgba(0,0,0,0) 16.8%),
    radial-gradient(circle, rgba(0,0,0,0) 0 94.5%, #d4dae2 95.2%, #7f8894 100%),
    radial-gradient(90% 60% at 30% 20%, rgba(255,255,255,.32), rgba(255,255,255,0) 60%),
    linear-gradient(150deg, color-mix(in srgb, var(--tone) 70%, #fff), var(--tone) 45%, color-mix(in srgb, var(--tone) 48%, #000));
  box-shadow: 0 6px 12px -5px rgba(0,0,0,.6);
}
/* the light running round the disc */
.cab-disc-face::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: conic-gradient(from 210deg, rgba(255,255,255,0), rgba(255,255,255,.22) 8%, rgba(255,255,255,0) 18%, rgba(255,255,255,0) 50%, rgba(255,255,255,.14) 58%, rgba(255,255,255,0) 68%);
}
.cab-disc-label {
  position: absolute; left: 16%; right: 16%; top: 62%;
  font-size: max(5.5px, 8.5cqi); font-weight: 850; line-height: 1.05; text-align: center; color: #fff;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere;
  text-shadow: 0 1px 2px rgba(0,0,0,.5);
}
.cab-disc .cab-easel { left: 28%; right: 28%; height: 9%; }
@container (max-width: 46px) {
  .cab-disc-label, .cab-cart-band, .cab-cart-title { display: none; }
}

/* ---- a console out of its box: a home console seen a little from above —
   its top, then its front with the slot, its name and a lit power light — or
   a handheld standing on an easel, screen and buttons */
.cab-unit.is-home { position: absolute; left: 0; right: 0; bottom: 0; height: 64%; }
.cab-unit-top {
  position: absolute; left: 0; right: 0; top: 0; height: 36%;
  clip-path: polygon(5% 0, 95% 0, 100% 100%, 0 100%);
  background:
    linear-gradient(90deg, rgba(255,255,255,.12), rgba(255,255,255,0) 40%, rgba(0,0,0,.12)),
    linear-gradient(180deg, color-mix(in srgb, var(--tone) 16%, #5a5f69), color-mix(in srgb, var(--tone) 14%, #3a3e46));
}
.cab-unit-front {
  position: absolute; left: 0; right: 0; top: 36%; bottom: 0;
  container-type: inline-size;
  display: flex; align-items: center; gap: 5%;
  padding: 0 6%;
  border-radius: 0 0 4px 4px;
  background:
    linear-gradient(90deg, rgba(255,255,255,.08), rgba(255,255,255,0) 30%, rgba(0,0,0,0) 80%, rgba(0,0,0,.25)),
    linear-gradient(180deg, color-mix(in srgb, var(--tone) 16%, #2e3138), color-mix(in srgb, var(--tone) 12%, #15171b));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.22), 0 8px 14px -6px rgba(0,0,0,.65);
}
/* a stripe in the platform's colour along the front's top edge */
.cab-unit-front::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 5%;
  background: linear-gradient(90deg, rgba(0,0,0,0), var(--tone) 12%, var(--tone) 88%, rgba(0,0,0,0));
  opacity: .85;
}
.cab-unit-slot {
  flex: 1.3; height: 11%; min-height: 2px;
  border-radius: 99px;
  background: #040506;
  box-shadow: 0 1px 0 rgba(255,255,255,.16);
}
.cab-unit-name {
  flex: 1; min-width: 0;
  font-size: max(5px, 5.5cqi); font-weight: 850; letter-spacing: .14em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: rgba(255,255,255,.66);
}
.cab-unit-led {
  flex: none; width: max(3px, 2.6cqi); aspect-ratio: 1; border-radius: 50%;
  background: color-mix(in srgb, var(--tone) 60%, #fff);
  box-shadow: 0 0 5px 1px color-mix(in srgb, var(--tone) 80%, transparent);
}
.cab-unit.is-handheld {
  position: absolute; left: 4%; right: 4%; top: 0; bottom: 6%;
  border-radius: 10% 10% 18% 10% / 7% 7% 12% 7%;
  background:
    linear-gradient(90deg, rgba(255,255,255,.2), rgba(255,255,255,0) 26%, rgba(0,0,0,0) 76%, rgba(0,0,0,.26)),
    linear-gradient(180deg, color-mix(in srgb, var(--tone) 72%, #fff), var(--tone) 40%, color-mix(in srgb, var(--tone) 55%, #000));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), inset 0 0 0 1px rgba(0,0,0,.28), 0 7px 14px -6px rgba(0,0,0,.6);
}
.cab-unit-screen {
  position: absolute; left: 13%; right: 13%; top: 8%; height: 40%;
  border-radius: 4px;
  background:
    linear-gradient(118deg, rgba(255,255,255,0) 30%, rgba(255,255,255,.16) 38%, rgba(255,255,255,0) 48%),
    radial-gradient(80% 70% at 50% 40%, color-mix(in srgb, var(--tone) 30%, #2a3a2e), #0c100d);
  box-shadow: 0 0 0 max(2px, .9cqi) rgba(10,12,16,.72), inset 0 2px 6px rgba(0,0,0,.6);
}
.cab-unit-pad {
  position: absolute; left: 13%; top: 62%; width: 26%; aspect-ratio: 1;
  background:
    linear-gradient(#17191e, #17191e) center / 34% 100% no-repeat,
    linear-gradient(#17191e, #17191e) center / 100% 34% no-repeat;
  filter: drop-shadow(0 1px 0 rgba(255,255,255,.25));
}
.cab-unit-btns {
  position: absolute; right: 12%; top: 60%; width: 28%; aspect-ratio: 1;
  background:
    radial-gradient(circle at 72% 32%, #b8263a 0 16%, rgba(0,0,0,0) 17%),
    radial-gradient(circle at 30% 68%, #b8263a 0 16%, rgba(0,0,0,0) 17%);
  filter: drop-shadow(0 1px 0 rgba(255,255,255,.3));
}
.cab-unit.is-handheld ~ .cab-easel { left: 26%; right: 26%; height: 7%; }

/* ---- reflections, in the shelf's own surface (Chrome, Safari; none in Firefox) */
@supports (-webkit-box-reflect: below 0px) {
  .cab[data-reflect="on"][data-shelf="glass"] .cab-fig {
    -webkit-box-reflect: below 0px linear-gradient(transparent 76%, rgba(255,255,255,.34));
  }
  .cab[data-reflect="on"][data-shelf="metal"] .cab-fig {
    -webkit-box-reflect: below 0px linear-gradient(transparent 80%, rgba(255,255,255,.24));
  }
  .cab[data-reflect="on"][data-shelf="wood"] .cab-fig {
    -webkit-box-reflect: below 0px linear-gradient(transparent 84%, rgba(255,255,255,.13));
  }
  .cab .cab-item.is-wanted .cab-fig { -webkit-box-reflect: none; }
}

/* ---- the nameplate on the rail: name, then grade · scale (· value) */
.cab-plate {
  position: absolute; z-index: 2; left: 50%;
  bottom: calc((var(--cab-pz) - var(--cab-plate-h)) / 2);
  width: min(calc(100% - 6px), var(--cab-plate-max));
  height: var(--cab-plate-h);
  translate: -50% 0;
  display: flex; flex-direction: column; justify-content: center; gap: 1px;
  padding: 0 7px;
  border-radius: 2px;
  color: var(--plate-ink);
  text-shadow: 0 1px 0 var(--plate-ink-hi);
  text-align: center;
  background:
    repeating-linear-gradient(90deg, rgba(255,255,255,.1) 0 1px, rgba(0,0,0,.05) 1px 2px, rgba(0,0,0,0) 2px 3px),
    linear-gradient(180deg, var(--plate-a), var(--plate-b) 55%, var(--plate-c));
  box-shadow:
    inset 0 1px 0 var(--plate-hi),
    inset 0 -1px 0 rgba(0,0,0,.28),
    0 1px 2px rgba(0,0,0,.6);
  overflow: hidden;
  pointer-events: none;
}
/* two tiny screws */
.cab-plate::before, .cab-plate::after {
  content: ""; position: absolute; top: 50%; width: 3px; height: 3px; margin-top: -1.5px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--plate-hi), var(--plate-c) 70%);
  box-shadow: 0 0 0 .5px rgba(0,0,0,.35);
}
.cab-plate::before { left: 3px; }
.cab-plate::after { right: 3px; }
.cab-plate-name {
  display: block; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: 10.5px; font-weight: 700; line-height: 1.15; letter-spacing: .005em;
}
/* The line under the name is short parts (cabinet.js plateNode), laid out as
   words that wrap onto a second line the plate is too short to show: a part
   that does not fit whole is left off, never cut to a dangling "· …". Only a
   first part too long for the plate on its own is cut, with an ellipsis. */
.cab-plate-meta {
  display: flex; flex-wrap: wrap; justify-content: center; align-content: flex-start;
  min-width: 0; height: 11px; overflow: hidden;
  font-size: 9px; font-weight: 650; line-height: 11px; letter-spacing: .05em; text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}
.cab-plate-part {
  flex: 0 1 auto; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  opacity: .8;
}
.cab-plate-part + .cab-plate-part::before { content: "·"; padding: 0 .38em; }
/* an amount reads as it does everywhere else ("¥2.5k"), never shouted in capitals */
.cab-plate-val { font-weight: 800; opacity: 1; text-transform: none; letter-spacing: .01em; }
.cab-plate-qty { font-weight: 800; }
/* the state of one's own copy — CIB, Sealed, Loose — as a small enamelled chip */
.cab-plate-chip {
  --chip: var(--plate-ink);
  flex: none; opacity: 1;
  height: 10px; margin: .5px 0; padding: 0 3.5px; border-radius: 2px;
  font-size: 7.5px; font-weight: 800; line-height: 10px; letter-spacing: .08em;
  color: #fff; text-shadow: none;
  background: color-mix(in srgb, var(--chip) 42%, #15171c);
  box-shadow: inset 0 0 0 .5px color-mix(in srgb, var(--chip) 70%, transparent), 0 .5px 0 var(--plate-ink-hi);
}
.cab-plate-chip.is-sealed { background: linear-gradient(180deg, color-mix(in srgb, var(--chip) 62%, #15171c), color-mix(in srgb, var(--chip) 38%, #15171c)); }
.cab-plate-part + .cab-plate-chip { margin-left: .38em; }
.cab-plate-part + .cab-plate-chip::before { content: none; }
.cab-plate-chip + .cab-plate-part::before { content: ""; padding: 0 0 0 .38em; }
.cab[data-plates="off"] .cab-plate { display: none; }

/* ---- hover: a kit lifts a touch off its shelf (Full motion, pointers that hover) */
@media (hover: hover) {
  :root[data-motion="full"] .cab:not(.is-dragging) .cab-kit:hover .cab-fig { transform: translateY(-4px); }
  :root[data-motion="full"] .cab:not(.is-dragging) .cab-kit:hover .cab-shadow { transform: scale(.88); opacity: .72; }
}

/* ---- focus: a ring that reads on every material — white, then the accent */
.cab-kit:focus-visible .cab-stand::before {
  content: ""; position: absolute; z-index: 3; inset: -6px -6px calc(-1 * var(--cab-df) * .6);
  border-radius: 7px; pointer-events: none;
  box-shadow:
    0 0 0 2px #fff,
    0 0 0 4px var(--accent),
    0 0 20px 3px color-mix(in srgb, var(--accent) 45%, transparent);
}
.cab-kit:focus-visible .cab-plate {
  box-shadow: inset 0 1px 0 var(--plate-hi), 0 0 0 2px #fff, 0 0 0 3.5px var(--accent);
}

/* ---- wanted: a ghost of the kit — no colour, half there, a dashed outline —
   and a ribbon on its plate */
.cab-item.is-wanted .cab-fig { opacity: .5; filter: grayscale(1) contrast(.92) brightness(1.08); }
.cab-item.is-wanted .cab-shadow { opacity: .35; }
.cab-item.is-wanted .cab-stand::after {
  content: ""; position: absolute; z-index: 2; inset: -5px -5px calc(-1 * var(--cab-df) * .5);
  border: 1.5px dashed color-mix(in srgb, var(--cab-ink) 50%, transparent);
  border-radius: 6px; pointer-events: none;
}
.cab-ribbon {
  position: absolute; z-index: 3; left: 0; top: 0;
  padding: 0 5px 0 4px; height: 10px;
  font-size: 7.5px; font-weight: 800; letter-spacing: .12em; line-height: 10px; text-transform: uppercase;
  color: var(--accent-ink, #04121c); text-shadow: none;
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 80%, #fff), var(--accent));
  clip-path: polygon(0 0, 100% 0, calc(100% - 4px) 50%, 100% 100%, 0 100%);
  box-shadow: 0 1px 2px rgba(0,0,0,.4);
}
.cab-item.is-wanted .cab-plate { padding-left: 42px; }
.cab-item.is-wanted .cab-plate::before { display: none; }

/* ================================================================ arrange */
/* The size chips: a small pill over each kit's head while arranging. */
.cab-sizes {
  position: absolute; z-index: 4; left: 50%;
  bottom: calc(var(--cab-df) + var(--cab-edge) + var(--cab-pz) + var(--fh) - 11px);
  translate: -50% 0;
  display: flex; gap: 1px; padding: 2px;
  border-radius: 999px;
  background: rgba(12,13,17,.82);
  border: 1px solid rgba(255,255,255,.2);
  box-shadow: 0 4px 12px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.12);
}
.cab-size {
  width: 22px; height: 18px; padding: 0; border: 0; border-radius: 999px;
  font: 700 10px/18px var(--font); color: rgba(255,255,255,.72);
  background: none; cursor: pointer;
}
.cab-size:hover { color: #fff; background: rgba(255,255,255,.12); }
.cab-size[aria-pressed="true"] { color: var(--accent-ink); background: var(--accent-fill); }
/* A finger's chips: bigger, and every kit wide enough for its whole pill, drawn whole (no containment clipping it). */
@media (hover: none) {
  .cab-size { width: 32px; height: 28px; line-height: 28px; }
  .cab.is-arranging .cab-item { width: max(108px, calc(var(--fw) + 12px)); content-visibility: visible; }
}
.cab.is-arranging .cab-stand::after {
  content: ""; position: absolute; z-index: 2; inset: -4px -4px calc(-1 * var(--cab-df) * .5);
  border: 1px dashed color-mix(in srgb, var(--cab-ink) 32%, transparent);
  border-radius: 6px; pointer-events: none;
}

/* "+" at the end of a row: an empty place on the shelf, lit from above */
.cab-add {
  --fh: calc(var(--cab-h) * .76);
  position: relative; flex: none;
  width: max(var(--cab-plate-min), calc(var(--fh) * .62 + 12px));
  height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  padding: 0 0 calc(var(--cab-df) + var(--cab-edge) + var(--cab-pz));
  margin: 0; border: 0; background: none; font: inherit; color: var(--cab-ink);
  cursor: pointer;
  scroll-snap-align: center;
}
.cab-add-slot {
  position: relative; display: grid; place-items: center;
  width: calc(var(--fh) * .62); height: var(--fh);
  border-radius: 8px;
  border: 1.5px dashed color-mix(in srgb, var(--accent) 70%, transparent);
  background:
    radial-gradient(70% 40% at 50% 100%, color-mix(in srgb, var(--accent) 26%, transparent), rgba(0,0,0,0) 70%),
    linear-gradient(180deg, color-mix(in srgb, var(--accent) 5%, transparent), color-mix(in srgb, var(--accent) 12%, transparent));
  box-shadow: 0 0 22px color-mix(in srgb, var(--accent) 22%, transparent), inset 0 0 18px color-mix(in srgb, var(--accent) 12%, transparent);
  transition: transform var(--t-1) var(--ease-out);
}
.cab-add-plus {
  display: grid; place-items: center;
  width: clamp(26px, calc(var(--fh) * .22), 40px); aspect-ratio: 1; border-radius: 50%;
  color: var(--accent-ink); background: var(--accent-fill);
  box-shadow: 0 0 16px color-mix(in srgb, var(--accent) 60%, transparent);
}
.cab-add-plus svg { width: 55%; height: 55%; }
/* where its plate will go: an empty outline on the rail */
.cab-add-label {
  position: absolute; left: 50%; bottom: calc((var(--cab-pz) - var(--cab-plate-h)) / 2);
  translate: -50% 0; max-width: calc(100% - 6px);
  height: var(--cab-plate-h); padding: 0 9px;
  display: flex; align-items: center; justify-content: center;
  border: 1px dashed color-mix(in srgb, var(--accent) 60%, transparent);
  border-radius: 2px;
  font-size: 10.5px; font-weight: 700; white-space: nowrap; overflow: hidden;
  color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.6);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
.cab[data-plates="off"] .cab-add-label { display: none; }
.cab-add:hover .cab-add-slot { transform: translateY(-2px); box-shadow: 0 0 30px color-mix(in srgb, var(--accent) 36%, transparent), inset 0 0 22px color-mix(in srgb, var(--accent) 18%, transparent); }
.cab-add:focus-visible { outline: none; }
.cab-add:focus-visible .cab-add-slot { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--accent), 0 0 24px color-mix(in srgb, var(--accent) 40%, transparent); }
/* the first kit's place, in an empty cabinet: bigger and brighter */
.cab-add.is-first { --fh: calc(var(--cab-h) * .86); width: max(160px, calc(var(--fh) * .8)); }
.cab-add.is-first .cab-add-slot { width: calc(var(--fh) * .8); }
:root[data-motion="full"] .cab-add.is-first .cab-add-slot { animation: cab-breathe 2.6s var(--ease-in-out) infinite; }
@keyframes cab-breathe { 50% { opacity: .72; } }
/* An empty cabinet is dimmer everywhere but the middle shelf. */
.cab.is-empty .cab-row:not(.has-first) .cab-lamp { opacity: .35; }

/* ---- dragging */
.cab-item.is-drag-source { display: none; }
.cab-item.is-pressing .cab-fig { transform: scale(.965); transition-duration: 300ms; }
.cab-gap {
  position: relative; flex: none; height: 100%;
  pointer-events: none;
}
.cab-gap::before {       /* the place it will land: a pool of light on the deck */
  content: ""; position: absolute; left: -4px; right: -4px;
  bottom: calc(var(--cab-edge) + var(--cab-pz) - 2px); height: calc(var(--cab-deck) * 2.2);
  border-radius: 50%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--accent) 70%, #fff), color-mix(in srgb, var(--accent) 34%, transparent) 50%, rgba(0,0,0,0));
}
.cab-gap::after {        /* and a soft beam up from it */
  content: ""; position: absolute; left: 12%; right: 12%;
  top: var(--cab-head); bottom: calc(var(--cab-df) + var(--cab-edge) + var(--cab-pz));
  border-radius: 8px 8px 3px 3px;
  border: 1.5px dashed color-mix(in srgb, var(--accent) 65%, transparent);
  background: linear-gradient(0deg, color-mix(in srgb, var(--accent) 22%, transparent), rgba(0,0,0,0) 80%);
}
:root[data-motion="full"] .cab-gap::after { animation: cab-breathe 1.4s var(--ease-in-out) infinite; }

/* The kit on its way, following the pointer (it lives on <body>). */
.cab-ghost {
  position: fixed; top: 0; left: 0; z-index: 95;
  pointer-events: none;
  will-change: transform;
  filter: drop-shadow(0 18px 18px rgba(0,0,0,.45)) drop-shadow(0 4px 6px rgba(0,0,0,.35));
}
.cab-ghost > .cab-fig { position: relative; transition: none; }
.cab-ghost .cab-fig.is-wanted { opacity: .7; filter: grayscale(1); }
html.cab-grabbing, html.cab-grabbing * { cursor: grabbing !important; }
.cab.is-dragging { -webkit-user-select: none; user-select: none; }

/* ---- held with the keyboard: lifted, ringed and glowing until it is put down */
.cab-item.is-held .cab-fig { transform: translateY(-6px) scale(1.03); }
.cab-item.is-held .cab-shadow { transform: scale(.8); opacity: .55; }
.cab-item.is-held .cab-stand::before {
  content: ""; position: absolute; z-index: 3; inset: -8px -8px calc(-1 * var(--cab-df) * .6);
  border-radius: 8px; pointer-events: none;
  box-shadow: 0 0 0 2px var(--accent), 0 0 18px 4px color-mix(in srgb, var(--accent) 50%, transparent);
}

/* ================================================================== doors
   Glass doors over the whole opening: two leaves meeting at a mullion where
   there is room, one below 700px. Static glare bands, a hairline edge, a pull
   on each leaf, and a soft sheen under the pointer on devices that hover.
   Never hit-tested: every click goes straight through to the kits. */
.cab-doors {
  position: absolute; inset: 0; z-index: 6;
  display: flex;
  pointer-events: none;
}
.cab[data-doors="off"] .cab-doors { display: none; }
.cab-glint {
  position: absolute; inset: 0;
  background: radial-gradient(32% 48% at var(--cab-dx, 50%) var(--cab-dy, 40%),
    rgba(255,255,255,.11), rgba(255,255,255,.035) 45%, rgba(255,255,255,0) 72%);
  opacity: 0;
  transition: opacity var(--t-3) var(--ease-out);
}
.cab.is-glinting .cab-glint { opacity: 1; }
:root:not([data-motion="full"]) .cab-glint { display: none; }
@media (hover: none) { .cab-glint { display: none; } }

.cab-pane {
  --cab-dfw: max(3px, calc(var(--cab-fw) * .38));
  position: relative; flex: 1;
  background:
    linear-gradient(112deg,
      rgba(255,255,255,0) 10%, rgba(255,255,255,.075) 15%, rgba(255,255,255,.02) 21%, rgba(255,255,255,0) 25%,
      rgba(255,255,255,0) 56%, rgba(255,255,255,.05) 60%, rgba(255,255,255,.012) 65%, rgba(255,255,255,0) 68%),
    linear-gradient(180deg, rgba(255,255,255,.07), rgba(255,255,255,0) 16%, rgba(255,255,255,0) 86%, rgba(255,255,255,.035)),
    rgba(196,220,240,.035);
}
/* the leaf's own frame, in the cabinet's material */
.cab-pane::before {
  content: ""; position: absolute; inset: 0;
  padding: var(--cab-dfw);
  background-color: var(--cab-mat-c);
  background-image: var(--cab-mat-v);
  background-size: var(--cab-mat-v-size);
  background-blend-mode: var(--cab-mat-blend);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.35);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
/* the glass's own lit edge, just inside the frame */
.cab-pane::after {
  content: ""; position: absolute; inset: var(--cab-dfw);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.12), inset 1px 1px 0 rgba(255,255,255,.2), inset 0 0 18px rgba(0,0,0,.18);
}
.cab-handle {
  position: absolute; z-index: 1; top: 50%;
  width: max(4px, calc(var(--cab-fw) * .32)); height: clamp(36px, 9cqi, 96px);
  translate: 0 -50%;
  border-radius: 3px;
  background:
    linear-gradient(90deg, #f1f3f6, #b9bec5 40%, #7f858e 70%, #c9cdd3);
  box-shadow: 0 2px 5px rgba(0,0,0,.55), 0 0 0 .5px rgba(0,0,0,.4), 2px 2px 0 -1px rgba(0,0,0,.25);
}
.cab[data-frame="gunmetal"] .cab-handle, .cab[data-frame="ebony"] .cab-handle {
  background: linear-gradient(90deg, #9aa1ab, #5a616a 40%, #33373d 70%, #6b727b);
}
.cab[data-frame="walnut"] .cab-handle {
  background: linear-gradient(90deg, #f6e2a6, #d2ab5c 40%, #9c7631 70%, #dcbc76);
}
.cab-pane.is-l .cab-handle { right: calc(var(--cab-dfw) + 7px); }
.cab-pane.is-r .cab-handle { left: calc(var(--cab-dfw) + 7px); }
@container cab (max-width: 699px) {
  .cab-pane.is-r { display: none; }
}

/* =============================================================== preview
   The mini cabinet in the Appearance dialog: the same object, small, still. */
.cab.is-preview { padding-bottom: 14px; pointer-events: none; }
.cab.is-preview .cab-case {
  --cab-fw: clamp(5px, 2cqi, 12px);
  --cab-h: clamp(44px, 18cqi, 96px);
  --cab-head: max(5px, calc(var(--cab-h) * .08));
  --cab-deck: max(4px, calc(var(--cab-h) * .07));
  --cab-edge: max(2px, calc(var(--cab-h) * .025));
  --cab-pz: 13px;
  --cab-plate-h: 9px;
  --cab-plate-min: 34px;
  --cab-plate-max: 70px;
  --cab-gap: max(5px, calc(var(--cab-h) * .08));
  --cab-pad-x: 8px;
  --cab-spot: max(90px, calc(var(--cab-h) * 1.6));
}
.cab.is-preview[data-plates="off"] .cab-case { --cab-pz: 4px; }
/* its plates are blank: at this size letters would only be noise */
.cab.is-preview .cab-plate > *,
.cab.is-preview .cab-plate::before, .cab.is-preview .cab-plate::after { display: none; }
.cab.is-preview .cab-handle { height: clamp(18px, 9cqi, 40px); }
.cab.is-preview::after { bottom: 3px; height: 14px; }

/* ================================================================= phones
   Near the screen's edges, a slimmer frame, rows sized to the width, each row
   its own sideways scroller, one door leaf, and one 11px line per plate. */
@container cab (max-width: 640px) {
  .cab-case {
    --cab-h: clamp(128px, 34cqi, 230px);
    --cab-pz: 20px;
    --cab-plate-h: 15px;
    --cab-plate-min: 70px;
    --cab-plate-max: 150px;
    --cab-pad-x: 12px;
    --cab-gap: 10px;
  }
  .cab.is-preview .cab-case { --cab-h: clamp(44px, 20cqi, 80px); --cab-pz: 11px; --cab-plate-h: 8px; --cab-plate-min: 30px; }
  /* one line: the name, then as many whole parts as fit after it */
  .cab-plate {
    flex-direction: row; flex-wrap: wrap; justify-content: center; align-content: flex-start; align-items: center;
    gap: 0; padding: 0 5px;
  }
  .cab-plate::before, .cab-plate::after { display: none; }
  .cab-plate-name { font-size: 11px; line-height: 15px; flex: 0 1 auto; }
  .cab-plate-meta { display: contents; }
  .cab-plate-part { font-size: 9px; line-height: 15px; }
  .cab-plate-part::before { content: "·"; padding: 0 .34em; }
  .cab-plate-chip { margin-left: .4em; line-height: 10px; }
  .cab-plate-chip::before { content: none; }
  .cab-ribbon { position: static; flex: none; align-self: center; margin-right: 3px; }
  .cab-item.is-wanted .cab-plate { padding-left: 3px; }
  /* One line that never wraps (a wrapped line is out of sight under the
     plate): the name gives way, trailing off, to what stands beside it — the
     "Wanted" ribbon and the value — rather than dropping below them. The rest
     of a plate's details are the kit sheet's on a phone. */
  .cab-plate { flex-wrap: nowrap; }
  .cab-plate-name { flex: 0 1 auto; min-width: 2.4em; }
  /* Spines wide enough to show a title and to be tapped (a Switch case was a 10px stick). */
  .cab-item.is-spine { width: max(18px, calc(var(--fw) + 1px)); }
  .cab-plate-part { flex: none; }
  .cab-plate-part:not(.cab-plate-val, .cab-plate-qty) { display: none; }
  .cab-ribbon { padding: 0 3px; font-size: 6.5px; letter-spacing: .06em; }
}

/* A phone on its side: rows a little lower, so a whole shelf and the start of
   the next fit between the top bar and the bottom one. */
@media (orientation: landscape) and (max-height: 520px) {
  .cab:not(.is-preview) .cab-case { --cab-h: clamp(108px, 15cqi, 150px); }
}

/* ================================================================ motion */
:root[data-motion="reduced"] .cab-fig,
:root[data-motion="reduced"] .cab-shadow { transition-duration: 120ms; }
:root[data-motion="reduced"] .cab-item.is-held .cab-fig { transform: none; }
:root[data-motion="off"] .cab-lamp { transition: none; }

/* ================================================================ misc */
.cab-sr {
  position: absolute !important;
  width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* ===========================================================================
   The Appearance dialog (cabinet-settings.js)
   =========================================================================== */
.modal.cab-dlg {
  width: min(980px, 100%); height: min(760px, 90vh); max-height: 90vh;
  display: flex; flex-direction: column; overflow: hidden;
}
.cab-set { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.cab-set-head {
  flex: none; padding: 16px 56px 13px 20px;
  border-bottom: 1px solid var(--line); box-shadow: var(--glass-edge);
}
.cab-set-head h2 { margin: 0 0 3px; font-size: var(--fs-h2); }
.cab-set-head p { margin: 0; font-size: var(--fs-sm); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cab-set-layout {
  flex: 1; min-height: 0;
  display: grid; grid-template-columns: minmax(300px, 1.05fr) minmax(0, 1fr);
}
.cab-set-stage {
  min-width: 0; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column;
  padding: 22px 22px 18px;
  border-right: 1px solid var(--line);
  background:
    radial-gradient(120% 70% at 50% -10%, color-mix(in srgb, var(--ink) 7%, transparent), transparent 62%),
    var(--bg);
}
/* centred while it fits, never cut off when it does not; narrower as it gets taller */
.cab-set-room { width: 100%; max-width: min(440px, calc(1900px / var(--cab-rows, 4))); margin: auto auto 0; }
.cab-set-note { margin: 12px 0 auto; text-align: center; font-size: 11.5px; color: var(--ink-3); }
.cab-set-controls {
  min-width: 0; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 20px;
  padding: 18px 22px 24px;
}
.cab-set-group { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; border: 0; min-width: 0; }
.cab-set-label {
  padding: 0; font-size: var(--fs-micro); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3);
}
.cab-opts { display: grid; grid-template-columns: repeat(auto-fill, minmax(78px, 1fr)); gap: 8px; }
.cab-opt {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 7px 5px 7px; min-width: 0;
  border: 1px solid var(--line); border-radius: 10px; background: var(--bg);
  box-shadow: var(--glass-edge);
  font-size: 12px; font-weight: 600; color: var(--ink-2); text-align: center;
  cursor: pointer;
  transition: border-color var(--t-1) var(--ease-out), background var(--t-1) var(--ease-out),
    transform var(--t-1) var(--ease-out), box-shadow var(--t-1) var(--ease-out);
}
.cab-opt:hover { color: var(--ink); border-color: color-mix(in srgb, var(--ink) 20%, var(--line)); transform: translateY(-1px); }
.cab-opt.is-on {
  color: var(--ink); border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--bg));
  box-shadow: var(--glow-accent);
}
.cab-opt:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.cab-opt input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.cab-opt-name { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* the little samples on each option */
.cab-sw {
  position: relative; display: block; width: 100%; height: 38px;
  border-radius: 6px; overflow: hidden;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.25), 0 1px 2px rgba(0,0,0,.3);
}
/* a frame sample: a corner of the carcass, rails and stile, round a dark opening */
.cab-sw.is-frame {
  background-color: var(--cab-mat-c);
  background-image: var(--cab-mat-h);
  background-size: var(--cab-mat-h-size);
  background-blend-mode: var(--cab-mat-blend);
}
.cab-sw.is-frame::before {
  content: ""; position: absolute; inset: 9px 0 9px 9px;
  background: linear-gradient(180deg, #17191e, #0c0d10);
  box-shadow: inset 0 5px 6px -4px rgba(0,0,0,.8), inset 4px 0 6px -4px rgba(0,0,0,.7);
}
.cab-sw.is-frame::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 9px;
  background-color: var(--cab-mat-c);
  background-image: var(--cab-mat-v);
  background-size: var(--cab-mat-v-size);
  background-blend-mode: var(--cab-mat-blend);
  box-shadow: inset -1px 0 0 rgba(0,0,0,.35), inset 1px 0 0 rgba(255,255,255,.18);
}
.cab-sw.is-back[data-back="dark"] { background: linear-gradient(180deg, #1b1d22, #0d0e11); }
.cab-sw.is-back[data-back="felt"] {
  background: var(--grain, none) 0 0 / 29px 29px, linear-gradient(180deg, #353b48, #22262f);
  background-blend-mode: overlay, normal;
}
.cab-sw.is-back[data-back="mirror"] {
  background:
    linear-gradient(104deg, rgba(255,255,255,0) 22%, rgba(255,255,255,.2) 34%, rgba(255,255,255,0) 44%, rgba(255,255,255,0) 60%, rgba(255,255,255,.12) 68%, rgba(255,255,255,0) 76%),
    linear-gradient(180deg, #7d858f, #464b53 45%, #30343a 75%, #50555e);
}
.cab-sw.is-back[data-back="light"] { background: linear-gradient(180deg, #f3f0ea, #dcd8cf); }
.cab-sw.is-back[data-back="color"] {
  background:
    linear-gradient(180deg, rgba(255,255,255,.12), rgba(0,0,0,.22)),
    var(--sw-c, #2b3a55);
}
.cab-sw.is-shelf { background: linear-gradient(180deg, #1b1d22, #101114); }
.cab-sw.is-shelf::before {
  content: ""; position: absolute; left: 0; right: 0; top: 60%; height: 7px;
}
.cab-sw.is-shelf::after {
  content: ""; position: absolute; left: 0; right: 0; top: calc(60% + 7px); height: 4px;
}
.cab-sw.is-shelf[data-shelf="glass"]::before { background: linear-gradient(180deg, rgba(255,255,255,.3) 0 1px, rgba(200,236,224,.12) 1px); }
.cab-sw.is-shelf[data-shelf="glass"]::after { background: linear-gradient(180deg, #e9fff6 0 1px, #93d3bd 1px, #3f7c6c); }
.cab-sw.is-shelf[data-shelf="wood"]::before { background: linear-gradient(180deg, #3a2517, #6f472d); }
.cab-sw.is-shelf[data-shelf="wood"]::after { height: 7px; background: linear-gradient(180deg, #9a6a44 0 1px, #6a432a 1px, #4a2e1c); }
.cab-sw.is-shelf[data-shelf="metal"]::before { background: linear-gradient(180deg, #7d848d, #c5cad0); }
.cab-sw.is-shelf[data-shelf="metal"]::after { background: linear-gradient(180deg, #fff 0 1px, #c7ccd2 1px, #8a919a); }
.cab-sw.is-light {
  --lc: var(--sw-c, #ffcf8f);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--lc) 40%, #fff) 0 2px, rgba(0,0,0,0) 2px),
    radial-gradient(40% 100% at 50% 0, color-mix(in srgb, var(--lc) 60%, transparent), color-mix(in srgb, var(--lc) 16%, transparent) 55%, rgba(0,0,0,0) 85%),
    linear-gradient(180deg, #1b1d22, #0d0e11);
}
.cab-sw.is-light[data-light="off"] { background: linear-gradient(180deg, #121316, #08090b); }
.cab-sw.is-light[data-light="off"]::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 16px; height: 16px; margin: -8px 0 0 -8px;
  border-radius: 50%; border: 1.5px solid rgba(255,255,255,.3);
  background: linear-gradient(135deg, transparent 45%, rgba(255,255,255,.3) 45% 55%, transparent 55%);
}
.cab-sw.is-doors { background: linear-gradient(180deg, #1b1d22, #0d0e11); }
.cab-sw.is-doors[data-doors="on"] {
  background:
    linear-gradient(112deg, rgba(255,255,255,0) 15%, rgba(255,255,255,.2) 24%, rgba(255,255,255,0) 33%, rgba(255,255,255,0) 60%, rgba(255,255,255,.12) 66%, rgba(255,255,255,0) 72%),
    linear-gradient(90deg, rgba(0,0,0,0) calc(50% - 2px), #9ea4ac calc(50% - 2px) calc(50% + 2px), rgba(0,0,0,0) calc(50% + 2px)),
    linear-gradient(180deg, #1b1d22, #0d0e11);
  box-shadow: inset 0 0 0 3px #9ea4ac, 0 1px 2px rgba(0,0,0,.3);
}
/* how games stand: three covers face on, or a row of spines packed tight */
.cab-sw.is-facing {
  display: flex; align-items: flex-end; justify-content: center; gap: 4px;
  padding: 0 8px 7px;
  background: linear-gradient(180deg, #1b1d22, #0d0e11);
}
.cab-sw.is-facing::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 4px; height: 3px;
  background: linear-gradient(180deg, #e9fff6 0 1px, #93d3bd 1px, #3f7c6c);
}
.cab-sw.is-facing i {
  display: block; flex: none; width: 14px; height: 22px; border-radius: 1.5px;
  background: linear-gradient(160deg, #8fb4ff, #3c55b8 50%, #1f2c66);
  box-shadow: inset 2px 0 0 rgba(0,0,0,.35), inset 0 0 0 1px rgba(0,0,0,.3);
}
.cab-sw.is-facing i:nth-child(3n+2) { height: 19px; background: linear-gradient(160deg, #ff9d9d, #c43d3d 50%, #5a1616); }
.cab-sw.is-facing i:nth-child(3n) { background: linear-gradient(160deg, #a9e6a4, #3d8b40 50%, #1a3d1c); }
.cab-sw.is-facing[data-facing="spines"] { gap: 1px; }
.cab-sw.is-facing[data-facing="spines"] i { width: 5px; height: 24px; box-shadow: inset 1px 0 0 rgba(255,255,255,.3), inset 0 0 0 .5px rgba(0,0,0,.4); }
.cab-sw.is-facing[data-facing="spines"] i:nth-child(3n+2) { height: 21px; }
.cab-sw.is-color-pick {
  background: conic-gradient(from 0deg, #f87171, #fbbf24, #4ade80, #38bdf8, #a78bfa, #f472b6, #f87171);
}

.cab-color-row { display: flex; align-items: center; gap: 10px; font-size: var(--fs-sm); color: var(--ink-2); }
.cab-color-row[hidden] { display: none; }
.cab-color {
  width: 44px; height: 28px; padding: 0; border: 1px solid var(--line); border-radius: 7px;
  background: none; cursor: pointer;
}
.cab-color::-webkit-color-swatch-wrapper { padding: 2px; }
.cab-color::-webkit-color-swatch { border: none; border-radius: 5px; }
.cab-color::-moz-color-swatch { border: none; border-radius: 5px; }

.cab-stepper {
  display: inline-flex; align-items: center; align-self: flex-start; gap: 2px; padding: 3px;
  background: var(--bg); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--glass-edge);
}
.cab-step {
  display: grid; place-items: center; width: 32px; height: 30px; padding: 0;
  border: 0; border-radius: 7px; background: none; color: var(--ink-2); cursor: pointer;
  font-size: 17px; font-weight: 600; line-height: 1;
}
.cab-step:hover { color: var(--ink); background: var(--bg-3); }
.cab-step[disabled] { opacity: .35; pointer-events: none; }
.cab-step-out { min-width: 5.2em; text-align: center; font-size: 13px; font-weight: 650; font-variant-numeric: tabular-nums; }
.cab-set-hint { margin: 0; font-size: 11.5px; color: var(--ink-3); max-width: 60ch; }

.cab-switches { display: flex; flex-direction: column; gap: 12px; }
.cab-switch { display: flex; align-items: center; gap: 11px; cursor: pointer; position: relative; }
.cab-switch input { position: absolute; left: 0; top: 50%; translate: 0 -50%; opacity: 0; width: 34px; height: 20px; margin: 0; pointer-events: none; }
.cab-switch-track {
  position: relative; flex: none; width: 34px; height: 20px; border-radius: 999px;
  background: var(--bg-3); border: 1px solid var(--line); box-shadow: var(--glass-edge);
  transition: background var(--t-2) var(--ease-out), border-color var(--t-2) var(--ease-out);
}
.cab-switch-track::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%;
  background: var(--ink-3);
  transition: transform var(--t-2) var(--ease-spring), background var(--t-2) var(--ease-out);
}
.cab-switch input:checked + .cab-switch-track {
  background: var(--accent-fill); border-color: transparent;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent), 0 4px 14px color-mix(in srgb, var(--accent) 22%, transparent);
}
.cab-switch input:checked + .cab-switch-track::after { transform: translateX(14px); background: var(--accent-ink); }
.cab-switch input:focus-visible + .cab-switch-track { outline: 2px solid var(--accent); outline-offset: 2px; }
.cab-switch-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.cab-switch-name { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.cab-switch-help { font-size: 11.5px; color: var(--ink-3); }
.cab-switch.is-off { opacity: .5; }

.cab-set-foot {
  flex: none; display: flex; align-items: center; gap: 8px;
  padding: 12px 20px 14px;
  border-top: 1px solid var(--line); box-shadow: var(--glass-edge);
}
.cab-set-foot .cab-set-reset { margin-right: auto; }

/* A phone: the whole screen, the cabinet over the choices, both scrolling as one. */
@media (max-width: 720px) {
  .modal.cab-dlg { height: min(100dvh - 24px, 820px); }
  .cab-set-layout { display: flex; flex-direction: column; overflow-y: auto; overscroll-behavior: contain; }
  .cab-set-stage { flex: none; overflow: visible; border-right: 0; border-bottom: 1px solid var(--line); padding: 14px 16px 12px; }
  .cab-set-room { max-width: min(300px, calc(1300px / var(--cab-rows, 4))); }
  .cab-set-controls { flex: none; overflow: visible; padding: 14px 16px 20px; }
  .cab-opts { grid-template-columns: repeat(auto-fill, minmax(70px, 1fr)); }
}
@media (max-width: 480px) {
  .modal-root:has(> .modal.cab-dlg) { padding: 0; }
  .modal.cab-dlg { width: 100%; height: 100dvh; max-height: none; border-radius: 0; }
  .cab-set-head { padding: 12px 52px 12px 16px; }
  .cab-set-foot { padding: 10px 16px calc(12px + env(safe-area-inset-bottom)); }
}

/* Sealed product with no photo: its box, the set across the top, the kind's picture on the front. */
.cab-pkg[data-pkg="sealed"] { padding: 9% 8%; border-radius: 3px; }
.cab-pkg[data-pkg="sealed"] .cab-pkg-head { text-align: center; }
.cab-pkg[data-pkg="sealed"] .cab-pkg-name { text-align: center; }
