* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; overflow: hidden; background: #0d0906; -webkit-tap-highlight-color: transparent; } /* no tap flash: WebKit paints a dark square over whatever a finger touches for a moment (author, 2026-09-24, on the TestFlight build: "tapping UI shows a black highlight square for a split second"); the property is inherited, so every button and the canvas lose it */
body {
  font-family: "Times New Roman", Times, Georgia, serif;
  color: #ffffff;
  user-select: none; -webkit-user-select: none; touch-action: none; -webkit-touch-callout: none;
}
#app { position: fixed; inset: 0; }
#game { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* ------------------------------------------------------------- HUD */
#hud {
  position: absolute; top: calc(14px + env(safe-area-inset-top, 0px));
  left: env(safe-area-inset-left, 0px); right: env(safe-area-inset-right, 0px);
  display: flex; justify-content: center; gap: clamp(14px, 4vw, 42px);
  flex-wrap: wrap; pointer-events: none; padding: 0 10px;
  z-index: 4; /* the corner buttons ride above the title card's veil (z 3) */
}
/* the corner controls: one white translucent row in the top right —
   pause, retry, reading left to right (mute lives in the pause menu) */
/* the row, right to left: retry, pause, mute, dev — each a step (the box
   less the padding overlap) further in; "Skip?" beyond them all */
#hud { --hw: clamp(54px, 11vw, 78px); --hstep: calc(var(--hw) - 14px); }
#pause-btn, #retry-btn, #mute-btn, #dev-btn {
  position: fixed;
  top: calc(8px + env(safe-area-inset-top, 0px));
  width: var(--hw); height: var(--hw);
  background: none; border: none; padding: 10px;
  pointer-events: auto; cursor: pointer;
  opacity: 0.32;
  transition: opacity 0.15s ease;
}
#pause-btn:hover, #pause-btn:active,
#retry-btn:hover, #retry-btn:active,
#mute-btn:hover, #mute-btn:active,
#dev-btn:hover, #dev-btn:active { opacity: 0.65; }
#pause-btn svg, #retry-btn svg, #mute-btn svg, #dev-btn svg { display: block; width: 100%; height: 100%; fill: #ffffff; }
#mute-btn { right: calc(10px + env(safe-area-inset-right, 0px) + var(--hstep) * 2); padding: 13px; }
#dev-btn { right: calc(10px + env(safe-area-inset-right, 0px) + var(--hstep) * 3); padding: 15px; }
#mute-btn .slash { display: none; }
#mute-btn.muted .slash { display: block; }
#mute-btn.muted .waves { display: none; }
/* the pair sits shoulder to shoulder: the buttons' inner padding already
   keeps the glyphs apart, so the boxes overlap their padding for a SMALL
   visual gap (the loop still gets extra padding to even its heavier draw) */
#retry-btn { right: calc(10px + env(safe-area-inset-right, 0px)); padding: 15px; }
#pause-btn { right: calc(10px + env(safe-area-inset-right, 0px) + clamp(54px, 11vw, 78px) - 14px); }
/* the boxes overlap their padding (above), and where they overlap a tap went
   to the LATER sibling — the pause icon's right edge was Retry, which throws
   the level away (28 px of overlap on a phone, the layout audit of
   2026-10-12); the pause button lies on top, the harmless answer */
#pause-btn { z-index: 2; }
/* the mercy verb: "Skip?" appears after the third drop on a level — a word,
   not a glyph, in the same white as its neighbours. Desktop: to the LEFT of
   the pair, on their line; phone: UNDER the pair, right-aligned with it */
#skip-btn {
  position: fixed; /* placed under the pause button by placeSkip (2026-09-21); the CSS keeps the type and the tan */
  top: 0; left: 0;
  height: auto; line-height: 1; /* the box is the line: a var(--hw) box put 13 px of air over the glyphs */
  padding: 0 14px;
  background: none; border: none;
  font: 400 clamp(22px, 3.2vw, 28px)/1 "Times New Roman", Times, Georgia, serif;
  color: #d4651a; letter-spacing: 0.03em; /* the sausage's tan — the banner's lit colour (author, 2026-09-13) */
  pointer-events: auto; cursor: pointer;
  opacity: 0.32;
  transition: opacity 0.15s ease;
}
#skip-btn:hover, #skip-btn:active { opacity: 0.65; }
/* the verb's stages (author, 2026-09-13): it FADES in over 1 s, stands 3 s,
   then FLIES into the pause button (restored the same night: "as it was
   before") */
#skip-btn { opacity: 0; transition: opacity 1s ease, transform 0.7s cubic-bezier(0.5, 0, 0.8, 0.4); }
#skip-btn.shown { opacity: 1; } /* the tan at full strength — at the corner's 0.32 it read as a muddy brown on the grey (author, 2026-09-13: "UI not darkened") */
#skip-btn.shown:hover, #skip-btn.shown:active { opacity: 1; }
/* THE FLIGHT (back, author 2026-09-13 night): into the pause button's middle
   (--fx/--fy set by tickSkip), shrinking and fading over the same 0.7 s */
#skip-btn.fly { opacity: 0 !important; transform: translate(var(--fx, 0px), var(--fy, 0px)) scale(0.12); transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.5, 0, 0.8, 0.4); pointer-events: none; }
#pause-btn.got-skip { animation: got-skip 0.5s ease-out; }
@keyframes got-skip { 0% { transform: scale(1); } 40% { transform: scale(1.22); } 100% { transform: scale(1); } }
/* ...and its home from then on: above the level selection in the pause menu */
#pause-skip {
  background: none; border: none; cursor: pointer;
  font: 400 clamp(29px, min(6vw, 5.4vh), 44px)/1 "Times New Roman", Times, Georgia, serif; /* a size up to Bacon's (author, 2026-09-24): 29 px on a phone, was 22 */
  letter-spacing: 0.06em; color: #d4651a; padding: 6px 18px;
  opacity: 0.9; transition: opacity 0.15s ease, transform 0.15s ease;
  /* OUT OF THE FLOW, over the level selection (2026-09-29): in the column it
     pushed the nav down by half its height whenever it showed; centred by
     auto margins with max-content (left 50% would cap its box at half the
     width and a long "to skip …" line would sit off-centre) */
  position: absolute; left: 0; right: 0; bottom: calc(100% + clamp(2px, 2vh, 22px));
  width: max-content; max-width: 96vw; margin: 0 auto;
}
#nav-stack { position: relative; width: 100%; }
#pause-skip:hover, #pause-skip:active { opacity: 1; transform: scale(1.015); background: none; } /* a whisper of growth (author, 2026-09-13: "much more subtle"; 1.06 before) */
#pause-mute-btn .slash { display: none; }
#pause-mute-btn.muted .slash { display: block; }
#pause-mute-btn.muted .waves { display: none; }

/* on a phone the corner controls are the whole control surface — bigger,
   bolder, brighter, still one row across the top right */
@media (max-width: 700px) {
  #hud { --hw: 86px; --hstep: 58px; }
  #pause-btn, #retry-btn, #mute-btn, #dev-btn {
    width: 86px; height: 86px;
    padding: 16px;
    opacity: 0.5;
  }
  #mute-btn { padding: 19px; }
  #dev-btn { padding: 21px; }
  /* tighter still on the phone: boxes overlap deep into their padding,
     leaving only a whisper of a gap between glyphs */
  #retry-btn { right: calc(10px + env(safe-area-inset-right, 0px)); padding: 21px; }
  #pause-btn { right: calc(10px + env(safe-area-inset-right, 0px) + 58px); }
  #skip-btn {
    padding: 0 10px;
    font-size: 30px;
  }
  #skip-btn.shown { opacity: 1; }
}

/* the ?fps readout: display rate, game speed against the wall clock, worst frame */
#fps {
  position: fixed; left: 8px; top: calc(8px + env(safe-area-inset-top, 0px)); z-index: 40;
  font: 12px/1.4 ui-monospace, Menlo, monospace; letter-spacing: 0;
  color: #fff; background: rgba(0, 0, 0, 0.55); padding: 3px 7px; border-radius: 6px;
  pointer-events: none;
}

/* ------------------------------------------------------------- banner */
/* The title card. A veil in the sausage's own orange (#d4651a, the top
   stop of its skin texture) lies between the text and the stage: a plain,
   frank gradient, heavy at the foot of the screen and thin at the top.
   Both lines are white on it, unshadowed. */
#banner {
  position: absolute; inset: 0; z-index: 3; pointer-events: none;
  text-align: center;
  color: #ffffff;
  background: linear-gradient(to top, rgba(212, 101, 26, 0.85), rgba(212, 101, 26, 0.18));
  text-shadow: none;
  transition: none; /* the title CUTS in — the transition below governs the exit only */
}
/* "Food Hack #n": bold, big, high — halfway between the old title line
   (33%) and the foot of the corner buttons (~12% on a phone) */
#banner-hack {
  position: absolute; left: 0; right: 0; top: 21%;
  transform: translateY(-50%);
  font-size: clamp(38px, 7.2vw, 80px);
  font-weight: 700;
  letter-spacing: 0.08em;
}
/* the task, dead centre, ruled above and below — the rules stop a solid
   margin short of the screen's sides, and DRAW from the centre outward
   each time the card rises (the animation restarts with the :not(.hidden)
   match, since the card only ever hides through opacity) */
#banner-task {
  position: absolute; left: 14%; right: 14%; top: 50%;
  transform: translateY(-50%);
  padding: 0.38em 0;
  font-size: clamp(30px, 5.6vw, 66px);
  font-weight: 400;
  letter-spacing: 0.05em;
  line-height: 1.15;
}
#banner-task::before, #banner-task::after {
  content: ""; position: absolute; left: 0; right: 0; height: 2px;
  background: currentColor;
  transform: scaleX(0); transform-origin: 50% 50%;
}
#banner-task::before { top: 0; }
#banner-task::after { bottom: 0; }
#banner:not(.hidden) #banner-task::before,
#banner:not(.hidden) #banner-task::after { animation: rule-grow 0.85s cubic-bezier(0.2, 0.7, 0.2, 1) forwards; }
#banner.hidden #banner-task::before,
#banner.hidden #banner-task::after { transform: scaleX(1); } /* the fade-out keeps them drawn */
@keyframes rule-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
/* the player's first move: the veil goes at once, the text and its rules
   take the veil's own orange, and the whole card fades on the slow exit */
#banner.lit {
  background: none;
  color: #d4651a;
}
/* the global .hidden's display:none would cut the fade dead — the banner
   stays in layout (it's pointer-transparent) and leaves through opacity.
   The transition lives on the hidden state so only the way OUT is eased */
#banner.hidden { display: block !important; opacity: 0; transition: opacity 1.1s; } /* a fade and nothing else */

/* ------------------------------------------------------------- photoshoot */
#letterbox { position: absolute; inset: 0; pointer-events: none; z-index: 5; }
/* the photoshoot's backdrop: the sausage's own gradient (the title card's
   veil) rises behind the prints for the length of the ceremony */
#shoot-veil {
  position: absolute; inset: 0; pointer-events: none; z-index: 5;
  background: linear-gradient(to top, rgba(212, 101, 26, 0.85), rgba(212, 101, 26, 0.18));
  opacity: 0; transition: opacity 0.6s;
}
#shoot-veil.active { opacity: 1; }
/* the camera flash: every shutter, on the BACKDROP only — above the sausage
   veil (z 5), below the prints (7) and the shoot's verbs (8) */
#flash {
  position: absolute; inset: 0; pointer-events: none; z-index: 6;
  background: #fff; opacity: 0;
}
#letterbox .bar {
  position: absolute; left: 0; right: 0; height: 11%;
  background: #000;
  transition: transform 0.7s cubic-bezier(0.25, 0.8, 0.3, 1);
}
#letterbox .bar.top { top: 0; transform: translateY(-101%); }
#letterbox .bar.bottom { bottom: 0; transform: translateY(101%); }
#letterbox.active .bar { transform: translateY(0); }
/* ------------------------------------------------------------- the Glorp splash
   THE STUDIO IDENT ON THE LOADING CURTAIN (author, 2026-09-21): the 3.0 s CRT
   power-on from assets/glorp-splash/glorp-splash.html, scoped to
   #glorp-splash and laid INSIDE #loading-screen (absolute, over the emblem) so
   the curtain's fade and hide take it along; the tagline ("presents") and its
   Share Tech Mono are dropped — it was opt-in and off; Orbitron is self-hosted
   (Poki forbids the Google Fonts link). Every animation is held until
   splash.js adds `.on`, so the keyframes and the module's 3 s timer start
   together. Black on any theme: a black tube that powers on is the joke.
   Timeline: 0.10 beam on · 0.45 tube opens, head tears in · 1.05 wordmark
   stamps · 1.70 double blink · 2.45 collapse to a line, a dot, black · 3.00 done. */
