/* ============================================================
   LOAD OUT — visual foundation.

   Load Out is a sub-brand of CueStudio, not a separate brand: it
   shares CueStudio's MATERIAL and diverges only in MOTIF.

   Material (from CueStudio's web foundation, cuestudio.show):
     plate      #0a0a0a -> #121211 -> #191918   warm-black, not blue-black
     text ramp  #f0efed / #b5b3b1 / #8b8d8b
     pour       linear-gradient(148deg,#f69509,#ea7207,#d64a06)
     go/danger  #3ec46d / #e35d52
     spacing    --s1..--s8      radii 6/10/16      system font stack

   Motif (Load Out's own licence, and the whole of it):
     - road-case corner brackets, on three containers only:
       the topbar, the board frame, and the Bronze laminate
     - safety yellow #f5b700 as the single accent, which sits a
       hair off CueStudio's own #f5a121 and reads as the same family

   No webfonts: this ships inside a native app that runs in venues
   with no internet. A font that fails to load is a broken identity
   at showtime.
   ============================================================ */

:root{
  /* ---- surfaces: the plate ---- */
  --bg-deck:#0a0a0a;
  --panel:#191918;
  --panel-2:#121211;
  --inset:#070707;
  --line:#26262a;
  --line-strong:#383838;

  /* ---- text ramp. --text-faint is NOT a text colour: hairlines
         and disabled affordances only. ---- */
  --text:#f0efed;
  --text-second:#b5b3b1;
  --text-muted:#8b8d8b;
  --text-faint:#55565a;

  /* ---- one accent ---- */
  --accent:#f5b700;
  --accent-bright:#ffcf3d;
  --accent-dim:#8a6708;
  --accent-glow:rgba(245,183,0,.16);
  --on-accent:#140f00;

  /* The pour is spent exactly once, on the Bronze laminate. It is
     the emotional peak, so it is the only saturated surface here. */
  --pour:linear-gradient(148deg,#f69509 0%,#ea7207 42%,#d64a06 100%);

  --go:#3ec46d;
  --danger:#e35d52;

  /* ---- warehouse floor ---- */
  --floor:#1c1c1a;
  --floor-line:#242422;
  --wall:#060606;
  --wall-stripe:#131312;

  /* ---- case types. Colour is the fast channel; SHAPE (below) and
         the 01-04 numeral are the ones that survive colour blindness. ---- */
  --t1:#e8a93c; --t1-face:#c9913a;
  --t2:#4cc0b0; --t2-face:#3d9e91;
  --t3:#a884dd; --t3-face:#8a68bb;
  --t4:#e8677a; --t4-face:#c25264;

  /* ---- spacing: one scale ---- */
  --s1:.25rem; --s2:.5rem;  --s3:.75rem; --s4:1rem;
  --s5:1.5rem; --s6:2rem;   --s7:3rem;   --s8:4rem;

  --radius-sm:6px;
  --radius:10px;
  --radius-lg:16px;

  --page:1120px;
  --column:820px;

  --font-sans:ui-sans-serif,-apple-system,"SF Pro Text","Segoe UI",
              "Helvetica Neue",Arial,sans-serif;

  /* Numeric readouts use the same face with tabular figures rather
     than a monospace costume. */
  --cols:9;
  --tile:52px;
  --step:53px;

  /* A strong ease-out: movement starts on the keypress, not after it.
     The old (.22,.61,.36,1) spent its first frames barely moving,
     which is exactly when the player is watching. */
  --ease:cubic-bezier(.23,1,.32,1);
}

*,*::before,*::after{ box-sizing:border-box; }

html{ -webkit-text-size-adjust:100%; }

html,body{
  margin:0; padding:0;
  background-color:var(--bg-deck); color:var(--text);
  font-family:var(--font-sans);
  font-size:16px; line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
body{ display:flex; justify-content:center; min-height:100vh; }

/* ---- venues ----
   Each gig lights the room it is played in. The plate stays the
   plate; what changes is a wash of the venue's own light falling
   from the top of the page, the way a site's light spills past the
   edge of the stage. The accent never changes: safety yellow is the
   crew's colour, not the venue's. */
body{
  --atmo:transparent;
  background-image:radial-gradient(120% 70% at 50% -12%, var(--atmo) 0%, transparent 62%);
  background-attachment:fixed;
}
body[data-site="warehouse"]{ --atmo:rgba(150,170,195,.10); --site-mark:#7f8ea3; }
body[data-site="festival"] { --atmo:rgba(255,190,120,.10); --site-mark:#c99a5e; }
body[data-site="arena"]    { --atmo:rgba(140,175,235,.13); --site-mark:#7a98c8; }
body[data-site="theatre"]  { --atmo:rgba(220,120,70,.13);  --site-mark:#c07a4c; }
body[data-site="desert"]   { --atmo:rgba(240,130,90,.15);  --site-mark:#d0835c; }
body[data-site="ice"]      { --atmo:rgba(150,210,240,.14); --site-mark:#86bcd6; }
body[data-site="stadium"]  { --atmo:rgba(120,200,140,.10); --site-mark:#78b087; }
body[data-site="ballroom"] { --atmo:rgba(200,80,100,.14);  --site-mark:#c06a7c; }
body[data-site="city"]     { --atmo:rgba(110,130,255,.14); --site-mark:#8a96d8; }

h1,h2,h3{ margin:0; line-height:1.14; letter-spacing:-.022em; font-weight:600; }

.app{
  width:100%; max-width:var(--page);
  padding:var(--s5) var(--s4) var(--s8);
  display:flex; flex-direction:column; gap:var(--s4);
}

/* Menu, editor and the reading surfaces stay in a narrow column;
   the play screen gets the full page so wide boards fit. */
.column{ width:100%; max-width:var(--column); margin-inline:auto; }

.visually-hidden{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

:focus-visible{
  outline:2px solid var(--accent);
  outline-offset:2px;
  border-radius:3px;
}

.tnum{ font-variant-numeric:tabular-nums; }

.icon{ width:1em; height:1em; display:block; }

/* ---- motif: road-case corner brackets. Three containers only. ---- */
.bracketed{ position:relative; }
.bracketed .tl,.bracketed .tr,.bracketed .bl,.bracketed .br{
  position:absolute; width:12px; height:12px;
  border:2px solid var(--accent); pointer-events:none;
}
.bracketed .tl{ top:-3px; left:-3px;  border-right:none; border-bottom:none; border-top-left-radius:var(--radius-sm); }
.bracketed .tr{ top:-3px; right:-3px; border-left:none;  border-bottom:none; border-top-right-radius:var(--radius-sm); }
.bracketed .bl{ bottom:-3px; left:-3px;  border-right:none; border-top:none; border-bottom-left-radius:var(--radius-sm); }
.bracketed .br{ bottom:-3px; right:-3px; border-left:none;  border-top:none; border-bottom-right-radius:var(--radius-sm); }

/* ================= TOPBAR ================= */
.topbar{
  display:flex; align-items:center; justify-content:space-between; gap:var(--s4);
  padding:var(--s3) var(--s4);
  background:var(--panel); border:1px solid var(--line);
  border-radius:var(--radius);
}
.brand{ font-size:1.0625rem; font-weight:700; letter-spacing:-.02em; }
.brand span{ color:var(--accent); }
.nav{ display:flex; gap:var(--s2); flex-wrap:wrap; }
.nav button{
  display:inline-flex; align-items:center; min-height:44px;
  background:transparent; border:1px solid var(--line); color:var(--text-muted);
  font-family:inherit; font-size:.8125rem; font-weight:500;
  padding:var(--s2) var(--s3); border-radius:var(--radius-sm);
  cursor:pointer; user-select:none;
  transition:color .15s ease, border-color .15s ease, transform .16s var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .nav button:hover{ border-color:var(--line-strong); color:var(--text); }
}
.nav button[aria-current="page"]{ border-color:var(--accent); color:var(--accent); }

/* ================= SCREENS / MENU ================= */
.screen{ display:none; flex-direction:column; gap:var(--s4); }
.screen.active{ display:flex; }

.menu-top{ display:flex; align-items:baseline; justify-content:space-between; gap:var(--s3); flex-wrap:wrap; }
.dept-label{ font-size:.875rem; color:var(--text-muted); margin:0; }
.dept-stack{ display:flex; flex-direction:column; gap:var(--s6); }
.dept{ display:flex; flex-direction:column; gap:var(--s3); }
/* Each gig's heading carries a short rule in its venue's light. */
.dept .dept-label{ display:flex; align-items:center; gap:var(--s2); }
.dept .dept-label::before{
  content:""; width:var(--s4); height:3px; border-radius:2px; flex:none;
  background:var(--mark, var(--text-faint));
}
.dept[data-site="warehouse"]{ --mark:#7f8ea3; }
.dept[data-site="festival"] { --mark:#c99a5e; }
.dept[data-site="arena"]    { --mark:#7a98c8; }
.dept[data-site="theatre"]  { --mark:#c07a4c; }
.dept[data-site="desert"]   { --mark:#d0835c; }
.dept[data-site="ice"]      { --mark:#86bcd6; }
.dept[data-site="stadium"]  { --mark:#78b087; }
.dept[data-site="ballroom"] { --mark:#c06a7c; }
.dept[data-site="city"]     { --mark:#8a96d8; }
.dept-blurb{ margin:calc(var(--s2) * -1) 0 0; font-size:.875rem; color:var(--text-second); }
.pass-badge{
  font-size:.75rem; font-weight:600; letter-spacing:.02em;
  color:var(--text-muted); border:1px solid var(--line);
  padding:var(--s1) var(--s2); border-radius:var(--radius-sm);
}
.pass-badge.bronze{ border-color:var(--accent); color:var(--accent); background:var(--accent-glow); }

.card-grid{ display:grid; grid-template-columns:1fr 1fr; gap:var(--s3); }
@media(max-width:560px){ .card-grid{ grid-template-columns:1fr; } }

.wo-card{
  display:block; width:100%; text-align:left;
  background:var(--panel); border:1px solid var(--line);
  border-radius:var(--radius); padding:var(--s3) var(--s4);
  color:inherit; font:inherit; cursor:pointer;
  transition:border-color .15s ease, background .15s ease, transform .16s var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .wo-card:hover:not(:disabled){ border-color:var(--line-strong); background:#1c1c1b; }
}
.wo-card .num{
  display:flex; align-items:center; gap:var(--s2);
  font-size:.75rem; font-weight:600; color:var(--text-muted);
  font-variant-numeric:tabular-nums;
}
.wo-card .num .cleared{ color:var(--go); display:flex; }
.wo-card .num .cleared .icon{ width:.9rem; height:.9rem; }
.wo-card h3{ font-size:1.0625rem; margin:var(--s1) 0 var(--s2); }
.wo-card p{ margin:0 0 var(--s3); font-size:.875rem; color:var(--text-second); line-height:1.45; }
.wo-card .foot{
  display:flex; justify-content:space-between; gap:var(--s2);
  font-size:.75rem; color:var(--text-muted); font-variant-numeric:tabular-nums;
}
.wo-card .foot .best{ color:var(--accent); }
.wo-card:disabled{ opacity:.5; cursor:not-allowed; }
.wo-card:disabled .lockline{ display:flex; align-items:center; gap:var(--s1); }

/* ================= PLAY SCREEN =================
   Only the board is allowed the full page width; the chrome stays in
   the reading column so a 7-wide Work Order doesn't sit marooned. */
#screenPlay > *:not(.board-wrap){ width:100%; max-width:var(--column); margin-inline:auto; }

.ticket{
  display:flex; justify-content:space-between; align-items:flex-start;
  gap:var(--s4); flex-wrap:wrap;
  background:var(--panel); border:1px solid var(--line);
  border-radius:var(--radius); padding:var(--s3) var(--s4);
}
.ticket h2{ font-size:1.0625rem; }
.ticket .wo-no{ font-size:.75rem; font-weight:600; color:var(--accent); font-variant-numeric:tabular-nums; }
.ticket .concept{ font-size:.875rem; color:var(--text-second); margin-top:var(--s1); max-width:52ch; }
.ticket .bench{ text-align:right; font-size:.8125rem; color:var(--text-muted); font-variant-numeric:tabular-nums; }
.ticket .bench strong{ display:block; color:var(--text); font-size:1rem; font-weight:600; }

.hud{ display:flex; align-items:center; justify-content:space-between; gap:var(--s3); flex-wrap:wrap; }
.stat-row{ display:flex; gap:var(--s2); }
.stat-box{
  background:var(--panel); border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:var(--s2) var(--s3); text-align:center; min-width:76px;
}
.stat-box .label{ font-size:.6875rem; color:var(--text-muted); }
.stat-box .value{ font-size:1.125rem; font-weight:600; font-variant-numeric:tabular-nums; }
.stat-box .value.warn{ color:var(--accent); }
#statCurfewBox .value.warn{ color:var(--danger); }
.stat-box[hidden]{ display:none; }

/* Department chips under the ticket: which number is which kit. */
.gear-legend{ display:flex; flex-wrap:wrap; gap:var(--s2); margin:var(--s2) 0 0; }
.gear-legend[hidden]{ display:none; }
.gear-chip{
  display:inline-flex; align-items:center; gap:var(--s2);
  font-size:.8125rem; color:var(--text-second); font-variant-numeric:tabular-nums;
  border:1px solid var(--line); border-radius:var(--radius-sm); padding:2px var(--s2);
}
.gear-chip .swatch{ width:11px; height:11px; background:var(--bay); flex:none; }
.gear-chip .swatch.shape-1{ border-radius:2px; }
.gear-chip .swatch.shape-2{ border-radius:50%; }
.gear-chip .swatch.shape-3{ clip-path:polygon(50% 0,100% 28%,100% 72%,50% 100%,0 72%,0 28%); }
.gear-chip .swatch.shape-4{ clip-path:polygon(28% 0,72% 0,100% 28%,100% 72%,72% 100%,28% 100%,0 72%,0 28%); }

.btn-row{ display:flex; gap:var(--s2); flex-wrap:wrap; }
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--s2);
  min-height:44px; padding:var(--s2) var(--s4);
  font-family:inherit; font-size:.8125rem; font-weight:600;
  background:transparent; border:1px solid var(--line-strong); color:var(--text-second);
  border-radius:var(--radius-sm); cursor:pointer; user-select:none;
  transition:color .15s ease, border-color .15s ease, background .15s ease, transform .16s var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .btn:hover:not(:disabled){ color:var(--text); border-color:var(--text-muted); background:#1c1c1b; }
}
.btn:disabled{ opacity:.4; cursor:not-allowed; }
.btn .icon{ width:1.05rem; height:1.05rem; }
.btn.primary{
  background:var(--accent); border-color:var(--accent); color:var(--on-accent);
}
.btn.danger{ border-color:var(--danger); color:var(--danger); }
@media (hover:hover) and (pointer:fine){
  .btn.primary:hover:not(:disabled){ background:var(--accent-bright); border-color:var(--accent-bright); color:var(--on-accent); }
  .btn.danger:hover:not(:disabled){ background:var(--danger); border-color:var(--danger); color:#1a0605; }
}
.btn.icon-only{ padding:var(--s2); min-width:44px; }

/* Press feedback: the control gives under the finger before the
   click resolves. Cards are bigger, so they give less. */
.btn:active:not(:disabled),
.nav button:active,
.office-grid button:active,
.pswatch:active{ transform:scale(.97); }
.wo-card:active:not(:disabled){ transform:scale(.985); }

.status-line{
  min-height:1.25rem; margin:0; font-size:.875rem; color:var(--text-muted);
  display:flex; align-items:center; gap:var(--s2);
}
.status-line.good{ color:var(--go); }
.status-line.bad{ color:var(--accent-bright); }
.status-line.fatal{ color:var(--danger); font-weight:600; }

/* ---- board ----
   `safe center` is load-bearing: a plain `center` on an overflowing
   flex item pushes content past the scroll origin, where scrollLeft
   clamps at 0 and it can never be reached. */
.board-wrap{
  display:flex; justify-content:flex-start; justify-content:safe center;
  overflow-x:auto; overflow-y:hidden; padding-block:var(--s1);
}
.board-frame{
  background:var(--panel-2); border:1px solid var(--line);
  border-radius:var(--radius); padding:var(--s2); flex:0 0 auto;
}
.board,.ed-board{
  /* --cols is set inline per board by render.js / editor.js. Declaring
     --tile HERE is load-bearing: on :root it would resolve var(--cols)
     against :root's own value and every board would size identically. */
  --tile:clamp(26px, calc((min(100vw, var(--page)) - 5rem) / var(--cols)), 52px);
  --step:calc(var(--tile) + 1px);
}
.board{ position:relative; }
.board-grid{ display:grid; gap:1px; background:var(--line); }
.tile{ width:var(--tile); height:var(--tile); position:relative; }
.tile.wall{
  background:repeating-linear-gradient(45deg,var(--wall) 0 6px,var(--wall-stripe) 6px 12px);
}
.tile.floor{ background:var(--floor); box-shadow:inset 0 0 0 1px var(--floor-line); }

/* Truck floor: ribbed deck, a step lighter than the yard. Tail lift:
   a hazard-edged plate whose chevron points the one way a case can
   ride it. Shared with the Workshop's swatches. */
.tile.truck, .pswatch.truck{
  background:repeating-linear-gradient(90deg,#262624 0 3px,#1e1e1c 3px 7px);
}
/* The hazard edge is on the board only: on a swatch it reads as the
   selected state. */
.tile.lift{ box-shadow:inset 0 0 0 2px var(--accent-dim); }
.tile.ice, .pswatch.ice{
  background:linear-gradient(135deg,#9fb8c6 0%,#d8e6ee 45%,#a9c2d0 100%);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.25);
}
.lift::after{
  content:""; position:absolute; inset:32%;
  border-top:3px solid var(--accent); border-left:3px solid var(--accent);
  transform:translateY(18%) rotate(45deg);
}
.lift-down::after{ transform:translateY(-18%) rotate(225deg); }
.lift-left::after{ transform:translateX(18%) rotate(-45deg); }
.lift-right::after{ transform:translateX(-18%) rotate(135deg); }

/* Bay markers and case tokens share a per-type SHAPE. This is the
   channel that survives colour blindness at any tile size — the
   numeral alone was 9px and drawn in the very hue it disambiguated. */
.case-token.shape-1,.chip.shape-1,.bay-chip.shape-1{ border-radius:2px; }
.case-token.shape-2,.chip.shape-2,.bay-chip.shape-2{ border-radius:50%; }
.case-token.shape-3,.chip.shape-3,.bay-chip.shape-3{ clip-path:polygon(50% 0,100% 28%,100% 72%,50% 100%,0 72%,0 28%); }
.case-token.shape-4,.chip.shape-4,.bay-chip.shape-4{ clip-path:polygon(28% 0,72% 0,100% 28%,100% 72%,72% 100%,28% 100%,0 72%,0 28%); }

.marker{
  position:absolute; inset:12%;
  border:2px dashed var(--bay); color:var(--bay);
  border-radius:3px;
  display:flex; align-items:center; justify-content:center;
}
/* The shape silhouette sits inside the bay outline rather than
   clipping it: clip-path on a dashed border cuts the dashes into an
   unreadable smear. The token itself is clipped, where a solid fill
   takes the shape cleanly. */
.marker::before{
  content:""; position:absolute; inset:16%;
  background:var(--bay); opacity:.2;
}
.marker.shape-1::before{ border-radius:2px; }
.marker.shape-2::before{ border-radius:50%; }
.marker.shape-3::before{ clip-path:polygon(50% 0,100% 28%,100% 72%,50% 100%,0 72%,0 28%); }
.marker.shape-4::before{ clip-path:polygon(28% 0,72% 0,100% 28%,100% 72%,72% 100%,28% 100%,0 72%,0 28%); }
.marker span{ position:relative; }
.marker.filled{ border-style:solid; }
.marker.filled::before{ opacity:.34; }
.marker span{
  font-size:max(11px, calc(var(--tile) * .24));
  font-weight:700; font-variant-numeric:tabular-nums; letter-spacing:-.02em;
}

.actors{ position:absolute; inset:0; pointer-events:none; }
.actor{
  position:absolute; top:0; left:0;
  width:var(--tile); height:var(--tile);
  transform:translate(calc(var(--c) * var(--step)), calc(var(--r) * var(--step)));
  transition:transform .16s var(--ease);
}

.case-token{
  position:absolute; inset:11%;
  background:var(--face); border:2px solid #0c0c0b;
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 2px 6px rgba(0,0,0,.5);
  /* Delayed by most of the slide, so a case turns "seated" as it
     lands in the bay rather than the instant it starts moving. */
  transition:border-color .12s ease .1s, box-shadow .12s ease .1s;
}
.case-token span{
  font-size:max(11px, calc(var(--tile) * .24));
  font-weight:700; color:rgba(8,6,2,.82);
  font-variant-numeric:tabular-nums; letter-spacing:-.02em;
}
.actor.seated .case-token{
  border-color:var(--accent);
  box-shadow:0 2px 6px rgba(0,0,0,.5), 0 0 0 2px var(--accent-glow);
}
.actor.wedged .case-token{
  border-color:var(--danger);
  box-shadow:0 2px 6px rgba(0,0,0,.5), 0 0 0 3px rgba(227,93,82,.35);
}
/* Both reactions play on the TOKEN, after the slide lands. On the
   actor they overrode its transform, so the case skipped the slide,
   teleported into the bay, then shook. `both` holds frame 0 through
   the delay so nothing flickers. */
.actor.pop .case-token{ animation:pop .22s var(--ease) .12s both; }
.actor.shake .case-token{ animation:shake .24s ease-in-out .12s both; }
@keyframes pop{ 0%{transform:scale(1);} 40%{transform:scale(1.12);} 100%{transform:scale(1);} }
@keyframes shake{
  0%,100%{ transform:translateX(0); }
  25%{ transform:translateX(-4px); }
  75%{ transform:translateX(4px); }
}
/* Restart is a reset, not a move: sliding every case home in a
   straight line would drag them through walls. */
.board.snap .actor{ transition:none; }

/* three.js board (scene3d.js). The canvas is sized from the same
   --step as the DOM grid; the height allows for the camera's tilt.
   The DOM grid is kept, visually hidden, as the screen-reader view. */
.board-canvas{ display:none; }
/* The 3D board isn't bound to the 52px tile cap: its frame takes the
   full page width and the board a height from its own proportions,
   capped so the floor never pushes the HUD off a laptop screen. The
   camera fits whatever box it gets. Sized from the frame (a size
   container) rather than 100vw, which counts the scrollbar and so
   overflowed into a horizontal scroll. */
/* margin-inline leaves room for the corner brackets, which sit 2px
   outside the frame and would otherwise scroll the wrap. */
.board-frame:has(> .board.three){ flex:1 1 auto; container-type:inline-size; margin-inline:2px; }
.board.three{
  width:100%;
  /* 24rem is roughly the header, ticket and HUD above the board on a
     laptop, so a tall Work Order still shows its whole floor without
     scrolling. */
  height:min(calc(100cqw * (var(--rows, 9) * .8 + .5) / var(--cols)), calc(100svh - 24rem));
  min-height:240px;
}
.board.three .board-canvas{
  display:block; width:100%; height:100%;
  cursor:pointer; touch-action:none; -webkit-tap-highlight-color:transparent;
}
.board.three .actors{ display:none; }
.board.three .board-grid{
  position:absolute; width:1px; height:1px; overflow:hidden;
  clip-path:inset(50%); white-space:nowrap;
}

/* forklift — the player token */
.forklift{ position:absolute; inset:8%; }
.forklift.left{ transform:scaleX(-1); }
.forklift span{ position:absolute; }
.forklift .body{ left:6%; top:44%; width:52%; height:34%;
  background:linear-gradient(var(--accent),#b98a00); border:2px solid #46443d; border-radius:3px; }
.forklift .cab{ left:26%; top:4%; width:36%; height:44%;
  border:3px solid #55534b; border-bottom:0; border-radius:5px 5px 0 0; }
.forklift .mast{ right:20%; top:0; width:8%; height:78%; background:#55534b; }
.forklift .forks{ right:-10%; top:66%; width:40%; height:8%; background:#6b6960; }
.forklift .tank{ left:0; top:46%; width:14%; height:28%;
  background:#d46a1f; border:2px solid #46443d; border-radius:4px; }
.forklift .wheel{ bottom:2%; width:20%; height:20%; border-radius:50%;
  background:#0a0a09; border:3px solid #4a4842; }
.forklift .wheel.one{ left:12%; } .forklift .wheel.two{ left:52%; }
.forklift .beacon{ left:38%; top:-8%; width:16%; height:12%;
  border-radius:4px 4px 1px 1px; background:var(--accent-bright); border:2px solid #46443d; }

.controls{
  display:flex; justify-content:center; gap:var(--s2); flex-wrap:wrap;
  font-size:.8125rem; color:var(--text-muted);
}
.controls kbd{
  background:var(--panel); border:1px solid var(--line-strong); border-bottom-width:2px;
  padding:1px 5px; border-radius:4px; color:var(--text-second);
  font-family:inherit; font-size:.75rem;
}

/* Q's hint — progressive disclosure, only offered once the player
   is past the optimal route. */
.ask-q{ display:none; }
.ask-q.available{ display:flex; }
.hint-note{
  border:1px solid var(--line); border-left:2px solid var(--accent);
  background:var(--panel); border-radius:var(--radius-sm);
  padding:var(--s3) var(--s4); font-size:.875rem; color:var(--text-second);
}
.hint-note strong{ color:var(--accent); font-weight:600; }

/* ================= OVERLAYS ================= */
.overlay{
  position:fixed; inset:0; background:rgba(6,6,6,.9);
  display:none; align-items:center; justify-content:center;
  z-index:30; padding:var(--s4); overflow:auto;
}
.overlay.show{ display:flex; opacity:1; transition:opacity .2s ease; }

/* Enter only. Close stays instant: the system is answering the
   player at that point, and nothing should stand between them and
   the board. Sheets aren't anchored to a trigger, so they scale
   from centre. */
.overlay.show .sheet{
  opacity:1; transform:none;
  transition:opacity .24s var(--ease), transform .24s var(--ease);
}
@starting-style{
  .overlay.show{ opacity:0; }
  .overlay.show .sheet{ opacity:0; transform:translateY(6px) scale(.97); }
}

.sheet{
  background:var(--panel-2); border:1px solid var(--line);
  border-radius:var(--radius-lg); padding:var(--s6);
  width:100%; max-width:420px; max-height:90vh; overflow:auto;
  position:relative;
}
.sheet.wide{ max-width:640px; }
.sheet h2{ font-size:1.375rem; margin-bottom:var(--s1); }
.sheet .sub{ font-size:.875rem; color:var(--text-muted); margin:0 0 var(--s5); }
.sheet .actions{ display:flex; gap:var(--s2); justify-content:flex-end; flex-wrap:wrap; margin-top:var(--s5); }
.sheet.center{ text-align:center; max-width:460px; }
.sheet.center .actions{ justify-content:center; }

/* The verification mark is a corner stamp on the card, not a label
   stacked above the heading. */
.stamp{
  position:absolute; top:var(--s4); right:var(--s4);
  display:flex; align-items:center; gap:var(--s1);
  font-size:.75rem; font-weight:600; color:var(--go);
}
.stamp .icon{ width:.95rem; height:.95rem; }

.result-line{
  font-size:.9375rem; color:var(--text-second);
  margin:var(--s2) 0 0; font-variant-numeric:tabular-nums;
}
.result-line .n{ color:var(--text); font-weight:600; }
.result-line.optimal{ color:var(--accent); font-weight:600; }

/* ---- the laminate: the one place the pour is spent ---- */
.credential{
  width:100%; margin:0 auto var(--s5); padding:var(--s5);
  text-align:left; border-radius:var(--radius);
  background:var(--pour);
  box-shadow:0 14px 34px rgba(0,0,0,.5);
  /* Near-black, not a warm brown: the pour's cold stop (#d64a06) is the
     worst case for a dark label, and #1a0d02 measured 4.39:1 there.
     This clears AA at both ends — 4.68 cold, 8.9 hot. */
  color:#050200;
  /* The one place motion is allowed to be a moment: it is seen once
     per career. It lands a beat after its sheet, then light runs
     across it once like a fresh laminate. */
  opacity:1; transform:none;
  transition:opacity .5s var(--ease) .14s, transform .5s var(--ease) .14s;
}
@starting-style{
  .overlay.show .credential{ opacity:0; transform:translateY(12px) scale(.96); }
}
.credential::after{
  content:""; position:absolute; inset:0; border-radius:inherit;
  pointer-events:none;
  background:linear-gradient(105deg, transparent 38%, rgba(255,240,210,.38) 50%, transparent 62%)
             no-repeat;
  background-size:260% 100%;
  background-position:120% 0;
  opacity:0;
}
.overlay.show .credential::after{ animation:sheen .9s ease-in-out .55s both; }
@keyframes sheen{
  0%{ background-position:120% 0; opacity:1; }
  100%{ background-position:-20% 0; opacity:1; }
}
/* Later laminates are metal, not the pour: the pour is spent once. */
.credential[data-rank="silver"]{ background:linear-gradient(148deg,#eceef0 0%,#bfc3c7 46%,#8e9399 100%); }
.credential[data-rank="gold"]{ background:linear-gradient(148deg,#efd894 0%,#cfa64a 46%,#9c7425 100%); }
.credential[data-rank="platinum"]{ background:linear-gradient(148deg,#f6f6f4 0%,#d6dadd 40%,#b3c0c9 72%,#e6e1ee 100%); }
.credential .credTop{ font-size:.75rem; letter-spacing:.04em; font-weight:700; }
.credential .credRank{ font-size:2rem; font-weight:700; letter-spacing:-.03em; margin:var(--s2) 0; }
.credential .credLine{ font-weight:600; margin:2px 0; font-size:.8125rem; }
.credential .credBottom{ margin-top:var(--s4); font-weight:700; letter-spacing:.04em; font-size:.75rem; }

/* ================= GATE ================= */
.app.locked{ display:none; }
.gate{
  position:fixed; inset:0; background:var(--bg-deck);
  display:flex; align-items:center; justify-content:center;
  z-index:100; padding:var(--s4);
  transition:opacity .4s var(--ease);
}
.gate.hidden{ opacity:0; pointer-events:none; }
.gate-card{
  background:var(--panel-2); border:1px solid var(--line);
  border-radius:var(--radius-lg); padding:var(--s7) var(--s6);
  text-align:center; max-width:400px; width:100%;
  transition:opacity .3s var(--ease);
}
.gate-brand{ font-size:1.25rem; font-weight:700; letter-spacing:-.02em; margin-bottom:var(--s5); }
.gate-brand span{ color:var(--accent); }
.gate-card h2{ font-size:1.5rem; margin-bottom:var(--s2); }
.gate-where{ font-size:.8125rem; color:var(--text-muted); margin:0 0 var(--s6); }
.gate-actions{ display:flex; gap:var(--s3); justify-content:center; }
.gate-actions .btn{ min-width:110px; }
.btn.gate-yes{ background:var(--go); border-color:var(--go); color:#04140a; }
@media (hover:hover) and (pointer:fine){
  .btn.gate-yes:hover{ background:#4fd67e; border-color:#4fd67e; color:#04140a; }
}
.gate-declined{ font-size:.9375rem; color:var(--text-second); }
.gate-declined p{ margin:0 0 var(--s5); }

/* ================= Q'S OFFICE ================= */
.office-grid{ display:grid; grid-template-columns:1fr 1fr; gap:var(--s2); }
@media(max-width:480px){ .office-grid{ grid-template-columns:1fr; } }
.office-grid button{
  background:var(--panel); border:1px solid var(--line); border-radius:var(--radius);
  color:var(--text); text-align:left; padding:var(--s4);
  font:inherit; cursor:pointer;
  transition:border-color .15s ease, background .15s ease, transform .16s var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .office-grid button:hover{ border-color:var(--line-strong); background:#1c1c1b; }
}
.office-grid button .icon{ width:1.25rem; height:1.25rem; color:var(--accent); margin-bottom:var(--s2); }
.office-grid button strong{ display:block; font-size:.9375rem; font-weight:600; }
.office-grid button em{
  font-style:normal; display:block; color:var(--text-muted);
  font-size:.8125rem; margin-top:2px; line-height:1.4;
}

.records-table{ width:100%; border-collapse:collapse; margin:var(--s3) 0 var(--s4); font-size:.875rem; }
.records-table th,.records-table td{ border-bottom:1px solid var(--line); padding:var(--s2); text-align:left; }
.records-table th{ color:var(--text-muted); font-size:.75rem; font-weight:600; }
.records-table td{ color:var(--text-second); }
.records-table td:last-child,.records-table th:last-child{ text-align:right; }
.records-table .rank-1 td{ color:var(--accent); font-weight:600; }
.records-table .score{ font-variant-numeric:tabular-nums; }
.records-table .empty{ color:var(--text-muted); text-align:center; padding:var(--s5); }

.field-row{ display:flex; gap:var(--s2); align-items:flex-end; }
.field-row label{ flex:1; font-size:.8125rem; color:var(--text-muted); display:block; }
input[type="text"],input[type="number"]{
  width:100%; margin-top:var(--s1);
  background:var(--inset); border:1px solid var(--line); border-radius:var(--radius-sm);
  color:var(--text); font-family:inherit; font-size:.9375rem;
  padding:var(--s2) var(--s3); min-height:44px;
}
input:focus-visible{ border-color:var(--accent); }

.pass-card{
  border:1px solid var(--line); border-radius:var(--radius);
  padding:var(--s5); background:var(--panel); text-align:left;
}
.pass-card.unlocked{ border-color:var(--accent); background:var(--accent-glow); }
.pass-card .pass-name{ font-size:1.125rem; font-weight:600; color:var(--accent); margin-bottom:var(--s2); }
.pass-card .icon{ width:1.5rem; height:1.5rem; color:var(--text-faint); margin-bottom:var(--s2); }
.pass-card .pass-line{ font-size:.875rem; color:var(--text-second); margin:2px 0; }

.ledger-grid{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:var(--s2); margin-bottom:var(--s3); }
@media(max-width:560px){ .ledger-grid{ grid-template-columns:1fr 1fr; } }
.ledger-group{ font-size:.75rem; color:var(--text-muted); margin:var(--s4) 0 var(--s2); font-weight:600; }
.ledger-item{ border:1px solid var(--line); border-radius:var(--radius-sm); background:var(--panel); padding:var(--s3); }
.ledger-item .ledger-label{ font-size:.6875rem; color:var(--text-muted); margin-bottom:var(--s1); }
.ledger-item .ledger-value{ font-size:1.125rem; font-weight:600; font-variant-numeric:tabular-nums; }

.notice-stack{ display:grid; gap:var(--s2); }
.notice-box{
  border:1px solid var(--line); border-radius:var(--radius-sm); background:var(--panel);
  padding:var(--s3) var(--s4); color:var(--text-second); font-size:.875rem; line-height:1.5;
}
.notice-box strong{ color:var(--accent); display:block; margin-bottom:var(--s1); font-weight:600; }
.notice-box .sig{ color:var(--text-muted); display:block; margin-top:var(--s2); }

/* ================= EDITOR ================= */
.editor-tools{
  display:flex; flex-wrap:wrap; gap:var(--s3); align-items:flex-end;
  background:var(--panel); border:1px solid var(--line); border-radius:var(--radius);
  padding:var(--s3) var(--s4);
}
.editor-tools label{ font-size:.75rem; color:var(--text-muted); }
.editor-tools .w-title{ flex:1; min-width:180px; }
.editor-tools .w-num input{ width:76px; }

.palette{
  display:flex; flex-wrap:wrap; gap:var(--s4);
  background:var(--panel); border:1px solid var(--line); border-radius:var(--radius);
  padding:var(--s3) var(--s4);
}
.palette fieldset{ border:0; margin:0; padding:0; }
.palette legend{ font-size:.6875rem; color:var(--text-muted); padding:0 0 var(--s2); font-weight:600; }
.palette .swatches{ display:flex; gap:var(--s2); flex-wrap:wrap; }
.pswatch{
  width:44px; height:44px; padding:0;
  border:1px solid var(--line); border-radius:var(--radius-sm);
  background:var(--floor); color:var(--text-second);
  display:flex; align-items:center; justify-content:center;
  cursor:pointer; font:inherit; font-size:.8125rem; font-weight:600;
  position:relative; transition:border-color .15s ease, transform .16s var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .pswatch:hover{ border-color:var(--line-strong); }
}
.pswatch[aria-pressed="true"]{ border-color:var(--accent); box-shadow:0 0 0 1px var(--accent); }
.pswatch.wall{ background:repeating-linear-gradient(45deg,var(--wall) 0 5px,var(--wall-stripe) 5px 10px); }
.pswatch .chip{ width:22px; height:22px; background:var(--face); border:2px solid #0c0c0b; }
.pswatch .bay-chip{ width:22px; height:22px; border:2px dashed var(--bay); }

.ed-board .tile{ cursor:crosshair; touch-action:none; }
.ed-board .tile.locked-edge{ cursor:not-allowed; }

.validate-result{
  font-size:.875rem; padding:var(--s3) var(--s4);
  border:1px solid var(--line); border-radius:var(--radius-sm); background:var(--panel);
  color:var(--text-muted);
}
.validate-result.ok{ color:var(--go); border-color:var(--go); }
.validate-result.bad{ color:var(--danger); border-color:var(--danger); }
.validate-result.busy{ color:var(--accent); border-color:var(--accent-dim); }

.export-box textarea{
  width:100%; min-height:150px; margin-bottom:var(--s2);
  background:var(--inset); border:1px solid var(--line); border-radius:var(--radius-sm);
  color:var(--text); font-family:ui-monospace,"SF Mono",Menlo,monospace;
  font-size:.8125rem; padding:var(--s3); resize:vertical;
}

.hint{ font-size:.875rem; color:var(--text-muted); line-height:1.5; }


/* ================= NARROW ================= */
@media (max-width:700px){
  .app{ padding:max(var(--s3), env(safe-area-inset-top)) var(--s3) var(--s6); gap:var(--s3); }

  /* Brand over nav: side-by-side wrapped the three nav buttons into a
     ragged two-row block beside a vertically-centred wordmark. */
  .topbar{ flex-direction:column; align-items:stretch; gap:var(--s3); }
  .nav{ display:grid; grid-template-columns:1fr 1fr; }
  .nav button{ justify-content:center; }
  .nav button:first-child{ grid-column:1 / -1; }

  /* The ticket stacks, and the benchmark becomes one compact line
     instead of a right-aligned block with a full-width gap above it. */
  .ticket{ flex-direction:column; gap:var(--s2); padding:var(--s3); }
  .ticket .bench{ text-align:left; display:flex; align-items:baseline; gap:var(--s2); }
  .ticket .bench strong{ display:inline; font-size:.9375rem; }

  /* Board above the fold: the HUD and controls move below it, so the
     first thing on screen after the ticket is the floor itself. */
  #screenPlay .ticket{ order:1; }
  #screenPlay .status-line{ order:2; }
  #screenPlay .board-wrap{ order:3; }
  #screenPlay .hud{ order:4; }
  #screenPlay .ask-q{ order:5; }
  #screenPlay .hint-note{ order:6; }
  #screenPlay .controls{ order:7; }
  #screenPlay .dpad{ order:3; }             /* right under the floor it drives */
  #screenPlay .touch-controls{ order:3; }   /* right under the floor it explains */

  .hud{ flex-direction:column; align-items:stretch; gap:var(--s2); }
  .stat-row{ display:grid; grid-template-columns:repeat(auto-fit, minmax(0, 1fr)); grid-auto-flow:column; }
  .stat-box{ min-width:0; }
  .btn-row{ display:grid; grid-template-columns:auto 1fr 1fr; }
  .btn{ padding:var(--s2) var(--s3); }
  #backToMenuBtn{ grid-column:1 / -1; }

  .sheet{ padding:var(--s5) var(--s4); }
  .controls{ font-size:.75rem; }
}

/* Touch devices get no hover state to lean on, so the keyboard legend
   is noise there. */
@media (hover:none){
  .controls{ display:none; }
}
.touch-controls{
  display:none; margin:0; text-align:center;
  font-size:.8125rem; color:var(--text-muted);
}
@media (hover:none){
  .touch-controls{ display:block; }
}

/* ---- d-pad: touch screens only ----
   A thumb-sized cross under the floor, with Undo in the corner where
   the other thumb rests. Pressing never selects, zooms or scrolls. */
.dpad{ display:none; }
@media (hover:none), (pointer:coarse){
  .dpad{
    display:grid; justify-content:center;
    grid-template-columns:repeat(3, 64px); grid-template-rows:repeat(3, 56px);
    grid-template-areas:". up ." "left . right" "undo down .";
    gap:var(--s2); margin:var(--s2) auto 0;
    touch-action:none; user-select:none; -webkit-user-select:none;
    -webkit-touch-callout:none; -webkit-tap-highlight-color:transparent;
  }
}
.dpad-btn{
  display:flex; align-items:center; justify-content:center;
  background:var(--panel); color:var(--text-second);
  border:1px solid var(--line-strong); border-radius:var(--radius);
  font:inherit; cursor:pointer; touch-action:none;
  transition:background .12s ease, color .12s ease, transform .12s var(--ease);
}
.dpad-btn .icon{ width:28px; height:28px; stroke-width:2; }
.dpad-btn.up{ grid-area:up; }
.dpad-btn.down{ grid-area:down; }
.dpad-btn.left{ grid-area:left; }
.dpad-btn.right{ grid-area:right; }
.dpad-btn.down .icon{ transform:rotate(180deg); }
.dpad-btn.left .icon{ transform:rotate(-90deg); }
.dpad-btn.right .icon{ transform:rotate(90deg); }
.dpad-btn.undo{ grid-area:undo; color:var(--text-muted); }
.dpad-btn.undo .icon{ width:22px; height:22px; stroke-width:1.75; }
.dpad-btn.held, .dpad-btn:active{
  background:var(--accent-glow); border-color:var(--accent); color:var(--accent); transform:scale(.96);
}
.dpad-btn:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

/* ================= PHONE ON ITS SIDE =================
   Turn a phone to landscape and the floor takes the whole screen. The
   chrome floats over it, see-through: the ticket and the numbers down
   the left, the d-pad on the right, messages along the bottom. The
   camera keeps the floor in the clear middle (--fit-x / --fit-y, read
   by scene3d.js) so nothing that matters sits under a control.
   Phones only: a tablet on its side has room for the normal layout. */
@media (orientation:landscape) and (max-height:600px) and (hover:none),
       (orientation:landscape) and (max-height:600px) and (pointer:coarse){
  html:has(#screenPlay.active), body:has(#screenPlay.active){ overflow:hidden; }
  body:has(#screenPlay.active) .topbar{ display:none; }
  body:has(#screenPlay.active) .app{ padding:0; }

  #screenPlay{ --glass:rgba(14,14,13,.5); --glass-line:rgba(255,255,255,.12); --side:168px; }
  #screenPlay > *:not(.board-wrap){ max-width:none; margin:0; }

  #screenPlay .board-wrap{ position:fixed; inset:0; z-index:1; padding:0; overflow:hidden; background:var(--bg-deck); }
  #screenPlay .board-frame{ border:0; border-radius:0; padding:0; margin:0; width:100%; height:100%; background:transparent; }
  #screenPlay .board-frame > .tl, #screenPlay .board-frame > .tr,
  #screenPlay .board-frame > .bl, #screenPlay .board-frame > .br{ display:none; }
  #screenPlay .board.three{ height:100%; min-height:0; --fit-x:.55; --fit-y:.92; }

  /* left column: ticket on top, numbers and buttons under it */
  #screenPlay .ticket, #screenPlay .hud{
    position:fixed; z-index:5; width:var(--side);
    left:max(var(--s2), env(safe-area-inset-left));
    background:var(--glass); border:1px solid var(--glass-line);
    -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
    border-radius:var(--radius);
  }
  #screenPlay .ticket{ top:var(--s2); padding:var(--s2) var(--s3); display:block; }
  #screenPlay .ticket h2{ font-size:.875rem; line-height:1.2; }
  #screenPlay .ticket .concept, #screenPlay .ticket .gear-legend{ display:none; }
  /* just "Optimal 169 moves": the long label wraps at this width */
  #screenPlay .ticket .bench{ text-align:left; font-size:0; margin:2px 0 0; color:var(--text-muted); }
  #screenPlay .ticket .bench::before{ content:"Optimal "; font-size:.6875rem; }
  #screenPlay .ticket .bench strong{ display:inline; font-size:.75rem; }

  #screenPlay .hud{ bottom:var(--s2); padding:var(--s2); flex-direction:column; align-items:stretch; gap:var(--s2); }
  #screenPlay .stat-row{ display:grid; grid-template-columns:repeat(auto-fit, minmax(0, 1fr)); gap:4px; }
  #screenPlay .stat-box{ min-width:0; padding:2px; background:transparent; border-color:var(--glass-line); }
  #screenPlay .stat-box .label{ font-size:.5625rem; }
  #screenPlay .stat-box .value{ font-size:.875rem; }
  #screenPlay .hud .btn-row{ display:grid; grid-template-columns:1fr 1fr; gap:4px; }
  #screenPlay .hud .btn{ min-height:36px; padding:0; font-size:0; background:transparent; border-color:var(--glass-line); }
  #screenPlay .hud .btn .icon{ width:18px; height:18px; }
  #screenPlay #undoBtn{ display:none; }   /* it lives on the d-pad */
  #screenPlay #backToMenuBtn{ grid-column:1 / -1; font-size:.75rem; min-height:32px; }

  /* right side: the d-pad, see-through */
  #screenPlay .dpad{
    position:fixed; z-index:5; margin:0; width:auto; justify-content:start;
    right:max(var(--s3), env(safe-area-inset-right)); top:50%; transform:translateY(-50%);
    grid-template-columns:repeat(3, 58px); grid-template-rows:repeat(3, 52px); gap:6px;
  }
  #screenPlay .dpad-btn{
    background:rgba(20,20,19,.32); border-color:rgba(255,255,255,.2); color:rgba(240,239,237,.85);
    -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px);
  }
  #screenPlay .dpad-btn.held, #screenPlay .dpad-btn:active{ background:rgba(245,183,0,.28); color:var(--accent); }

  /* messages along the bottom, between the two columns */
  #screenPlay .status-line{
    position:fixed; z-index:5; bottom:var(--s2); left:50%; transform:translateX(-50%);
    width:auto; max-width:calc(100vw - 2 * var(--side) - 4rem);
    padding:var(--s1) var(--s3); border-radius:var(--radius-sm); text-align:center;
    pointer-events:none;
  }
  #screenPlay .status-line:not(:empty){ background:var(--glass); -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px); }

  /* Ask Q and its answer float top centre when they're offered */
  #screenPlay .ask-q.available{ position:fixed; z-index:5; top:var(--s2); left:50%; transform:translateX(-50%); width:auto; }
  #screenPlay .ask-q .btn{ min-height:32px; background:var(--glass); border-color:var(--glass-line); }
  #screenPlay .hint-note:not([hidden]){
    position:fixed; z-index:5; top:var(--s2); left:50%; transform:translateX(-50%);
    width:min(420px, calc(100vw - 2 * var(--side) - 4rem));
    background:var(--glass); -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  }

  #screenPlay .controls, #screenPlay .touch-controls{ display:none; }

  #screenPlay .fs-tip:not([hidden]){
    display:flex; align-items:center; gap:var(--s2);
    position:fixed; z-index:6; top:var(--s2); left:50%; transform:translateX(-50%);
    width:auto; max-width:calc(100vw - 2 * var(--side) - 4rem);
    margin:0; padding:var(--s1) var(--s1) var(--s1) var(--s3);
    font-size:.75rem; color:var(--text-second); border-radius:var(--radius-sm);
    background:var(--glass); border:1px solid var(--glass-line);
    -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  }
  #screenPlay .fs-tip strong{ color:var(--text); font-weight:600; }
  #screenPlay .fs-tip button{
    flex:none; width:32px; height:32px; border:0; border-radius:var(--radius-sm);
    background:transparent; color:var(--text-muted); font-size:1.125rem; line-height:1; cursor:pointer;
  }
}
/* everywhere else the tip stays out of the way */
.fs-tip{ display:none; }

/* ================= MOTION ================= */
/* Reduced motion means less movement, not none. Things stop
   travelling, scaling and shaking; fades and colour changes stay,
   because they carry state without moving anything. */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{ animation:none !important; }
  .actor{ transition:none; }
  .btn:active:not(:disabled), .nav button:active, .office-grid button:active,
  .pswatch:active, .wo-card:active:not(:disabled){ transform:none; }
  .overlay.show .sheet, .credential{ transition-property:opacity; }
  @starting-style{
    .overlay.show .sheet, .overlay.show .credential{ transform:none; }
  }
}