@font-face { font-family: "Orbitron"; src: url("../assets/fonts/Orbitron%5Bwght%5D.ttf") format("truetype"); font-weight: 400 900; font-style: normal; font-display: block; }
#glorp-splash {
  --glorp: #39FF14; --glorp-deep: #1f9a0c; --void: #000000; --dur: 3s;
  position: absolute; inset: 0; z-index: 3; background: var(--void);
  display: grid; place-items: center; overflow: hidden;
  font-family: "Orbitron", "Eurostile", "Bank Gothic", ui-sans-serif, sans-serif; color: var(--glorp);
  cursor: none; user-select: none; -webkit-user-select: none; isolation: isolate;
}
#glorp-splash:not(.on) * { animation-play-state: paused !important; }
#glorp-splash .grid { position: absolute; inset: 0; background-image: radial-gradient(circle, rgba(57,255,20,.28) 1px, transparent 1.5px); background-size: 28px 28px; background-position: center; mask-image: radial-gradient(ellipse 60% 60% at 50% 50%, #000 0%, transparent 100%); -webkit-mask-image: radial-gradient(ellipse 60% 60% at 50% 50%, #000 0%, transparent 100%); opacity: 0; animation: gs-grid-life var(--dur) linear both; }
@keyframes gs-grid-life { 0% { opacity: 0; transform: scale(1.15); } 12% { opacity: .55; } 80% { opacity: .55; transform: scale(1); } 90% { opacity: 0; } 100% { opacity: 0; } }
#glorp-splash .vignette { position: absolute; inset: 0; pointer-events: none; background: radial-gradient(ellipse 70% 70% at 50% 50%, transparent 40%, rgba(0,0,0,.85) 100%); }
#glorp-splash .scanlines { position: absolute; inset: 0; pointer-events: none; z-index: 5; background: repeating-linear-gradient(0deg, rgba(0,0,0,0) 0 2px, rgba(0,0,0,.35) 2px 4px); mix-blend-mode: multiply; animation: gs-scan-drift 3s linear infinite; }
@keyframes gs-scan-drift { to { background-position: 0 4px; } }
#glorp-splash .flicker { position: absolute; inset: 0; pointer-events: none; z-index: 6; background: rgba(57,255,20,.04); animation: gs-flick .12s steps(2) infinite; mask-image: radial-gradient(ellipse 42% 32% at 50% 50%, #000 0%, transparent 100%); -webkit-mask-image: radial-gradient(ellipse 42% 32% at 50% 50%, #000 0%, transparent 100%); } /* THE FLICKER STAYS ON THE TUBE (author, 2026-09-24, the store app: "the green lighting flashing a bit, more around the screen edges, not the logo itself"): a full-frame 4% green blinking at 8 Hz over the vignette pulsed the black edges of an OLED phone, and the held ident (splash.js, THE HOLD) keeps it going for as long as the load takes; masked to the tube like the grid, the edges stay black */
@keyframes gs-flick { 50% { opacity: .35; } }
#glorp-splash .beam { position: absolute; left: 50%; top: 50%; height: 2px; width: 0; transform: translate(-50%, -50%); background: #d9ffd0; box-shadow: 0 0 6px 1px var(--glorp), 0 0 22px 4px rgba(57,255,20,.7), 0 0 60px 12px rgba(57,255,20,.35); border-radius: 2px; animation: gs-beam-on var(--dur) both; }
@keyframes gs-beam-on { 0% { width: 0; opacity: 1; } 3% { width: 0; opacity: 1; } 11% { width: min(78vw, 720px); opacity: 1; } 15% { width: min(78vw, 720px); opacity: 1; } 17% { opacity: 0; } 80% { opacity: 0; width: min(78vw, 720px); } 83% { opacity: 1; width: min(78vw, 720px); height: 2px; } 93% { opacity: 1; width: 8px; height: 2px; } 95% { opacity: 1; width: 6px; height: 6px; border-radius: 50%; } 100% { opacity: 0; width: 0; height: 0; } }
#glorp-splash .edge { position: absolute; left: 50%; top: 50%; height: 1px; width: min(78vw, 720px); background: var(--glorp); box-shadow: 0 0 8px 1px var(--glorp); transform: translate(-50%, -50%); opacity: 0; animation: gs-edge-travel var(--dur) both; }
#glorp-splash .edge.down { --dir: 1; } #glorp-splash .edge.up { --dir: -1; }
@keyframes gs-edge-travel { 0%, 15% { opacity: 0; transform: translate(-50%, -50%) translateY(0); } 16% { opacity: 1; } 28% { opacity: .9; transform: translate(-50%, -50%) translateY(calc(var(--dir) * min(30vh, 260px))); } 31% { opacity: 0; transform: translate(-50%, -50%) translateY(calc(var(--dir) * min(34vh, 300px))); } 100% { opacity: 0; } }
#glorp-splash .tube { position: relative; z-index: 2; display: grid; justify-items: center; gap: clamp(10px, 2vh, 22px); clip-path: inset(50% 0 50% 0); animation: gs-tube-open var(--dur) both; will-change: clip-path, transform; }
@keyframes gs-tube-open { 0%, 15% { clip-path: inset(50% 0 50% 0); transform: scaleX(1.06) scaleY(.4); filter: brightness(2.2); } 28% { clip-path: inset(-40% -40% -40% -40%); transform: scaleX(1) scaleY(1); filter: brightness(1.15); } 34% { filter: brightness(1); } 80% { clip-path: inset(-40% -40% -40% -40%); transform: scale(1); filter: brightness(1); } 82% { transform: scale(1.03); filter: brightness(1.8); } 86% { clip-path: inset(50% 0 50% 0); transform: scaleX(1.02) scaleY(.6); filter: brightness(3); } 100% { clip-path: inset(50% 0 50% 0); filter: brightness(3); } }
#glorp-splash .head { width: clamp(110px, 24vmin, 230px); aspect-ratio: 183 / 216; position: relative; animation: gs-head-glitch var(--dur) steps(1, end) both; }
#glorp-splash .head svg { width: 100%; height: 100%; display: block; overflow: visible; }
#glorp-splash .head .skin { fill: var(--glorp); }
#glorp-splash .head .eye { fill: var(--void); transform-box: fill-box; transform-origin: 50% 50%; animation: gs-blink var(--dur) both; }
@keyframes gs-blink { 0%, 55% { transform: scaleY(1); } 57% { transform: scaleY(.06); } 59% { transform: scaleY(1); } 62% { transform: scaleY(1); } 64% { transform: scaleY(.06); } 66% { transform: scaleY(1); } 100% { transform: scaleY(1); } }
#glorp-splash .head .ghost { position: absolute; inset: 0; opacity: 0; pointer-events: none; }
#glorp-splash .head .ghost.a { animation: gs-ghost-a var(--dur) steps(1, end) both; }
#glorp-splash .head .ghost.b { animation: gs-ghost-b var(--dur) steps(1, end) both; }
#glorp-splash .head .ghost svg .skin { fill: #c4ffb5; } #glorp-splash .head .ghost svg .eye { fill: transparent; }
@keyframes gs-head-glitch { 0%, 16% { transform: translate(0,0); } 17% { transform: translate(-6px, 2px) skewX(6deg); } 19% { transform: translate(5px, -1px) skewX(-4deg); } 21% { transform: translate(-3px, 0) skewX(2deg); } 23% { transform: translate(2px, 1px); } 25% { transform: translate(0,0); } 100% { transform: translate(0,0); } }
@keyframes gs-ghost-a { 0%, 16% { opacity: 0; } 17% { opacity: .7; transform: translate(-14px, 0); clip-path: inset(10% 0 55% 0); } 19% { opacity: .7; transform: translate(11px, 0); clip-path: inset(40% 0 20% 0); } 21% { opacity: .5; transform: translate(-7px, 0); clip-path: inset(65% 0 5% 0); } 23% { opacity: 0; } 100% { opacity: 0; } }
@keyframes gs-ghost-b { 0%, 17% { opacity: 0; } 18% { opacity: .6; transform: translate(12px, 0); clip-path: inset(0 0 70% 0); } 20% { opacity: .6; transform: translate(-9px, 0); clip-path: inset(30% 0 35% 0); } 22% { opacity: .4; transform: translate(6px, 0); clip-path: inset(75% 0 0 0); } 24% { opacity: 0; } 100% { opacity: 0; } }
#glorp-splash .word { position: relative; display: flex; gap: .06em; font-weight: 700; text-transform: lowercase; font-size: clamp(38px, 9vmin, 92px); letter-spacing: .14em; line-height: 1; text-shadow: 0 0 8px rgba(57,255,20,.8), 0 0 28px rgba(57,255,20,.45); }
#glorp-splash .word span { display: inline-block; opacity: 0; animation: gs-stamp var(--dur) cubic-bezier(.2,1.4,.3,1) both; animation-delay: calc(var(--i) * 55ms); }
@keyframes gs-stamp { 0%, 35% { opacity: 0; transform: translateY(.55em) scaleY(1.6); } 41% { opacity: 1; transform: translateY(-.06em) scaleY(.92); } 45% { transform: translateY(0) scaleY(1); } 100% { opacity: 1; transform: translateY(0); } }
#glorp-splash .word::after { content: ""; position: absolute; left: -10%; right: -10%; top: -60%; bottom: -60%; background: radial-gradient(ellipse 22% 55% at 50% 50%, rgba(255,255,255,.5), rgba(57,255,20,.15) 55%, transparent 75%); opacity: 0; pointer-events: none; animation: gs-leak var(--dur) both; }
@keyframes gs-leak { 0%, 45% { opacity: 0; transform: translateX(-45%); } 48% { opacity: 1; } 57% { opacity: 0; transform: translateX(45%); } 100% { opacity: 0; } }
#glorp-splash.done { animation: gs-bye .25s both; pointer-events: none; }
@keyframes gs-bye { to { opacity: 0; visibility: hidden; } }
@media (prefers-reduced-motion: reduce) { #glorp-splash .head, #glorp-splash .head .ghost, #glorp-splash .flicker, #glorp-splash .scanlines { animation: none !important; } #glorp-splash .head .ghost { display: none; } }

/* ------------------------------------------------------------- screens */
#loading-screen,
#title-screen, #win-screen, #credits, #pause-screen, #settings-screen, #gallery-screen, #radio-screen, #wear-screen {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 26px; text-align: center;
  /* every menu wears the same grey wash — no dark curtains, no blur */
  background: rgba(125, 125, 125, 0.78);
  color: #ffffff; z-index: 10;
}
/* THE BANNER'S ROOM (the store apps only, 2026-09-22): src/native.js writes
   the anchored AdMob banner's height as --ad-h on the root (and
   body.ad-banner) — the plugin lays the banner OVER the webview on iOS and
   Android, on the safe area's bottom edge, so the page keeps its height and
   every bottom-anchored rule adds var(--ad-h, 0px) on top of
   env(safe-area-inset-bottom): the pause menu's corners and its padding,
   the look / radio / wardrobe panels, the shoot's prints and verbs, the
   guide, the cage hint, the mini-games, the scrolling credits and gallery.
   Unset on the web (Poki), and removed the moment the banner goes, so
   everything stands where it stood before. */
#title-screen, #win-screen { padding-bottom: var(--ad-h, 0px); }
#title-screen h1, #win-screen h1, #pause-screen h1 {
  font-size: clamp(56px, 10vw, 128px);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: 0.14em;
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.9);
}
#title-screen h1 span {
  display: block;
  font-size: 0.22em;
  font-style: italic;
  letter-spacing: 0.55em;
  margin-top: 0.6em;
  opacity: 0.9;
}
.rule {
  width: min(340px, 60vw);
  height: 1px;
  background: rgba(255, 255, 255, 0.55);
}
.tag { font-size: 19px; font-style: italic; opacity: 0.85; letter-spacing: 0.04em; }
.hint { font-size: 14px; opacity: 0.55; font-variant: normal; letter-spacing: 0.22em; }

/* ------------------------------------------------------------- buttons */
button {
  font-family: inherit;
  font-weight: 700;
  font-size: 19px;
  letter-spacing: 0.32em;
  text-indent: 0.32em; /* balance the letter-spacing */
  color: #ffffff;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.85);
  border-radius: 0;
  padding: 15px 46px;
  cursor: pointer;
  transition: background 0.18s, color 0.18s;
}
button:hover { background: #ffffff; color: #0d0906; }
button.linkish {
  border: none; padding: 4px; font-weight: 400; font-size: 13px; font-style: italic;
  letter-spacing: 0.1em; text-indent: 0; opacity: 0.65; text-decoration: underline;
  text-underline-offset: 4px;
}
button.linkish:hover { background: transparent; color: #ffffff; opacity: 1; }

/* THE LOADING SCREEN (2026-09-20, night): the game's own grey (the white
   theme's light when the body wears it), the wordmark small, the village
   sausage drawing itself on and cooking to the tan as the assets land, steam
   off the grill marks, the hint's dots cycling; it fades out over 0.4 s once
   the drawing has had its 1.4 s (finishLoading) */
#loading-screen { z-index: 30; background: #5b6156; color: #ffffff; gap: 18px; transition: opacity 0.4s ease; }
#loading-screen.lifting { opacity: 0; pointer-events: none; }
.bg-white #loading-screen { background: #e6e6e6; color: #2b2b2b; }
body.native #loading-screen { background: #000000; } /* THE STORE APPS OPEN ON BLACK (author, 2026-09-24: "grey flashes just before the Glorp splash"): the launch screen, the web view and the curtain are the ident's own black; the curtain's emblem and steam never show there (the ident holds until the game has loaded), and when the tube collapses the black lifts straight onto the game */
body.native #loading-screen > :not(#glorp-splash) { visibility: hidden; }
#loading-screen h1 { font-size: clamp(26px, 4.6vw, 44px); font-weight: 400; line-height: 1.02; letter-spacing: 0.2em; text-shadow: 0 2px 12px rgba(0, 0, 0, 0.25); margin: 0 0 22px; } /* room under the wordmark for the steam, which rises 34 px past the emblem's top (it rose into the title on the desktop, seen) */
#loading-screen .hint { font-size: clamp(15px, 2.4vw, 19px); letter-spacing: 0.18em; font-style: italic; opacity: 0.85; }
#loading-screen .hint::after { content: ""; display: inline-block; width: 1.6em; text-align: left; animation: load-dots 1.6s steps(4, end) infinite; }
@keyframes load-dots { 0% { content: ""; } 25% { content: "."; } 50% { content: ".."; } 75% { content: "..."; } 100% { content: ""; } }
#load-emblem { width: min(62vw, 320px); animation: load-rock 3.2s ease-in-out infinite; transform-origin: 50% 70%; filter: drop-shadow(0 4px 14px rgba(0, 0, 0, 0.25)); }
#load-emblem svg { display: block; width: 100%; height: auto; overflow: visible; }
@keyframes load-rock { 0%, 100% { transform: rotate(-3deg) translateY(0); } 50% { transform: rotate(3deg) translateY(-6px); } }
/* the draw-on: every stroke runs its own length (pathLength 1), the outline first, the ties, then the three grill marks one after another */
#load-emblem .ink polygon, #load-emblem .ink polyline { stroke-dasharray: 1; stroke-dashoffset: 1; animation: load-draw 0.7s ease-out forwards; }
#load-emblem .ink .d0 { animation-duration: 0.9s; }
#load-emblem .ink .d1 { animation-delay: 0.55s; animation-duration: 0.35s; }
#load-emblem .ink .d2 { animation-delay: 0.85s; animation-duration: 0.25s; }
#load-emblem .ink .d3 { animation-delay: 1.0s; animation-duration: 0.25s; }
#load-emblem .ink .d4 { animation-delay: 1.15s; animation-duration: 0.25s; }
@keyframes load-draw { to { stroke-dashoffset: 0; } }
/* the cook: the tan fill under the ink, clipped to the loaded fraction; it arrives with the drawing */
#load-emblem .cook { opacity: 0; animation: load-fade-in 0.5s ease 0.9s forwards; }
#load-fill { transition: width 0.35s ease-out; }
@keyframes load-fade-in { to { opacity: 1; } }
/* the steam: three wisps rising off the grill marks and fading, staggered */
#load-emblem .steam path { opacity: 0; animation: load-steam 2.4s ease-out infinite; transform-box: fill-box; transform-origin: 50% 100%; }
#load-emblem .steam .s1 { animation-delay: 1.3s; }
#load-emblem .steam .s2 { animation-delay: 2.1s; }
#load-emblem .steam .s3 { animation-delay: 1.7s; }
@keyframes load-steam { 0% { opacity: 0; transform: translateY(10px) scale(0.8); } 20% { opacity: 0.7; } 100% { opacity: 0; transform: translateY(-34px) scale(1.15); } }
@media (prefers-reduced-motion: reduce) { #load-emblem, #load-emblem .steam path { animation: none; } #load-emblem .ink polygon, #load-emblem .ink polyline { animation-duration: 0.01s; animation-delay: 0s; } #load-emblem .cook { animation-delay: 0s; } }

#credits { z-index: 20; justify-content: flex-start; overflow-y: auto; padding: 48px 20px calc(40px + var(--ad-h, 0px)); }
#credits ul { max-width: 640px; }
#credits .pause-option { font-size: clamp(22px, 4vw, 34px); margin-top: 10px; flex: none; }
/* the pause menu must fit ANY stage: every height answers to the viewport
   height, so a short wide window tightens its lines instead of clipping
   Quit off the bottom; overflow scroll is the last-resort safety net */
#pause-screen {
  z-index: 15;
  gap: clamp(10px, 3vh, 34px);
  overflow-y: auto;
  padding: 2vh 10px calc(24vh + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px)); /* the level selection rides HIGH: the group centres in the room above the padding, so the nav row sits near a third of the height — about where an iPhone's side button is (author, 2026-09-13) */
}
.pause-icon {
  background: none; border: none; padding: 0;
  width: clamp(64px, 14vw, 96px); height: clamp(64px, 14vw, 96px);
  cursor: pointer;
  opacity: 0.9;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.pause-icon:hover, .pause-icon:active { background: none; opacity: 1; transform: scale(1.06); }
.pause-icon svg {
  display: block; width: 100%; height: 100%; fill: #ffffff;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.45)) drop-shadow(0 4px 14px rgba(0, 0, 0, 0.3));
}
/* the menu's own corners: mute bottom left, gallery bottom centre, settings bottom right */
.pause-corner {
  position: absolute;
  bottom: calc(14px + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px));
  width: clamp(58px, 12vw, 84px); height: clamp(58px, 12vw, 84px);
  padding: 8px;
  /* the same grey as the in-level corner buttons: white at their opacities */
  opacity: 0.32;
}
.pause-corner:hover, .pause-corner:active { opacity: 0.65; }
@media (max-width: 700px) { .pause-corner { opacity: 0.5; } }
.pause-corner svg { filter: none; }
.pause-corner.bl { left: calc(14px + env(safe-area-inset-left, 0px)); }
/* the language corner, top right: the globe, dressed like the other corner
   icons, and its menu — a titled, scrollable list of every language in its
   own name, the current one marked */
.pause-corner.tr {
  bottom: auto; top: calc(14px + env(safe-area-inset-top, 0px));
  right: calc(14px + env(safe-area-inset-right, 0px));
}
#lang-menu {
  position: absolute; z-index: 17;
  top: calc(14px + env(safe-area-inset-top, 0px) + clamp(58px, 12vw, 84px) + 4px);
  right: calc(14px + env(safe-area-inset-right, 0px));
  width: min(86vw, 340px);
  max-height: calc(100% - 14px - env(safe-area-inset-top, 0px) - clamp(58px, 12vw, 84px) - 4px - 110px - env(safe-area-inset-bottom, 0px) - var(--ad-h, 0px));
  display: flex; flex-direction: column;
  border-radius: 14px; overflow: hidden;
  background: rgba(34, 34, 34, 0.94);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
  text-align: left; font-variant: normal; letter-spacing: 0;
}
.lang-head {
  padding: 12px 16px 10px; font-size: 15px; letter-spacing: 0.28em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.6);
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
/* min-height 0: a flex-column child cannot shrink below its content by
   default, so the list overflowed the menu's clip instead of scrolling —
   on every screen (measured: 23 rows clipped at the 14th). pan-y: the
   body's touch-action is none for the pan's sake; the list says otherwise */
.lang-list { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 6px; min-height: 0; flex: 1 1 auto; touch-action: pan-y; overscroll-behavior: contain; }
.lang-pick {
  display: flex; align-items: center; gap: 12px; width: 100%;
  background: none; border: none; border-radius: 9px; padding: 9px 12px;
  color: #ffffff; font-family: inherit; font-size: 18px; line-height: 1.2; text-align: left;
  letter-spacing: 0.02em; text-indent: 0; font-variant: normal; /* the menus' wide tracking stops here: names read as words */
  white-space: nowrap; cursor: pointer;
}
.lang-pick .flag { font-size: 22px; line-height: 1; flex: none; width: 30px; text-align: center; }
.lang-pick .name { flex: 1; letter-spacing: 0.02em; }
.lang-pick:hover, .lang-pick:active { background: rgba(255, 255, 255, 0.1); }
.lang-pick.sel { background: rgba(255, 255, 255, 0.16); }
.lang-pick.sel::after { content: "\2713"; margin-left: auto; opacity: 0.85; }
.pause-corner.br { right: calc(14px + env(safe-area-inset-right, 0px)); }
.pause-corner.bc { left: 50%; transform: translateX(-50%); }
.pause-corner.bc:hover, .pause-corner.bc:active { transform: translateX(-50%) scale(1.06); }
/* the way back out of any menu: one thick white X, no words */
.menu-close {
  width: clamp(50px, 10vw, 68px); height: clamp(50px, 10vw, 68px);
  flex: none;
}
/* the LOOK menu gathers at the bottom centre, where the thumb lives */
#settings-screen {
  z-index: 16;
  justify-content: flex-end;
  padding-bottom: calc(6vh + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px));
}
#gallery-screen { z-index: 16; }
/* the still of the current level under the menus while a portrait batch builds the others in the live scene (see startPreviewBatch) */
#gallery-still, #wear-still { position: fixed; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 9; pointer-events: none; } /* #wear-still: the paused view frozen under the wardrobe while the real chain stands up (2026-09-13) */

/* the main menu floats on a lightly blurred view of the scene, not a dark veil */
#title-screen {
  background: none;
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
}
#title-screen h1 { font-size: clamp(44px, 8vw, 96px); }
#credits h2, #settings-screen h2, #radio-screen h2, #wear-screen h2 { font-weight: 400; letter-spacing: 0.3em; font-variant: normal; font-size: 34px; }
/* THE WARDROBE (author, 2026-09-13): the radio's place and dress on the
   right — the tee above the look, the screen with a portrait of the meat in
   what it wears over the rail of options */
.pause-corner.br2 { right: calc(14px + env(safe-area-inset-right, 0px)); bottom: calc(14px + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px) + clamp(58px, 12vw, 84px) + 6px); }
/* MORE (the store apps only, 2026-09-22; author: "'more' above the clothes
   menu button", after Bacon's pause menu): a third corner up the right side,
   the same 6 px over the wardrobe that the wardrobe keeps over the look, the
   corners' size, opacity, hover and fade — but a WORD, not an icon: Bacon's
   small grey "more", lowercase, in the menu's type and the corners' ink.
   display none unless body.native (index.html's inline script); its tap is
   src/native.js's native action sheet */
.pause-corner.br3 { right: calc(14px + env(safe-area-inset-right, 0px)); bottom: calc(14px + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px) + 2 * (clamp(58px, 12vw, 84px) + 6px)); }
#pause-more-btn { display: none; font-weight: 400; font-size: clamp(17px, 3.6vw, 22px); line-height: 1; letter-spacing: 0.06em; text-indent: 0.06em; white-space: nowrap; color: #ffffff; }
body.native #pause-more-btn { display: block; }
/* REMOVE ADS over the gallery (2026-09-24, Bacon's pause menu): the word in
   the corners' ink a size up from "more", the restore lowercase and paler
   under it, the pair standing 4 px over the gallery button (which rides the
   banner, so they do too); the store apps only, gone once bought */
#pause-noads { display: none; position: absolute; left: 50%; transform: translateX(-50%); bottom: calc(14px + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px) + clamp(58px, 12vw, 84px) + 4px); flex-direction: column; align-items: center; gap: 2px; }
body.native:not(.noads-owned) #pause-noads { display: flex; }
#pause-noads button { background: none; border: none; padding: 4px 14px; margin: 0; font-family: inherit; font-weight: 400; line-height: 1.05; white-space: nowrap; letter-spacing: 0.04em; cursor: pointer; transition: opacity 0.15s ease; }
#pause-noads-buy { font-size: clamp(20px, 4.8vw, 27px); color: #111111; opacity: 0.8; }
#pause-noads-restore { font-size: clamp(15px, 3.7vw, 20px); color: #ffffff; opacity: 0.72; }
.bg-white #pause-noads-buy { color: #2b2b2b; opacity: 0.72; }
.bg-white #pause-noads-restore { color: #2b2b2b; opacity: 0.42; }
#pause-noads button:active { opacity: 1; background: none; }
/* the sheet's answers ("Ads removed", "No purchase to restore"): a pill at the top centre over the pause menu, clear of the banner (native.js) */
#shell-note { position: fixed; left: 50%; top: calc(18px + env(safe-area-inset-top, 0px)); transform: translate(-50%, -8px); z-index: 40; max-width: min(86vw, 420px); padding: 10px 18px; border-radius: 16px; background: rgb(125, 125, 125); color: #ffffff; font-size: 17px; letter-spacing: 0.04em; text-align: center; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); opacity: 0; pointer-events: none; transition: opacity 0.25s ease, transform 0.25s ease; }
#shell-note.on { opacity: 1; transform: translate(-50%, 0); }
.bg-white #shell-note { background: rgb(226, 226, 226); color: #2b2b2b; }
#pause-more-btn:hover, #pause-more-btn:active { color: #ffffff; } /* the plain button's hover inks dark on a white fill; a corner has no fill */
.bg-grey #pause-screen #pause-more-btn, .bg-grey #pause-screen #pause-more-btn:hover { color: #111111; }
.bg-white #pause-screen #pause-more-btn, .bg-white #pause-screen #pause-more-btn:hover { color: #2b2b2b; }
#wear-screen { z-index: 16; justify-content: flex-end; padding-bottom: calc(6vh + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px)); background: none; transition: opacity 0.35s ease; }
#wear-screen.fading { opacity: 0; pointer-events: none; }
/* the stage: the second renderer's canvas, a round window on the meat standing upright */
#wear-stage { position: absolute; inset: 0; pointer-events: none; z-index: 0; } /* THE FITTING (2026-09-13, fourth cut): a full-screen transparent canvas drawing the real meat through the game lens over the wash — the same size as in play */
#wear-stage canvas { display: block; width: 100%; height: 100%; }
#wear-nav { position: relative; z-index: 1; }
#wear-close { position: relative; z-index: 1; } /* under the grid again, the whole stack raised (author, 2026-09-20, later: "place the back button where it was previously, only now raised vertically"; a top-left corner lived an hour) */
/* the rail is the level selection's: the same guillemets, the item's name in the middle in the same tan */
#wear-nav { max-width: calc(100% - 24px); display: flex; align-items: center; justify-content: center; gap: clamp(16px, 5vw, 42px); }
#wear-nav button { flex: 0 0 auto; background: none; border: none; padding: 0 14px; font-size: clamp(56px, min(12vw, 12vh), 112px); font-weight: 700; line-height: 0.8; letter-spacing: 0; text-indent: 0; color: #ffffff; -webkit-text-stroke: 0.045em #ffffff; paint-order: stroke fill; text-shadow: none; transition: opacity 0.15s ease, transform 0.15s ease; } /* white on the grey (dark) theme, black on the white (author, 2026-09-13) */
#wear-nav button:hover { background: none; color: #ffffff; transform: scale(1.08); }
#wear-pics { display: flex; align-items: center; justify-content: center; gap: 10px; min-width: clamp(96px, 26vw, 150px); }
#wear-pics img { width: clamp(72px, 20vw, 112px); height: clamp(72px, 20vw, 112px); object-fit: contain; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.35)); }
.bg-white #wear-nav button, .bg-white #wear-nav button:hover { color: #2b2b2b; -webkit-text-stroke: 0.045em #2b2b2b; }
/* THE GRID (author, 2026-09-20): three columns of outfit pictures in a box
   that scrolls, standing where the rail stood; the pick wears the level
   selection's tan as a ring. `#wear-screen.grid` / `.rail` is WEAR_MENU
   (main.js) — the rail is kept whole behind the toggle. The box is at most
   30vh tall so the standing sausage, centred on the screen and enlarged,
   keeps its room above it (wearFitPose sizes it to that room). */
#wear-grid { --wear-cell: calc((min(92vw, 360px) - 36px) / 3); position: relative; z-index: 1; display: none; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: max-content; align-content: start; gap: 10px; width: min(92vw, 360px); max-height: min(calc(2.5 * var(--wear-cell) + 36px), 62vh); /* two rows and a half (author, 2026-09-20: "2.5 rows ideally"; 3.15 the night before) */ overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; touch-action: pan-y; padding: 8px; box-sizing: border-box; border-radius: 20px; background: rgba(125, 125, 125, 0.85); -webkit-overflow-scrolling: touch; } /* rows size to their cells (a cell's min-height of 0 let the auto rows share the box's 240 px, five rows of 37 with 129 px cells drawn over each other — seen); the tray's wash over the menu's so the still under the menus does not show through the cells */
#wear-grid button { position: relative; min-width: 0; width: 100%; aspect-ratio: 1; padding: 0; margin: 0; background: rgba(255, 255, 255, 0.08); border: 3px solid transparent; border-radius: 16px; box-shadow: none; text-shadow: none; transition: transform 0.15s ease, border-color 0.15s ease, background 0.15s ease; }
#wear-grid button:hover { background: rgba(255, 255, 255, 0.16); transform: scale(1.04); }
.wear-gap { grid-column: 1 / -1; height: 2px; } /* between the skins and the hats (2026-09-29): a full-width row, so the grid's own gap stands twice over it */
#wear-grid button.on { border-color: #e8906a; background: rgba(255, 255, 255, 0.16); } /* the grey theme's tan; the white theme's below */
#wear-grid img { position: absolute; inset: 8%; width: 84%; height: 84%; object-fit: contain; display: block; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.35)); pointer-events: none; } /* WEBKIT SIZED THE CELLS BY THEIR PICTURES (author, 2026-09-24, a phone shot of the TestFlight build: the third column cut off): a 1fr column's floor is its content's min-content, and Safari counted the in-flow picture's own pixels — 131 px cells in a 360 box, the grid 430 wide on every frame (measured in Playwright's WebKit; Chromium kept 108). The columns may shrink to 0 and the picture stands out of the flow, so the cell is its column's width and square by aspect-ratio alone */
.bg-white #wear-grid { background: rgba(226, 226, 226, 0.85); }
.bg-white #wear-grid button { background: rgba(0, 0, 0, 0.05); }
.bg-white #wear-grid button:hover, .bg-white #wear-grid button.on { background: rgba(0, 0, 0, 0.09); }
.bg-white #wear-grid button.on { border-color: #f3a283; }
/* SAUSAGE POINTS (author, 2026-09-20: "1 point awarded for one level
   completed, each clothes item costing 10"): the balance stands over the
   selector; an outfit not yet bought shows greyed with its price in the
   corner, and a tap without the points shakes it and the balance */
#wear-points { position: absolute; z-index: 2; right: 22px; top: calc(22px + env(safe-area-inset-top, 0px)); display: flex; align-items: center; gap: 12px; font-size: 22px; opacity: 0.95; cursor: pointer; padding: 6px 8px; margin: -6px -8px; background: none; }
#wear-points:hover { background: none; } /* no box behind it, hovered or not (author, 2026-09-20, night: "remove the background thing from the points top right") */ /* a tap tells what the points are (2026-09-20) */ /* the village sausage and the count, in the top-right corner (author, 2026-09-20: "move the sausage points to the top right") */
#wear-points svg { display: block; height: 1.25em; width: auto; filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.3)); }
.bg-white #wear-points svg g { stroke: #2b2b2b; }
#wear-points b { font-weight: 700; letter-spacing: 0; text-indent: 0; color: #e8906a; }
.bg-white #wear-points b { color: #f3a283; }
#wear-grid button.locked img, #wear-pics.locked img { opacity: 0.38; filter: grayscale(0.7) drop-shadow(0 2px 6px rgba(0, 0, 0, 0.35)); }
#wear-pics { position: relative; }
#wear-grid button.locked::after, #wear-pics.locked::after { content: attr(data-cost); position: absolute; right: 9px; bottom: 5px; font-size: 18px; font-weight: 700; letter-spacing: 0; text-indent: 0; color: #e8906a; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45); }
.bg-white #wear-grid button.locked::after, .bg-white #wear-pics.locked::after { color: #f3a283; }
#wear-grid button.ad::after, #wear-pics.ad::after { content: ""; width: 15px; height: 15px; right: 11px; bottom: 9px; background: currentColor; -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path d='M4 2.5 L17.5 10 L4 17.5 Z'/></svg>") no-repeat center / contain; mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path d='M4 2.5 L17.5 10 L4 17.5 Z'/></svg>") no-repeat center / contain; text-shadow: none; } /* the play glyph where a price stands: an ad item (WEAR_ADS, 2026-09-20) — an SVG mask in the tan, not the U+25B6 text (a colour emoji on a phone; 2026-09-21) */
#wear-grid button.nope, #wear-pics.nope, #wear-points.nope { animation: wear-nope 0.4s ease; }
@keyframes wear-nope { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-6px); } 40% { transform: translateX(6px); } 60% { transform: translateX(-4px); } 80% { transform: translateX(4px); } }
#wear-screen.grid #wear-grid { display: grid; }
#wear-screen.grid #wear-nav { display: none; }
#wear-screen.grid { justify-content: flex-end; padding-bottom: calc(9vh + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px)); } /* the stack raised: 9vh (was 3); BOTTOM-ANCHORED since 2026-09-22 — centred, the leftover split above and below the stack and a short frame left the sausage 37 px; layoutWearGrid (main.js) sizes the grid's box to the frame and the room above is the sausage's */
/* THE WIDE LAYOUT (2026-09-20, night; a frame at least 1.25× wider than tall — Poki's inspector, a landscape phone, a laptop): the grid and Back stand in the RIGHT half, centred on its height, and the sausage takes the left half (wearFitPose's wide branch); the grid's cells shrink with the half so a 640 × 360 phone on its side still shows two rows and a bit */
#wear-screen.grid.wide { justify-content: center; align-items: flex-end; padding-top: 70px; padding-bottom: calc(env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px)); padding-right: max(4vw, env(safe-area-inset-right, 0px)); } /* the stack centred in the room UNDER the corner row (the balance stood over the grid's corner at 856 × 483 and 640 × 360, measured) */
#wear-screen.grid.wide #wear-grid { --wear-cell: calc((min(40vw, 360px) - 36px) / 3); width: min(40vw, 360px); max-height: min(calc(2.5 * var(--wear-cell) + 36px), calc(100vh - 170px - var(--ad-h, 0px))); } /* 40vw, not 46: with Back at the bottom centre the grid's left edge must clear the centre by Back's half width — at 836 × 470 a 360-wide grid started 9 px short of it, at 640 × 360 the two overlapped (measured) */
#wear-screen.grid.wide #wear-close { position: absolute; left: 50%; bottom: calc(3vh + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px)); transform: translateX(-50%); margin: 0; } /* Back at the frame's bottom centre, where it stood before the wide layout (author, 2026-09-20, night: "move the back arrow back into the previous position"; under the right column for an hour) */
/* THE UNLOCK ASK: a small card over the grid — the theme's wash near solid,
   the item's picture, its name, the question, Not now and Unlock (the tan) */
#wear-ask { position: absolute; z-index: 3; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(86vw, 340px); box-sizing: border-box; padding: 20px 20px 18px; border-radius: 22px; background: rgb(125, 125, 125); box-shadow: 0 14px 40px rgba(0, 0, 0, 0.35); display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; animation: ask-in 0.18s ease-out; transition: opacity 0.18s ease; }
#wear-ask.closing { opacity: 0; pointer-events: none; } /* the fade out (author, 2026-09-20) */
#wear-ask-emblem svg { display: block; height: 64px; width: auto; margin: 16px 0; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.35)); }
.bg-white #wear-ask-emblem svg g { stroke: #2b2b2b; }
.bg-white #wear-ask { background: rgb(226, 226, 226); color: #111111; } /* the card's words in the dark ink on the light card (author, 2026-09-24: "the clothes menu pop ups need black text in light mode" — they inherited the menu's white) */
@keyframes ask-in { from { opacity: 0; transform: translate(-50%, -50%) scale(0.92); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
#wear-ask-pic { width: 96px; height: 96px; object-fit: contain; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.35)); }
#wear-ask-name { font-weight: 700; font-size: 22px; letter-spacing: 0.08em; }
#wear-ask-q { font-size: 17px; line-height: 1.35; opacity: 0.9; }
#wear-ask-row { display: flex; gap: 12px; margin-top: 8px; }
#wear-ask button { min-width: 108px; padding: 11px 18px; border: none; border-radius: 14px; font-size: 16px; letter-spacing: 0.08em; text-indent: 0.08em; background: rgba(255, 255, 255, 0.14); color: inherit; text-shadow: none; box-shadow: none; transition: transform 0.12s ease, background 0.12s ease; }
#wear-ask button:hover { background: rgba(255, 255, 255, 0.24); color: inherit; transform: scale(1.03); }
#wear-ask #wear-ask-yes, #wear-ask #wear-ask-yes:hover { background: #e8906a; color: #1c1410; } /* the ancestor id too: `#wear-ask button` outranks a bare `#wear-ask-yes` (an id and a type over an id — measured, the tan lost) */
.bg-white #wear-ask button { background: rgba(0, 0, 0, 0.07); }
.bg-white #wear-ask button:hover { background: rgba(0, 0, 0, 0.12); }
.bg-white #wear-ask #wear-ask-yes, .bg-white #wear-ask #wear-ask-yes:hover { background: #f3a283; color: #1c1410; }
/* THE RADIO (author, 2026-09-13): the look menu's place and dress — the
   radio for a title, the piece's name, the five verbs in the menus' white
   (the corner icon wears the corners' grey and re-inks with the theme like
   the sound and the look). THE FADE: the pause menu's whole surface fades
   out over 0.35 s and the radio fades in over it, and back (`.fading`) */
.pause-corner.bl2 { left: calc(14px + env(safe-area-inset-left, 0px)); bottom: calc(14px + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px) + clamp(58px, 12vw, 84px) + 6px); }
#radio-screen { z-index: 16; justify-content: flex-end; padding-bottom: calc(6vh + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px)); background: none; } /* no wash of its own: it lies on the pause menu's, which never fades (author: "don't fade out the background pause menu overlay") */
#pause-screen > * { transition: opacity 0.35s ease; }
#pause-screen.fading > *, .bg-grey #pause-screen.fading .pause-corner, .bg-white #pause-screen.fading .pause-corner, #pause-screen.fading .pause-corner:hover, #pause-screen.fading .pause-corner:focus, #pause-screen.fading .pause-corner:active { opacity: 0 !important; pointer-events: none; } /* !important: on a phone the TAPPED corner keeps :hover and :focus until the next tap (sticky touch hover) and its hover rule held it at 0.85 over the wardrobe and the radio — the clothes and music icons lingered (author, 2026-09-21); openPanel blurs it too */ /* the CONTENTS fade — the corners too, whose themed opacity rules outranked the plain child rule (the bottom buttons stayed, seen 2026-09-13); the grey stays */
#pause-screen.fading { pointer-events: none; }
#radio-screen { transition: opacity 0.35s ease; }
#radio-screen.fading { opacity: 0; pointer-events: none; }
#radio-name { font-size: clamp(20px, min(4.2vw, 3.8vh), 30px); letter-spacing: 0.08em; font-variant: normal; min-height: 1.3em; color: #111111; text-shadow: none; } /* black on the white theme, white on the grey (author, 2026-09-13, twice) */
.bg-grey #radio-name { color: #ffffff; }
#radio-row { display: flex; align-items: center; justify-content: center; gap: clamp(14px, 4vw, 34px); }
.radio-btn { position: relative; background: none; border: none; padding: 8px; cursor: pointer; width: clamp(48px, 10vw, 64px); height: clamp(48px, 10vw, 64px); opacity: 0.9; transition: opacity 0.15s ease, transform 0.15s ease; }
.radio-btn:hover, .radio-btn:active { background: none; opacity: 1; transform: scale(1.06); }
.radio-btn svg { display: block; width: 100%; height: 100%; fill: #ffffff; filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.45)); }
.radio-main { width: clamp(76px, 15vw, 96px); height: clamp(76px, 15vw, 96px); padding: 18px; border-radius: 50%; border: 4px solid rgba(255, 255, 255, 0.9); } /* no shadow on the ring or its glyph (author, 2026-09-13) */
.radio-main svg { filter: none; }
.radio-main:hover, .radio-main:active { border-color: #ffffff; }
.radio-main .pp-pause { display: none; }
.radio-main.playing .pp-pause { display: block; }
.radio-main.playing .pp-play { display: none; }
.radio-toggle { opacity: 0.55; }
.radio-toggle .dot { position: absolute; left: 50%; bottom: 2px; width: 6px; height: 6px; margin-left: -3px; border-radius: 50%; background: #ffffff; opacity: 0; transition: opacity 0.15s ease; }
.radio-toggle.on { opacity: 1; }
.radio-toggle.on .dot { opacity: 1; }
/* the pause options wear the PAUSED heading's own clothes */
.pause-option {
  background: none; border: none; box-shadow: none; padding: 0;
  font-size: clamp(34px, 6vw, 74px);
  font-weight: 400;
  letter-spacing: 0.14em; text-indent: 0.14em;
  line-height: 1.15;
  color: #ffffff;
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.9);
}
.pause-option:hover { background: none; color: #ffffff; font-style: italic; }
.act-heading {
  font-variant: normal; letter-spacing: 0.34em; text-indent: 0.34em;
  font-size: clamp(24px, 4.5vw, 40px); font-weight: 700;
  color: #ffffff;
  grid-column: 1 / -1; text-align: center; padding: 14px 0 4px;
}
#gallery-screen { overflow-y: auto; justify-content: flex-start; padding: 40px 0 30px; touch-action: pan-y; overscroll-behavior: contain; }
#gallery-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px; width: min(1100px, 93vw);
}
.gallery-card {
  background: none; border: 1px solid rgba(255, 255, 255, 0.35); border-radius: 0;
  padding: 0; cursor: pointer; display: flex; flex-direction: column;
  color: #ffffff; font-family: inherit; letter-spacing: 0;
  transition: border-color 0.15s, transform 0.15s;
}
.gallery-card img, .gallery-card .ph {
  width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block;
}
.gallery-card .ph { background: rgba(255, 255, 255, 0.06); }
.gallery-card .cap {
  font-variant: normal; letter-spacing: 0.14em; font-size: 12.5px;
  padding: 7px 6px 8px; text-align: center;
}
.gallery-card:hover { background: none; color: #ffffff; border-color: #ffffff; transform: translateY(-2px); }
.gallery-card.locked { opacity: 0.6; pointer-events: none; }
.gallery-card.locked img { filter: grayscale(0.9) brightness(0.45); }
.gallery-card.locked .cap { font-style: italic; opacity: 0.8; }
.gallery-card.faded { opacity: 0.22; } /* the second locked card, fading out (author, 2026-09-13) */
.gallery-card.ghost { opacity: 0.1; } /* the third: the frame alone, no text — the last the grid shows (author, later that night) */
@media (max-width: 760px) { #gallery-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.setting {
  display: flex; align-items: center; gap: 18px;
  font-variant: normal; letter-spacing: 0.22em; font-size: 17px;
}
.setting input[type="range"] { width: 190px; accent-color: #ffffff; }
/* the backdrop swatches: three tall chips of the colour itself — auto wears both halves */
#bg-row { display: flex; gap: 18px; align-items: center; }
.bg-swatch {
  width: 30px; height: 52px;
  padding: 0; border: 2px solid rgba(255, 255, 255, 0.45); border-radius: 4px;
  cursor: pointer;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
/* each chip keeps its colour under the global button hover-wash */
.bg-swatch[data-bg="grey"], .bg-swatch[data-bg="grey"]:hover { background: #5b6156; }
.bg-swatch[data-bg="white"], .bg-swatch[data-bg="white"]:hover { background: #e6e6e6; }
/* auto: white by day, grey under dark mode — the chip shows both, split on the diagonal */
.bg-swatch[data-bg="auto"], .bg-swatch[data-bg="auto"]:hover { background: linear-gradient(135deg, #e6e6e6 0%, #e6e6e6 49.5%, #5b6156 50.5%, #5b6156 100%); }
.bg-swatch:hover { border-color: rgba(255, 255, 255, 0.8); }
.bg-swatch.sel { border-color: #ffffff; transform: scale(1.12); }
.setting input[type="checkbox"] { width: 18px; height: 18px; accent-color: #ffffff; }
#credits ul { list-style: none; font-size: 16px; line-height: 2.2; font-style: italic; opacity: 0.9; }
#credits ul b { font-style: normal; font-variant: normal; letter-spacing: 0.08em; }
#win-stats { font-size: 19px; font-style: italic; opacity: 0.9; }
.hidden { display: none !important; }

/* ------------------------------------------------- instant prints
   Every shutter snap develops into a print — white border, deep chin,
   fresh out of the camera and still darkening into view. */
#prints {
  position: absolute; inset: 0; bottom: var(--ad-h, 0px); /* the prints centre in the room over the store app's banner (0 everywhere else) */
  display: grid; place-items: center;
  pointer-events: none; z-index: 7;
}
.print-slot {
  grid-area: 1 / 1; /* the prints stack — each new one lands on the pile */
  transform: translateX(var(--off, 0vw));
  transition: transform 0.38s cubic-bezier(0.3, 0.8, 0.3, 1);
}
/* --tilt is a real angle so it can EASE: the eject animation's fill holds
   a transform built from var(--tilt), and registering the property lets the
   viewed card swing smoothly between straight and its dealt lean */
@property --tilt {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
.print {
  position: relative;
  background: #f4f0e6;
  /* a taller top margin carries the studio's stamp; the chin keeps the caption.
     THE FOREHEAD AND THE CHIN ARE THE PHONE'S (author, 2026-09-20: "trim the
     polaroid's chin and forehead so they don't change size from the more
     ideal mobile sizes" — to leave the "+1" its room): 34 and 52 px on every
     frame, where they used to grow with the width to 66 and 110 (a 640 × 360
     phone on its side wore a 51 px forehead and an 83 px chin and its card
     ran to 352 of 360; now 244 tall with 100 px under it) */
  padding: 34px clamp(12px, 3vw, 24px) 52px;
  border-radius: 2px;
  box-shadow: 0 16px 44px rgba(0, 0, 0, 0.55);
  transform: rotate(var(--tilt, 0deg));
  transition: --tilt 0.38s cubic-bezier(0.3, 0.8, 0.3, 1);
  animation: print-eject 0.55s cubic-bezier(0.2, 1.5, 0.4, 1) both,
             print-shake 0.9s ease-in-out 0.55s 1;
}
.print img {
  display: block;
  width: min(78vw, 58vh); /* a short landscape shrinks it below, so the verbs have their sides */
  height: auto;
  border-radius: 1px;
  filter: saturate(1.04) contrast(1.02); /* full colour, straight out of the camera */
}
/* the studio's stamp across the top margin, same hand as the caption */
.print-head {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 34px; /* the forehead's own height (above) */
  display: flex; align-items: center; justify-content: center;
  font-family: "Bradley Hand", "Segoe Script", "Savoye LET", "Comic Sans MS", cursive;
  font-size: clamp(14px, 3.6vw, 18px); /* capped to the 34 px band (was 24 in a 66 px one); a phone's 14 unchanged */
  color: #4a4238;
  white-space: nowrap;
}
.print-cap {
  /* vertically centred in the print's chin */
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 52px; /* the chin's own height (above) */
  display: flex; align-items: center; justify-content: center;
  font-family: "Bradley Hand", "Segoe Script", "Savoye LET", "Comic Sans MS", cursive;
  font-size: clamp(17px, 4.6vw, 22px); /* capped to the 52 px chin (was 30 in a 110 px one); a phone's 17–20 unchanged */
  color: #4a4238;
  /* one unbroken line of handwriting; JS shrinks it until it fits the chin */
  white-space: nowrap; overflow: hidden;
  padding: 0 clamp(10px, 2.6vw, 22px); box-sizing: border-box;
}
/* a short landscape (a phone on its side): the print gives up height so it
   clears the floor and leaves each side a gap wide enough for a verb — and
   room under its chin for the "+1" (2026-09-20: the rule once asked for
   701 px of width too, which a 640 × 360 phone lacks, so it kept the 58vh
   photo and its card ran to 327 of 360; a portrait phone is never 480
   tall, so the width guard protected nothing) */
@media (max-height: 480px) {
  .print img { width: min(78vw, 44vh); }
}
/* placed by layoutShootNav() on wide screens AND landscape phones: each verb
   at the centre of its side gap, on the print's midline (outside the media
   query — a 640×360 phone is landscape, not wide) */
#shoot-nav.side { inset: 0; bottom: auto; top: 0; transform: none; padding: 0; display: block; height: 100%; }
#shoot-nav.side button { position: absolute; }
/* the photoshoot's two verbs, shoulder to shoulder beneath the prints —
   WHITE on every backdrop (they sit on the sausage-orange veil, never on the
   bare white; the .bg-white re-inking below leaves them alone) */
#shoot-nav {
  position: absolute; left: 0; right: 0;
  bottom: calc(11vh + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px));
  display: flex; justify-content: center; align-items: center;
  gap: clamp(30px, 10vw, 70px);
  z-index: 8; pointer-events: none;
}
#shoot-nav button {
  width: clamp(74px, 17vw, 104px); height: clamp(74px, 17vw, 104px);
  background: none; border: none; padding: 0; /* the icon's own viewBox carries the margin and the shadow (index.html) */
  pointer-events: auto; cursor: pointer;
  opacity: 0.6;
  transition: opacity 0.15s ease;
}
#shoot-nav button:hover, #shoot-nav button:active { opacity: 0.95; }
#shoot-nav svg { display: block; width: 100%; height: 100%; fill: #ffffff; }
/* phones: the verbs are the shoot's whole interface — make them commanding */
@media (max-width: 700px) {
  #shoot-nav {
    gap: clamp(26px, 9vw, 58px);
    bottom: calc(2.5vh + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px));
  }
  #shoot-nav button { width: 128px; height: 128px; padding: 0; opacity: 0.7; }
}

/* a PORTRAIT TABLET (2026-10-12) keeps the phone's row under the print: the
   print fills its width, and flanking it the verbs stood on the card's
   cream edges — 58–77 px into it on every iPad, the Tab S8 and the Fold
   (the layout audit); layoutShootNav sizes them to the room under the pile */
@media (min-width: 701px) and (max-aspect-ratio: 10/11) {
  #shoot-nav {
    gap: clamp(40px, 12vw, 120px);
    bottom: calc(3vh + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px));
  }
  #shoot-nav button { opacity: 0.7; }
}

/* "+1" AND THE VILLAGE SAUSAGE (2026-09-20): under the polaroid on a subject's
   first win, above the verbs on a phone (the row sits at the bottom edge)
   and between the print and its chin on a wide screen (the verbs flank the
   print there); placed by layoutShootNav from the top print's rect; white
   with the verbs' shadow, popping in on the third snap */
#shoot-points { position: absolute; z-index: 8; pointer-events: none; display: flex; align-items: center; gap: 10px; transform: translate(-50%, 0); color: #ffffff; font-weight: 700; font-size: clamp(26px, 5vw, 40px); letter-spacing: 0.04em; text-shadow: 0 2px 10px rgba(0, 0, 0, 0.6); animation: points-pop 0.55s cubic-bezier(0.2, 0.9, 0.3, 1.3) 0.25s backwards; }
#shoot-points svg { display: block; height: 1.35em; width: auto; filter: drop-shadow(0 2px 10px rgba(0, 0, 0, 0.6)); }
@keyframes points-pop { from { opacity: 0; transform: translate(-50%, 10px) scale(0.6); } to { opacity: 1; transform: translate(-50%, 0) scale(1); } }
/* entrance on the third snap: phones rise, wide screens slide from the wings
   (fill-mode backwards, so hover opacity rules take over once it lands) */
#shoot-nav button { animation: verb-rise 0.5s ease-out backwards; }
#shoot-nav button:last-child { animation-delay: 0.07s; }
@keyframes verb-rise {
  from { opacity: 0; transform: translateY(26px); }
  to   { transform: none; } /* opacity lands on each button's own base value */
}
/* wide screens: the verbs flank the print instead of crowding its chin —
   retake stage-left, onward stage-right, both at the print's midline */
@media (min-width: 701px) and (min-aspect-ratio: 10/11) {
  #shoot-nav {
    inset: 0; bottom: auto; top: calc(50% - var(--ad-h, 0px) / 2); transform: translateY(-50%);
    justify-content: space-between;
    padding: 0 clamp(16px, 4.5vw, 90px);
  }

  #shoot-nav button:first-child { animation-name: verb-in-left; }
  #shoot-nav button:last-child { animation-name: verb-in-right; animation-delay: 0s; }
  #shoot-nav button { animation-duration: 0.6s; animation-timing-function: cubic-bezier(0.2, 0.9, 0.3, 1); }
}
@keyframes verb-in-left {
  from { opacity: 0; transform: translateX(-28vw); }
  to   { transform: none; }
}
@keyframes verb-in-right {
  from { opacity: 0; transform: translateX(28vw); }
  to   { transform: none; }
}

@keyframes print-eject {
  from { transform: translateY(46px) rotate(var(--tilt, 0deg)) scale(0.62); opacity: 0; }
  to   { transform: translateY(0) rotate(var(--tilt, 0deg)) scale(1); opacity: 1; }
}
@keyframes print-shake {
  0%, 100% { transform: rotate(var(--tilt, 0deg)); }
  25% { transform: rotate(calc(var(--tilt, 0deg) + 2.4deg)); }
  55% { transform: rotate(calc(var(--tilt, 0deg) - 1.8deg)); }
  80% { transform: rotate(calc(var(--tilt, 0deg) + 0.9deg)); }
}

/* programme selector at the top of the gallery — same manners as the
   pause menu's level navigator: ‹ title › */
.prog-select {
  grid-column: 1 / -1;
  display: flex; align-items: center; justify-content: center;
  gap: clamp(16px, 5vw, 42px);
  margin: 4px 0 10px;
}
.prog-select button {
  background: none; border: none; padding: 4px 16px;
  font-size: clamp(34px, 6vw, 54px); font-weight: 400; line-height: 1;
  letter-spacing: 0; text-indent: 0;
  color: rgba(255, 255, 255, 0.85); cursor: pointer;
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.9);
}
.prog-select button:hover { background: none; color: #ffffff; font-style: italic; }
.prog-select button:disabled { opacity: 0.25; cursor: default; font-style: normal; }
.prog-name {
  font-size: clamp(17px, 3vw, 24px);
  letter-spacing: 0.22em; text-indent: 0.22em;
  opacity: 0.85; text-shadow: 0 2px 30px rgba(0, 0, 0, 0.9);
}


/* ------------------------------------------------- first-steps guide
   A gloved hand at the bottom centre of the screen — where a thumb rests
   on a phone held in two hands: press, then a nudge up-and-right — the pan
   follows the finger from anywhere (the invisible joystick). Screen-fixed;
   JS only toggles it. */
#guide {
  position: absolute; z-index: 4; pointer-events: none;
  left: 50%;
  bottom: calc(7% + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px));
  width: clamp(52px, 11vw, 88px);
  transform: translateX(-50%);
}
/* desktop: JS parks it under the pan (left/top), the fingertip on the hold zone */
#guide.desk { bottom: auto; transform: translate(-17%, -9%); }
#guide svg {
  display: block; width: 100%; height: auto;
  filter: drop-shadow(0 3px 10px rgba(0, 0, 0, 0.4));
}
/* lesson one (levels 1–2): TAP — the glove presses and lifts, in place */
#guide.tap svg { animation: guide-tap 1.5s ease-in-out infinite; }
/* lesson two (level 3): press, then nudge up-and-right — the pan wants dragging */
#guide.drag svg { animation: guide-drag 2.6s ease-in-out infinite; }
@keyframes guide-tap {
  0%   { transform: scale(1); opacity: 0.95; }
  18%  { transform: scale(0.84); opacity: 1; }
  34%  { transform: scale(1); opacity: 0.95; }
  100% { transform: scale(1); opacity: 0.95; }
}
@keyframes guide-drag {
  0%   { transform: translate(0, 0) scale(1); opacity: 0; }
  10%  { transform: translate(0, 0) scale(0.88); opacity: 0.95; }
  22%  { transform: translate(0, 0) scale(0.88); opacity: 0.95; }
  62%  { transform: translate(85%, -110%) scale(0.88); opacity: 0.95; }
  76%  { transform: translate(97%, -126%) scale(1); opacity: 0; }
  100% { transform: translate(0, 0) scale(1); opacity: 0; }
}

/* ------------------------------------------------- pause level navigator */
#level-nav {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(16px, 5vw, 42px);
}
/* the arrows are the typeface's own single guillemets, set bold and
   inked heavier with a stroke — they keep Times' curve and contrast, and
   still hold their own beside the bold level number */
/* the level selection — arrows, number, name, fast-forward — wears the
   sausage's own orange, the title card's colour (author, 2026-09-02) */
/* the white theme's level selection wears a LIGHTER tan than the sausage's
   #d4651a since 2026-09-13 (author: "make the level selection color lighter
   — the sausage tan that white theme has; leave black as is"): the grey
   backdrop's black ink below is untouched */
#level-nav button {
  background: none; border: none; padding: 0 14px;
  font-size: clamp(56px, min(12vw, 12vh), 112px); font-weight: 700; line-height: 0.8;
  letter-spacing: 0; text-indent: 0;
  color: #f3a283;
  -webkit-text-stroke: 0.045em #f3a283; paint-order: stroke fill;
  text-shadow: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
#level-nav button:hover { background: none; color: #f3a283; transform: scale(1.08); }
#level-nav button:disabled { opacity: 0.25; cursor: default; transform: none; }
/* the fast-forward is the double guillemet: same face, same ink, one more
   chevron — pinned to the screen's right edge, level with the arrows, so
   the prev/number/next trio stays centred as before */
#level-nav { position: relative; width: 100%; }
/* (selectors carry #level-nav so they outrank the shared button rule) */
#level-nav #lvl-last {
  position: absolute; right: calc(8px + env(safe-area-inset-right, 0px)); top: 50%;
  padding: 0 8px;
  transform: translateY(-50%);
  transition: opacity 0.15s ease; /* no transform transition: it read as a slide down when it appeared */
}
#level-nav #lvl-last:hover, #level-nav #lvl-last:disabled { transform: translateY(-50%); }
#lvl-num {
  font-size: clamp(22px, min(4.6vw, 4.2vh), 38px);
  font-weight: 700;
  letter-spacing: 0.1em; text-indent: 0.1em;
  min-width: 4ch;
  color: #f3a283; text-shadow: none;
}
/* the level's paperwork, folded into the pause menu: the subject's name as
   a playbill line under the navigator (the drop count retired) —
   heavy white ink with a tight dark edge, legible on the daylight veil */
#pause-name {
  font-size: clamp(26px, min(6vw, 5.4vh), 48px);
  letter-spacing: 0.08em;
  margin-top: -6px;
  color: #f3a283; text-shadow: none;
}

#pause-name { cursor: pointer; }
#pause-name:hover { opacity: 0.85; }
/* THE LEVEL SEARCH (author, 2026-09-13, from a mockup: a white pill under
   the number, "search level" in a pale placeholder, in place of the name):
   the input is the mockup's box; the matches list under it, each a row
   "#12 Cheeseburger" in the menu's ink, tapped to jump */
/* the slot keeps the name's place in the flow: the box lies over it
   (absolute, centred on the name's line), the matches hang under the box
   over whatever is below — opening the search moves nothing (author,
   2026-09-13: "prevent it from moving the UI layout") */
#lvl-slot { position: relative; display: flex; justify-content: center; align-items: center; width: 100%; }
#lvl-slot.searching #pause-name { visibility: hidden; }
#lvl-search { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(92vw, 560px); z-index: 2; }
#lvl-search.hidden { display: none !important; }
#lvl-query {
  width: 100%; box-sizing: border-box;
  font: 400 clamp(22px, min(4.6vw, 4.2vh), 34px)/1.2 "Times New Roman", Times, Georgia, serif;
  letter-spacing: 0.06em; text-align: center;
  color: #2b2b2b; background: #ffffff; border: none; border-radius: 12px;
  padding: 8px 18px; outline: none; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
}
#lvl-query::placeholder { color: #d9d9d9; }
#lvl-results { position: absolute; top: 100%; left: 0; width: 100%; margin-top: 6px; display: flex; flex-direction: column; align-items: stretch; max-height: min(38vh, 320px); overflow-y: auto; }
#lvl-results button { background: rgba(255, 255, 255, 0.55); backdrop-filter: blur(4px); }
#lvl-results button {
  background: none; border: none; cursor: pointer; text-align: center;
  font: 400 clamp(18px, min(3.6vw, 3.4vh), 28px)/1.25 "Times New Roman", Times, Georgia, serif;
  letter-spacing: 0.05em; color: #f3a283; padding: 4px 10px; border-radius: 8px;
}
#lvl-results button:hover, #lvl-results button.lit { background: rgba(255, 255, 255, 0.85); }
#lvl-results button .n { font-weight: 700; margin-right: 0.5em; }
.bg-grey #lvl-results button { color: #e8906a; } /* the level selection wears the light theme's tan on the grey too (author, 2026-09-13) */
.bg-white #lvl-query { box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12); }

/* ------------------------------------------------- gallery dressing */
#gallery-screen { padding-bottom: calc(44px + var(--ad-h, 0px)); }
#gallery-screen .pause-option {
  font-size: clamp(22px, 4vw, 34px);
  margin-top: 18px; flex: none;
}
.prog-select { margin-bottom: 6px; }
.act-heading { padding: 20px 0 6px; }
.gallery-card .cap { font-size: 13.5px; padding: 9px 6px 10px; }

/* ------------------------------------------------- the white backdrop
   White ink vanishes on a white stage. When the player picks the white
   background (body.bg-white), every piece of in-game chrome that was
   painted white switches to dark ink; the menus keep their grey veil
   (constant contrast), but the veil-less title screen borrows one. */
.bg-white #pause-btn svg, .bg-white #retry-btn svg, .bg-white #mute-btn svg, .bg-white #dev-btn svg { fill: #2b2b2b; }
.bg-white #pause-btn svg [stroke], .bg-white #retry-btn svg [stroke], .bg-white #mute-btn svg [stroke] { stroke: #2b2b2b; }
.bg-white #mute-btn, .bg-white #dev-btn { opacity: 0.38; }
.bg-white #mute-btn:hover, .bg-white #mute-btn:active, .bg-white #dev-btn:hover, .bg-white #dev-btn:active { opacity: 0.7; }
.bg-white #skip-btn { color: #2b2b2b; }
.bg-white #pause-btn, .bg-white #retry-btn, .bg-white #skip-btn { opacity: 0.38; }
.bg-white #skip-btn:hover, .bg-white #skip-btn:active,
.bg-white #pause-btn:hover, .bg-white #pause-btn:active,
.bg-white #retry-btn:hover, .bg-white #retry-btn:active { opacity: 0.7; }
/* the title screen floats veil-less on the blurred scene — on white it
   wears the same grey wash as every other menu so its text stays legible */
.bg-white #title-screen { background: rgba(125, 125, 125, 0.78); }
/* the PAUSE menu on the white backdrop: the same idea as the grey wash —
   a translucent veil of the backdrop's own tone — so a light wash with
   dark ink, the level number, name, arrows and corner icons all re-inked */
.bg-white #pause-screen, .bg-white #settings-screen { background: rgba(226, 226, 226, 0.78); color: #2b2b2b; } /* the look menu wears the pause menu's light wash on the white theme (author, 2026-09-13) */
.bg-white #settings-screen .pause-icon svg, .bg-white #settings-screen .set-title-ico { fill: #2b2b2b; filter: drop-shadow(0 2px 6px rgba(255, 255, 255, 0.6)); }
.bg-white #settings-screen .pause-icon svg [stroke] { stroke: #2b2b2b; }
.bg-white #settings-screen .rule { background: rgba(0, 0, 0, 0.35); }
.bg-white .bg-swatch { border-color: rgba(0, 0, 0, 0.3); }
.bg-white .bg-swatch.sel { border-color: #2b2b2b; }
/* the radio on the white theme: its glyphs in the menu's dark ink like the corners */
.bg-white #radio-screen .radio-btn svg, .bg-white #radio-screen .set-title-ico, .bg-white #radio-screen .pause-icon svg { fill: #2b2b2b; filter: drop-shadow(0 2px 6px rgba(255, 255, 255, 0.6)); }
.bg-white #radio-screen svg [stroke] { stroke: #2b2b2b; }
.bg-white #radio-screen .radio-main { border-color: rgba(43, 43, 43, 0.9); }
.bg-white #radio-screen .radio-main svg { filter: none; } /* after the re-ink rule above, which it outranked by order alone */
.bg-white #radio-screen .radio-toggle .dot { background: #2b2b2b; }
.bg-white #radio-screen .rule { background: rgba(0, 0, 0, 0.35); }
.bg-white #wear-screen #wear-close svg { fill: #2b2b2b; filter: drop-shadow(0 2px 6px rgba(255, 255, 255, 0.6)); } /* the wardrobe's Back in the look and radio menus' dark ink on the white theme (author, 2026-09-24: "in light mode have the back arrow in the clothes menu black for consistency") */
.bg-white #wear-screen #wear-close svg [stroke] { stroke: #2b2b2b; }
.bg-white #pause-screen .pause-icon svg { fill: #2b2b2b; filter: drop-shadow(0 2px 6px rgba(255, 255, 255, 0.6)); }
.bg-white #pause-screen .pause-icon svg [stroke] { stroke: #2b2b2b; }
.bg-white #pause-screen .pause-corner { opacity: 0.38; }
.bg-white #pause-screen .pause-corner:hover, .bg-white #pause-screen .pause-corner:active { opacity: 0.7; }

/* ------------------------------------------------- programme orchestrator
   An authoring surface inside the gallery: drag cards to reorder the bill,
   drag one into the wings (right column) to bench it, drag it back to
   reinstate it. TODO: hide for the real Poki port. */
#orch-toggle { grid-column: 1 / -1; justify-self: center; margin: 4px 0 8px; }
#notebook-btn { grid-column: 1 / -1; justify-self: center; margin: -4px 0 10px; opacity: 0.8; }
/* THE NOTEBOOK (dev only): the idea list on ruled paper, over the gallery */
#notebook { position: fixed; inset: 4vh 0 4vh 0; margin: 0 auto; width: min(760px, 94vw); z-index: 70; background: #fbf6e9; color: #2b2116; border-radius: 6px; box-shadow: 0 18px 50px rgba(0, 0, 0, 0.45); font: 14px/1.5 "Times New Roman", Times, serif; display: flex; flex-direction: column; overflow: hidden; }
#notebook .nb-head { display: flex; align-items: baseline; gap: 14px; padding: 14px 54px 10px 22px; border-bottom: 2px solid #d8c9a6; position: relative; }
#notebook .nb-head b { letter-spacing: 0.12em; font-size: 15px; }
#notebook .nb-head span { font-size: 12.5px; color: #7a6646; }
#notebook .nb-close { position: absolute; right: 10px; top: 8px; color: #2b2116; opacity: 0.75; font-size: 26px; line-height: 1; background: transparent; border: 0; cursor: pointer; }
#notebook .nb-close:hover { opacity: 1; color: #b8321e; }
#notebook .nb-list { flex: 1; overflow-y: auto; margin: 0; padding: 6px 22px 18px 44px; background: repeating-linear-gradient(transparent 0 27px, rgba(120, 90, 40, 0.16) 27px 28px); counter-reset: nb; }
#notebook .nb-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; min-height: 28px; padding: 3px 0; border-bottom: 0; }
#notebook .nb-row input[type="checkbox"] { width: 15px; height: 15px; margin: 0 2px 0 0; accent-color: #b8321e; }
#notebook .nb-row.done .nb-text { text-decoration: line-through; color: #8a7a62; }
#notebook .nb-row.auto .nb-text { color: #4c3d27; }
#notebook .nb-text { flex: 0 1 auto; }
#notebook .nb-badge { font-style: normal; font-size: 11px; line-height: 16px; padding: 0 7px; border-radius: 8px; background: #e6dcc4; color: #5a4a30; white-space: nowrap; }
#notebook .nb-badge.bill { background: #2e7d32; color: #fff; }
#notebook .nb-badge.wings { background: #c9a24a; color: #2b2116; }
#notebook .nb-badge.retired { background: #b8321e; color: #fff; cursor: pointer; }
#notebook .nb-badge.gone { background: #999; color: #fff; }
#notebook .nb-badge.dropped { background: #6b6560; color: #fff; }
#notebook .nb-row.dropped .nb-text { text-decoration: line-through; color: #a89c88; }
#notebook .nb-row.dropped input[type="checkbox"], #notebook .nb-row.dropped .nb-mine { opacity: 0.4; }
#notebook .nb-x { width: 18px; height: 18px; line-height: 16px; padding: 0; border: 1px solid #c9b995; border-radius: 50%; background: #f4ecd8; color: #7a3a2a; font: 11px/16px "Times New Roman", Times, serif; cursor: pointer; }
#notebook .nb-x:hover { background: #b8321e; color: #fff; border-color: #b8321e; }
.wing-card.unlisted .cap::after { content: " · no row"; color: #ffb347; font-size: 9px; }
#notebook .nb-note { font-size: 12px; color: #8a7a62; }
#notebook .nb-mine { flex: 1 1 120px; min-width: 90px; border: 0; border-bottom: 1px dotted #b9a781; background: transparent; font: 12.5px "Times New Roman", Times, serif; color: #2b2116; padding: 1px 4px; }
#notebook .nb-mine:focus { outline: none; border-bottom-color: #b8321e; }
#notebook .nb-foot { padding: 10px 22px 14px; border-top: 2px solid #d8c9a6; font-size: 12.5px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
#notebook .nb-foot b { letter-spacing: 0.1em; margin-right: 6px; }
#gallery-screen.orch #gallery-grid { width: min(1000px, calc(93vw - 170px)); margin-right: 160px; }
#gallery-screen.orch .gallery-card { cursor: grab; touch-action: none; }
#orch-wings {
  position: fixed; top: 66px; bottom: 56px; right: 10px; width: 148px;
  display: flex; flex-direction: column; gap: 10px;
  padding: 10px 8px; overflow-y: auto; z-index: 18;
  border: 1px dashed rgba(255, 255, 255, 0.5); border-radius: 6px;
  background: rgba(0, 0, 0, 0.12);
}
#orch-wings.over { border-color: #ffffff; background: rgba(255, 255, 255, 0.12); }
.wings-head {
  font-size: 11px; letter-spacing: 0.3em; text-indent: 0.3em;
  text-align: center; opacity: 0.7; font-weight: 700;
}
.wing-card .cap { font-size: 10.5px; }
.drag-ghost {
  position: fixed; z-index: 40; width: 150px; pointer-events: none;
  transform: translate(-50%, -50%) rotate(-3deg); opacity: 0.85;
}

/* live filing marker: the bright edge is exactly where the card will land */
.gallery-card.drop-before { box-shadow: -5px 0 0 0 #ffffff; }
.gallery-card.drop-after { box-shadow: 5px 0 0 0 #ffffff; }
.gallery-card.dragging { opacity: 0.35; }

/* stage-edit footer */
#edit-hint {
  position: absolute; left: 0; right: 0;
  bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  text-align: center; pointer-events: none; z-index: 8;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}
#edit-hint .keys {
  font-size: 12.5px; letter-spacing: 0.08em; opacity: 0.75;
  font-variant: normal;
}
#edit-hint .vals {
  font-size: 12px; letter-spacing: 0.12em; opacity: 0.9;
  font-variant: normal; margin-top: 3px; min-height: 15px;
  color: #ffe9a8;
}
.bg-white #edit-hint { color: #2b2b2b; text-shadow: 0 1px 4px rgba(255, 255, 255, 0.7); }
.bg-white #edit-hint .vals { color: #7a5a00; }

/* settings menu iconography */
.set-title-ico { display: block; width: 42px; height: 42px; fill: #ffffff; margin: 0 auto; }
.set-ico { width: 36px; height: 36px; fill: #ffffff; flex: none; }

/* ------------------------------------------- the grey's pause menu ink */
/* on the grey backdrop (the default now) the pause menu's icons and the
   level selection are BLACK (author, 2026-09-06); the in-level corner
   buttons keep their white */
.bg-grey #pause-screen .pause-icon svg { fill: #111111; filter: none; }
.bg-grey #pause-screen .pause-icon svg [stroke] { stroke: #111111; }
.bg-grey #pause-screen .pause-corner { opacity: 0.55; }
.bg-grey #pause-screen .pause-corner:hover, .bg-grey #pause-screen .pause-corner:active { opacity: 0.85; }
.bg-grey #level-nav button { color: #e8906a; -webkit-text-stroke: 0.045em #e8906a; } /* the light theme's tan, a shade darker, on the grey (author, 2026-09-13: "the same tan color as light mode", then "slightly darker only for dark mode") */
.bg-grey #level-nav button:hover { color: #e8906a; }
.bg-grey #lvl-num, .bg-grey #pause-name { color: #e8906a; }
.bg-grey #pause-skip { color: #111111; }
.bg-white #pause-skip { color: #2b2b2b; }

/* ------------------------------------------------------ the dev panel */
#dev-screen {
  position: fixed; top: calc(8px + env(safe-area-inset-top, 0px) + clamp(54px, 11vw, 78px) + 8px);
  right: calc(10px + env(safe-area-inset-right, 0px));
  z-index: 6; width: min(300px, calc(100vw - 20px));
  padding: 14px 16px 16px; border-radius: 10px;
  background: rgba(20, 20, 20, 0.82); color: #f2f2f2;
  font: 15px/1.4 ui-monospace, Menlo, monospace; letter-spacing: 0;
  display: flex; flex-direction: column; gap: 10px; align-items: stretch;
  pointer-events: auto;
}
#dev-screen .dev-title { font-size: 13px; opacity: 0.7; letter-spacing: 0.08em; }
#dev-screen .dev-scope { display: flex; gap: 8px; }
#dev-screen .dev-scope button, #dev-screen #dev-zoom-clear {
  flex: 1; background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.2);
  color: #f2f2f2; padding: 7px 10px; border-radius: 6px; cursor: pointer;
  font: inherit; letter-spacing: 0; text-indent: 0;
}
#dev-screen .dev-scope button.sel { background: #d4651a; border-color: #d4651a; color: #fff; }
#dev-screen input[type="range"] { width: 100%; accent-color: #d4651a; }
#dev-screen #dev-zoom-val, #dev-screen #dev-slip-val { font-size: 13px; opacity: 0.85; }
#dev-screen .dev-slip-title { margin-top: 6px; }
#dev-screen #dev-slip-clear { flex: none; background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.2); color: #f2f2f2; padding: 7px 10px; border-radius: 6px; cursor: pointer; font: inherit; letter-spacing: 0; text-indent: 0; }
/* the slider greys on a subject that is not slippery: the skate has nothing to push */
#dev-screen.no-slip #dev-slip, #dev-screen.no-slip #dev-slip-val, #dev-screen.no-slip .dev-slip-title { opacity: 0.32; pointer-events: none; }
#dev-screen.no-stab #dev-stab, #dev-screen.no-stab #dev-stab-val, #dev-screen.no-stab .dev-stab-title { opacity: 0.32; pointer-events: none; }
#dev-screen.no-birds #dev-birds, #dev-screen.no-birds #dev-birds-val, #dev-screen.no-birds .dev-birds-title { opacity: 0.32; pointer-events: none; }
#dev-screen #dev-close {
  position: absolute; top: 4px; right: 8px; background: none; border: none;
  color: #f2f2f2; font: 22px/1 "Times New Roman", Times, serif; cursor: pointer; padding: 2px 6px;
}
@media (max-width: 700px) {
  #dev-screen { top: calc(8px + env(safe-area-inset-top, 0px) + 86px + 62px); }
}

/* ------------------------------------------------ the thought bubble */
/* the bubble's own voice: Bowlby One (Vernon Adams, OFL — see
   assets/fonts/CREDITS.txt), a fat early-1900s display face */
@font-face {
  font-family: "Bowlby One";
  src: url("../assets/fonts/BowlbyOne-Regular.ttf") format("truetype");
  font-weight: 400; font-style: normal; font-display: swap;
}
/* pinned to the face's screen spot by frame(): a LOW-POLY cloud (a
   twenty-cornered polygon, straight edges, lumpy like a paper cut-out) up
   and to the right, two shrinking hexagons trailing back toward the meat.
   It FORMS: the small dot pops, then the big one, then the cloud swells out
   of them with an overshoot — each a fresh run of its keyframes whenever
   the bubble comes back from display:none. Everything the cloud holds — a
   line of text, or the picture — is clipped to its outline. */
#thought {
  position: fixed; left: 0; top: 0; z-index: 3; pointer-events: none;
  will-change: transform;
}
#thought .cloud {
  position: absolute; left: 20px; bottom: 20px;
  box-sizing: border-box;
  max-width: min(72vw, 330px); min-width: 200px; /* Bowlby is fat: room for three rows, not five */
  padding: 26px 34px 28px; /* the lobes cut in to ~14% of each side: the text box stays inside them */
  background: #ffffff; color: #2a1208;
  font: 400 clamp(13px, 2.1vw, 18px)/1.18 "Bowlby One", "Arial Black", Impact, sans-serif;
  letter-spacing: 0.02em; text-align: center;
  white-space: normal; overflow: hidden;
  clip-path: polygon(3% 56%, 9% 22%, 30% 5%, 55% 3%, 78% 4%, 97% 24%, 98% 62%, 83% 95%, 50% 98%, 16% 94%); /* ten corners — half the cut-out's points (author, 2026-09-06) */
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.18));
  transform-origin: 8% 92%;
  animation: cloud-form 0.5s cubic-bezier(0.2, 0.9, 0.25, 1.25) both;
  animation-delay: 0.16s;
}
#thought .cloud .txt { display: block; position: relative; z-index: 1; }
#thought .d1, #thought .d2 {
  position: absolute; background: #ffffff;
  clip-path: polygon(50% 0, 95% 25%, 95% 75%, 50% 100%, 5% 75%, 5% 25%);
  filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.18));
  animation: dot-form 0.22s cubic-bezier(0.2, 0.9, 0.3, 1.3) both;
}
#thought .d1 { width: 9px; height: 9px; left: 0; top: -8px; }
#thought .d2 { width: 15px; height: 15px; left: 9px; top: -24px; animation-delay: 0.08s; }
@keyframes dot-form { from { opacity: 0; transform: scale(0.2); } to { opacity: 1; transform: scale(1); } }
@keyframes cloud-form {
  0% { opacity: 0; transform: scale(0.15, 0.3); }
  55% { opacity: 1; transform: scale(1.06, 0.94); }
  75% { transform: scale(0.97, 1.03); }
  100% { opacity: 1; transform: scale(1, 1); }
}
/* the picture thought: the cloud becomes a window onto the picture, the
   picture's edges faded into the cloud's white, all of it clipped to the
   cloud's low-poly outline */
#thought .cloud .pic { display: none; }
#thought.pic-mode .cloud { width: min(44vw, 200px); height: min(38vw, 170px); padding: 0; min-width: 0; }
#thought.pic-mode .cloud .txt { display: none; }
#thought.pic-mode .cloud .pic {
  display: block; position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
  -webkit-mask-image: radial-gradient(ellipse at center, #000 40%, rgba(0, 0, 0, 0.55) 58%, transparent 74%);
  mask-image: radial-gradient(ellipse at center, #000 40%, rgba(0, 0, 0, 0.55) 58%, transparent 74%);
}
/* a product CUT-OUT on white (the bun, the mustard, the trophy; `.cutout`
   from THOUGHT_CUTOUTS) is shown whole: contained, inset from the lobes,
   no fade — cover cropped the bottle's cap and the trophy's handles and the
   fade took more (author, 2026-09-13: "so they aren't cut off"); the cake
   and the beach keep the cover and the fade */
#thought.pic-mode .cloud .pic.cutout {
  inset: 9% 12%; width: 76%; height: 82%;
  object-fit: contain; object-position: center;
  -webkit-mask-image: none; mask-image: none;
}
.bg-white #thought .cloud, .bg-white #thought .d1, .bg-white #thought .d2 { background: #fbfbfb; filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.3)); }

/* ------------------------------------------------ the mini-games */
/* a caged subject's lock opens one of these over the frozen table: the
   kitchen grey, the sausage orange, Bowlby One — the HUD's own dress */
#mini {
  position: fixed; inset: 0; z-index: 7;
  background: rgba(40, 40, 40, 0.92);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: calc(10px + env(safe-area-inset-top, 0px)) 12px calc(12px + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px));
  box-sizing: border-box; color: #f2f2f2; touch-action: none; user-select: none; -webkit-user-select: none;
  font-family: "Bowlby One", "Times New Roman", Times, serif;
}
#mini.hidden { display: none; }
#mini .mini-head { position: relative; width: min(92vw, 560px); text-align: center; padding: 0 44px; box-sizing: border-box; }
#mini .mini-title { font-size: clamp(22px, 5vw, 34px); color: #d4651a; letter-spacing: 0.01em; }
#mini .mini-sub { font-size: clamp(16px, 3.6vw, 22px); opacity: 0.85; min-height: 1.3em; }
#mini .mini-close {
  position: absolute; top: -4px; right: 0; width: 40px; height: 40px; border-radius: 50%;
  background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.25); color: #f2f2f2;
  font: 26px/1 "Times New Roman", Times, serif; cursor: pointer; padding: 0; text-indent: 0; letter-spacing: 0;
}
#mini .mini-board { width: min(92vw, 560px, calc(100vh - 220px)); aspect-ratio: 1 / 1; touch-action: none; }
#mini.has-pad .mini-board { width: min(92vw, 560px, calc(100vh - 330px)); }
#mini .mini-pad { display: none; flex-direction: column; align-items: center; gap: 6px; }
#mini.has-pad .mini-pad { display: flex; }
#mini .mini-pad > div { display: flex; gap: 6px; }
#mini .mini-pad button {
  width: 58px; height: 46px; border-radius: 10px; background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.25); color: #f2f2f2; font: 18px/1 sans-serif; cursor: pointer;
  padding: 0; text-indent: 0; letter-spacing: 0; touch-action: none;
}
#mini .mini-pad button:active { background: #d4651a; border-color: #d4651a; }
@media (hover: hover) and (pointer: fine) { #mini .mini-pad { display: none !important; } }
/* the hint under a locked cage: "Tap the cage" */
#gate-hint {
  position: fixed; left: 50%; bottom: calc(18px + env(safe-area-inset-bottom, 0px) + var(--ad-h, 0px)); transform: translateX(-50%);
  z-index: 5; padding: 8px 16px; border-radius: 20px; background: rgba(20, 20, 20, 0.6); color: #f2f2f2;
  font: 500 clamp(15px, 3.4vw, 20px)/1.2 "Bowlby One", "Times New Roman", Times, serif; letter-spacing: 0.01em;
  pointer-events: none; animation: gate-pulse 1.6s ease-in-out infinite;
}
#gate-hint.hidden { display: none; }
@keyframes gate-pulse { 0%, 100% { opacity: 0.75; } 50% { opacity: 1; } }

/* the wings' retire cross (orchestrator only): a candidate leaves the hero
   pack for cold storage — see retireCandidate and scripts/dev-server.mjs */
.wing-card { position: relative; }
.wing-card .retire {
  position: absolute; top: 2px; right: 2px; width: 20px; height: 20px; border-radius: 50%;
  background: rgba(0, 0, 0, 0.55); color: #fff; font: 15px/20px "Times New Roman", Times, serif; text-align: center;
  cursor: pointer; opacity: 0.6; letter-spacing: 0; text-indent: 0;
}
.wing-card .retire:hover { opacity: 1; background: #b8321e; }
/* the question on the card (retire? ✓ ✕) and the answer as a toast — no
   window.confirm/alert: embedded hosts swallow them (2026-09-09) */
.wing-card .ask { position: absolute; left: 2px; right: 2px; top: 2px; display: flex; align-items: center; justify-content: center; gap: 6px; height: 24px; border-radius: 12px; background: rgba(0, 0, 0, 0.8); color: #fff; font: 11px/24px "Times New Roman", Times, serif; z-index: 2; }
.wing-card .ask b { font-weight: normal; letter-spacing: 0.02em; }
.wing-card .ask i { font-style: normal; width: 20px; height: 20px; line-height: 20px; border-radius: 50%; text-align: center; cursor: pointer; background: rgba(255, 255, 255, 0.18); }
.wing-card .ask i.yes:hover { background: #b8321e; }
.wing-card .ask i.no:hover { background: #555; }
.wing-card .ask.busy i { visibility: hidden; }
#orch-toast { position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 12px); max-width: min(640px, 90vw); padding: 9px 16px; border-radius: 10px; background: rgba(20, 16, 12, 0.92); color: #f4e9d8; font: 13px/1.4 "Times New Roman", Times, serif; z-index: 60; opacity: 0; pointer-events: none; transition: opacity 0.25s, transform 0.25s; }
#orch-toast.on { opacity: 1; transform: translate(-50%, 0); }

/* THE AUDITIONS (orchestrator only, dev only): the column LEFT of the slate,
   mirroring the wings — sourced, judged, levelled models not yet in the
   hero pack. ▲ promotes (or drag onto the bill / into the wings), × rejects,
   a tap plays it in edit dress. See renderAuditions in main.js. */
#gallery-screen.orch.auditions #gallery-grid { width: min(1000px, calc(93vw - 330px)); margin-left: 160px; }
#orch-auditions {
  position: fixed; top: 66px; bottom: 56px; left: 10px; width: 148px;
  display: flex; flex-direction: column; gap: 10px;
  padding: 10px 8px; overflow-y: auto; z-index: 18;
  border: 1px dashed rgba(255, 214, 120, 0.55); border-radius: 6px;
  background: rgba(60, 40, 0, 0.14);
}
#orch-auditions .wings-head { color: #ffd678; }
.audition-card .sub { font-size: 9px; opacity: 0.6; letter-spacing: 0.04em; padding: 0 4px 6px; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wing-card .retire.promote { right: 24px; font-size: 11px; }
.wing-card .retire.promote:hover { background: #2e7d32; }
@media (max-width: 1100px) { #orch-auditions { width: 120px; } #gallery-screen.orch.auditions #gallery-grid { margin-left: 130px; width: min(1000px, calc(93vw - 300px)); } }

/* ------------------------------------------------ the nightclub */
/* the disco ball's show (see THE CLUB in main.js): the backdrop goes to a
   dark violet with a slow hue drift; the chrome stays the grey's black ink */
body.bg-club { background: radial-gradient(ellipse at 50% 30%, #2a1040 0%, #0c0616 60%, #05030a 100%); animation: club-hue 6s linear infinite; }
@keyframes club-hue { 0% { filter: hue-rotate(0deg); } 100% { filter: hue-rotate(360deg); } }

/* THE TOUCH RING: the finger's own cursor — a ring under any touch pointer the page hears, gone a beat after the lift (2026-09-12) */
#touch-ring { position: fixed; left: 0; top: 0; width: 30px; height: 30px; margin: -15px 0 0 -15px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, 0.85); background: rgba(0, 0, 0, 0.18); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35); pointer-events: none; z-index: 40; }
#touch-ring.hidden { display: none; }

/* "Skip?" stands in the corner or flies: the pause button wears the tan with
   it, at full strength — the EVENT's colour only (author, 2026-09-13:
   "temporary, only during the skip event and UI not darkened"); once the
   offer lands in the menu the button is white again and the menu entry
   wears the menu's own ink. The white backdrop's dark ink yields to it too. */
#pause-btn.skipping, .bg-white #pause-btn.skipping { opacity: 1; }
#pause-btn.skipping svg, .bg-white #pause-btn.skipping svg { fill: #d4651a; }
.bg-white #skip-btn.shown { color: #d4651a; opacity: 1; }
/* …and FADES back to the white over the offer's last second (author,
   2026-09-13, third note: "make the tan fade back to the normal color when
   the skip event finishes"): the class rides the button for 1.2 s */
#pause-btn.tan-fade { transition: opacity 1s ease; }
#pause-btn.tan-fade svg { transition: fill 1s ease; }
/* THE OFFER'S TWO LINES: "▶ Watch Ad" bold over "to skip donut" smaller,
   centred (the author's mockup, 2026-09-13) — the pause menu's entry; the
   corner says "Skip?" alone and its tap opens the menu */
#pause-skip { display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1.05; }
#pause-skip .ad-head { font-weight: 700; white-space: nowrap; display: inline-flex; align-items: center; gap: 0.3em; }
#pause-skip .ad-play { width: 0.72em; height: 0.72em; display: block; } /* the play glyph in the entry's ink (2026-09-21) */
#pause-skip .ad-sub { font-size: 0.74em; white-space: nowrap; margin-top: 0.12em; }

/* THE SLEEP: three Zs rising from beside the face, on a loop */
#zzz { position: fixed; left: 0; top: 0; width: 0; height: 0; z-index: 12; pointer-events: none; font-family: "Bowlby One", "Times New Roman", serif; color: #2b2116; }
#zzz.hidden { display: none; }
#zzz span { position: absolute; left: 0; bottom: 0; opacity: 0; animation: zzz-rise 2.4s ease-out infinite; }
#zzz span:nth-child(1) { font-size: 24px; animation-delay: 0s; }
#zzz span:nth-child(2) { font-size: 32px; animation-delay: 0.8s; }
#zzz span:nth-child(3) { font-size: 42px; animation-delay: 1.6s; }
@keyframes zzz-rise { 0% { opacity: 0; transform: translate(0, 0) scale(0.6); } 20% { opacity: 0.9; } 100% { opacity: 0; transform: translate(26px, -60px) scale(1.25); } }

/* ------------------------------------------------ THE TOUCH SURFACE
   (author, 2026-09-24, on TestFlight build 4: "sometimes when moving the pan
   something is being highlighted as if there was text there … check for
   other highlighting bugs too; after a button is pressed, make the darkening
   fade back into the button's normal colour"). A phone is not a mouse:
   - nothing is selectable or draggable but a text field — WebKit starts a
     text selection (the blue box, the loupe) from a long press anywhere a
     text node lies under the finger, the title card's words, a caption, the
     thought bubble; a picture long-pressed lifts for a drag or opens the
     share callout (the wardrobe's items, the gallery's portraits, the stills)
   - main.js rewrites every :hover rule as :active on a device with no hover
     (a tapped button kept its hover look — the dark ink of the plain button's
     white fill — until the next tap anywhere), so a press shows while the
     finger is down, and the RELEASE fades back slowly: the rules below give
     the return 0.4 s, the press keeps each button's own quick transition */
*, *::before, *::after { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
input, textarea, [contenteditable="true"] { -webkit-user-select: text; user-select: text; }
img, canvas, svg { -webkit-user-drag: none; }
::selection { background: transparent; }
input::selection, textarea::selection { background: rgba(232, 144, 106, 0.45); }
@media (hover: none) {
  button:not(:active), .pause-corner:not(:active), .pause-icon:not(:active), .radio-btn:not(:active), .lang-pick:not(:active), [role="button"]:not(:active),
  #retry-btn:not(:active), #mute-btn:not(:active), #dev-btn:not(:active), #pause-btn:not(:active):not(.tan-fade):not(.skipping),
  #wear-grid button:not(:active), #wear-ask button:not(:active), #level-nav button:not(:active), #shoot-nav button:not(:active), #wear-nav button:not(:active), #lvl-results button:not(:active) { transition-duration: 0.4s; }
}
/* "more" takes its touches itself (native.js: the TestFlight hold), so its press look is a class */
.bg-grey #pause-screen #pause-more-btn.pressed { opacity: 0.85; }
.bg-white #pause-screen #pause-more-btn.pressed { opacity: 0.7; }

/* THE SUN AND THE CRESCENT (author, 2026-09-24: "a crescent moon and sun that
   switches"): the look menu's icon shows the theme in force — the sun on the
   light, the moon on the dark (auto resolves first) — and a change turns one
   out and the other in, spun a quarter and shrunk, with a little overshoot */
.theme-ico .sun, .theme-ico .moon { transform-box: view-box; transform-origin: 16px 16px; transition: opacity 0.4s ease, transform 0.5s cubic-bezier(0.3, 1.45, 0.5, 1); }
.theme-ico .sun { opacity: 0; transform: rotate(-90deg) scale(0.4); }
.bg-white .theme-ico .sun { opacity: 1; transform: none; }
.bg-white .theme-ico .moon { opacity: 0; transform: rotate(90deg) scale(0.4); }

/* THE CREDITS PAGE drawn from the index (2026-09-24): a licence a heading, its
   works under it, the music and "everything else" as quiet notes */
#credits h3 { font-size: 13px; font-weight: 600; letter-spacing: 0.14em; opacity: 0.7; margin: 22px 0 6px; }
#credits .credits-note { font-size: 14px; line-height: 1.45; opacity: 0.85; margin: 14px 0; }
