/* OBEY? LOL. — visual identity: "official memo vs. toy box".
 * Bossworth issues instructions on paper slips with ink outlines and hard shadows;
 * the player answers with rubber stamps. Themes only swap the tokens below. */

@font-face { font-family: 'Bagel Fat One'; src: url('../assets/fonts/bagel-fat-one-latin.woff2') format('woff2'); font-display: swap; }
@font-face { font-family: 'Atkinson Hyperlegible'; src: url('../assets/fonts/atkinson-hyperlegible-400.woff2') format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Atkinson Hyperlegible'; src: url('../assets/fonts/atkinson-hyperlegible-700.woff2') format('woff2'); font-weight: 700; font-display: swap; }

/* ------------------------------------------------------------------ tokens */
:root, [data-theme="classic"] {
  --bg: #aab3ff;
  --bg-2: #96a0f7;
  --paper: #fffdf6;
  --paper-2: #f1efff;
  --ink: #1c1640;
  --muted: #514a7a;
  --accent: #d61e35;       /* stamp red (4.5:1 with white and on paper) */
  --accent-ink: #ffffff;
  --accent-2: #ffde3b;     /* highlighter */
  --good: #0e8456;
  --stage: #eef0ff;
  --stage-floor: #d9dcfb;
  --on-bg: #1c1640;
  --region-1: rgba(255, 222, 59, .28);
  --region-2: rgba(255, 255, 255, .30);
  --region-3: rgba(229, 36, 59, .14);
  --region-4: rgba(62, 193, 255, .14);
}
[data-theme="candy"] {
  --bg: #ffb7dc; --bg-2: #ff9bcd; --paper: #fff8fc; --paper-2: #ffe8f4; --ink: #3b0d34; --muted: #7a3a6c;
  --accent: #c2127a; --accent-ink: #fff; --accent-2: #8fe9ff; --good: #0d8059;
  --stage: #fff0f8; --stage-floor: #ffd6ec; --on-bg: #3b0d34;
  --region-1: rgba(143, 233, 255, .35); --region-2: rgba(255, 255, 255, .35); --region-3: rgba(194, 18, 122, .14); --region-4: rgba(143, 233, 255, .22);
}
[data-theme="ocean"] {
  --bg: #7dd3ea; --bg-2: #62c2de; --paper: #f5feff; --paper-2: #dff6fb; --ink: #072f3d; --muted: #2e5b69;
  --accent: #c4401e; --accent-ink: #fff; --accent-2: #ffe066; --good: #0c7a57;
  --stage: #e3f7fc; --stage-floor: #c4ecf6; --on-bg: #072f3d;
  --region-1: rgba(255, 224, 102, .35); --region-2: rgba(255, 255, 255, .35); --region-3: rgba(226, 80, 43, .14); --region-4: rgba(42, 157, 143, .14);
}
[data-theme="sunset"] {
  --bg: #47205a; --bg-2: #6b2a63; --paper: #fff3e8; --paper-2: #ffe2cc; --ink: #2a1230; --muted: #6b4060;
  --accent: #cf2850; --accent-ink: #fff; --accent-2: #ffc145; --good: #10805a;
  --stage: #ffeadb; --stage-floor: #ffd2b5; --on-bg: #fff3e8;
  --region-1: rgba(255, 193, 69, .30); --region-2: rgba(255, 122, 84, .30); --region-3: rgba(232, 53, 95, .30); --region-4: rgba(255, 193, 69, .16);
}

:root {
  --font-display: 'Bagel Fat One', 'Arial Rounded MT Bold', 'Trebuchet MS', system-ui, sans-serif;
  --font-body: 'Atkinson Hyperlegible', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --line: 3px;
  --shadow: 5px 5px 0 var(--ink);
  --shadow-sm: 3px 3px 0 var(--ink);
  --shadow-hover: 4px 4px 0 var(--ink);
  --shadow-press: 1px 1px 0 var(--ink);
  --r-lg: 22px;
  --r-md: 14px;
  --r-sm: 9px;
  --fs: 17px;
  --tap: 48px;
}
[data-text="large"] { --fs: 20px; }

/* ------------------------------------------------------------------- base */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  font-family: var(--font-body);
  font-size: var(--fs);
  line-height: 1.5;
  color: var(--ink);
  background-color: var(--bg);
  background-image:
    radial-gradient(var(--bg-2) 1.6px, transparent 1.8px),
    radial-gradient(var(--bg-2) 1.6px, transparent 1.8px);
  background-size: 26px 26px;
  background-position: 0 0, 13px 13px;
  overflow-x: hidden;
}
[data-theme="sunset"] body, html[data-theme="sunset"] body {
  background-image: radial-gradient(rgba(255,193,69,.18) 1.6px, transparent 1.8px), linear-gradient(180deg, #2c1340 0%, #6b2a63 55%, #a8455f 100%);
  background-size: 26px 26px, 100% 100%;
  background-attachment: scroll, fixed;
}
button, input { font: inherit; color: inherit; }
h1, h2, h3 { line-height: 1.15; margin: 0 0 .4em; }
p { margin: 0 0 .7em; }
.small { font-size: .85em; color: var(--muted); }
[hidden] { display: none !important; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip-link { position: absolute; left: 8px; top: -60px; z-index: 1000; background: var(--paper); padding: 8px 14px; border: var(--line) solid var(--ink); border-radius: var(--r-sm); }
.skip-link:focus { top: 8px; }
:focus-visible { outline: 4px solid var(--accent-2); outline-offset: 3px; box-shadow: 0 0 0 7px var(--ink); border-radius: 6px; }
[tabindex="-1"]:focus { outline: none; box-shadow: none; }
.icon { width: 1.25em; height: 1.25em; flex: none; vertical-align: -0.25em; }

.app { max-width: 1240px; margin: 0 auto; padding: 14px 16px 40px; padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(16px, env(safe-area-inset-right)); }
.boot { font-family: var(--font-display); font-size: 1.4rem; text-align: center; padding: 40vh 0; color: var(--on-bg); }
.panel { background: var(--paper); border: var(--line) solid var(--ink); border-radius: var(--r-lg); box-shadow: var(--shadow); padding: 18px 20px; }

/* ---------------------------------------------------------------- buttons */
.btn, .chip-btn, .slip {
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  min-height: var(--tap); padding: .45em 1.05em;
  border: var(--line) solid var(--ink); border-radius: var(--r-md);
  background: var(--paper); color: var(--ink);
  font-weight: 700; cursor: pointer; text-decoration: none;
  box-shadow: var(--shadow-sm);
  transition: transform .08s ease, box-shadow .08s ease;
  touch-action: manipulation;
}
.btn:hover, .chip-btn:hover, .slip:hover { transform: translate(-1px, -1px); box-shadow: var(--shadow-hover); }
.btn:active, .chip-btn:active, .slip:active { transform: translate(2px, 2px); box-shadow: var(--shadow-press); }
.btn.primary, .slip-primary { background: var(--accent); color: var(--accent-ink); }
.btn.danger { background: var(--ink); color: var(--paper); }
.btn.ghost { background: transparent; box-shadow: none; border-style: dashed; }
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 14px; }
.btn-row.center { justify-content: center; }
.chip-btn { min-height: 44px; padding: .3em .8em; border-radius: 999px; font-size: .92em; background: var(--paper); }
.chip-btn.icon-only { padding: .3em .6em; }
.pill { display: inline-flex; align-items: center; gap: .3em; background: var(--paper); border: var(--line) solid var(--ink); border-radius: 999px; padding: .15em .7em; font-weight: 700; color: var(--ink); }
.pill .icon { color: var(--accent-2); }

/* ------------------------------------------------------------------ topbar */
.topbar { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.topbar .screen-title { font-family: var(--font-display); font-weight: 400; font-size: clamp(1.6rem, 4vw, 2.3rem); margin: 0; color: var(--on-bg); flex: 1 1 auto; min-width: 0; }
.topbar-end { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }

/* ------------------------------------------------------------------- menu */
.menu-layout { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 32px; align-items: center; min-height: calc(100dvh - 60px); }
.logo { font-family: var(--font-display); font-weight: 400; margin: 0 0 8px; line-height: .86; display: inline-flex; flex-direction: column; align-items: flex-start; max-width: 100%; }
.logo-obey {
  font-size: clamp(4.2rem, 15vw, 9.5rem); color: var(--paper);
  -webkit-text-stroke: 4px var(--ink); paint-order: stroke fill;
  text-shadow: 7px 7px 0 var(--ink); letter-spacing: -.02em;
}
.logo-lol {
  font-size: clamp(2.6rem, 9vw, 5.6rem); color: var(--accent-ink); background: var(--accent);
  border: 5px solid var(--accent); outline: 3px solid var(--ink); outline-offset: -11px;
  padding: .02em .28em .1em; border-radius: 12px; align-self: flex-end; margin: -.18em -.1em 0 0; transform: rotate(-7deg);
  box-shadow: 6px 6px 0 var(--ink); animation: stamp-in .5s cubic-bezier(.2, 1.6, .4, 1) .2s both;
}
.tagline { font-size: 1.15em; max-width: 34ch; color: var(--on-bg); font-weight: 700; margin: 6px 0 18px; }
.menu-narrator { display: flex; align-items: flex-end; gap: 10px; margin-bottom: 18px; }
.narrator-mini { width: 110px; flex: none; }
.narrator-mini svg { width: 100%; height: auto; display: block; }
.bubble { position: relative; background: var(--paper); border: var(--line) solid var(--ink); border-radius: var(--r-lg); padding: 12px 16px; box-shadow: var(--shadow-sm); margin: 0; max-width: 40ch; }
.bubble .speaker { display: block; font-family: var(--font-display); font-size: .85em; color: var(--accent); margin-bottom: 2px; }
.bubble-left::before { content: ''; position: absolute; left: -15px; bottom: 18px; border: 9px solid transparent; border-right: 14px solid var(--ink); }
.stat-row { list-style: none; padding: 0; margin: 0; display: flex; gap: 10px; flex-wrap: wrap; }
.stat-row li { background: var(--paper); border: var(--line) solid var(--ink); border-radius: var(--r-md); padding: 6px 12px; display: flex; align-items: baseline; gap: 6px; }
.stat-row b { font-family: var(--font-display); font-weight: 400; font-size: 1.4em; }
.stat-row span { font-size: .85em; color: var(--muted); }
.menu-nav { display: flex; flex-direction: column; gap: 10px; }
.slip { justify-content: flex-start; width: 100%; padding: .6em 1.1em; font-size: 1.05em; border-radius: var(--r-sm); }
.slip:nth-child(odd) { transform: rotate(-.6deg); }
.slip:nth-child(even) { transform: rotate(.5deg); }
.slip:hover { transform: translate(-1px, -2px) rotate(0); }
.slip em { margin-left: auto; font-style: normal; font-size: .85em; background: var(--paper-2); border: 2px solid var(--ink); border-radius: 999px; padding: 0 .6em; }
.slip-primary { font-family: var(--font-display); font-weight: 400; font-size: 1.45em; padding: .5em 1em; }
.slip-primary em { color: var(--ink); }

/* -------------------------------------------------------------------- map */
.map-layout { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 24px; align-items: start; }
.map-side { position: sticky; top: 16px; display: flex; flex-direction: column; gap: 14px; }
.map-help { margin: 0; color: var(--on-bg); } /* 2.3: muted failed contrast on the page background */
.map-help.strong { color: var(--ink); font-weight: 700; }
.map-scroll { width: 100%; }
.map-world { position: relative; width: 100%; max-width: 640px; margin: 0 auto; background: var(--paper); border: var(--line) solid var(--ink); border-radius: var(--r-lg); box-shadow: var(--shadow); overflow: hidden; }
.map-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.map-path { fill: none; stroke: var(--ink); stroke-width: 7; stroke-dasharray: 2 14; stroke-linecap: round; opacity: .35; }
.map-path-done { fill: none; stroke: var(--accent); stroke-width: 9; stroke-linecap: round; }
.map-dot { display: none; } /* 2.3 E55: the faint dots read as smudges */
.region-label { font-family: var(--font-display); font-size: 17px; fill: var(--ink); opacity: .55; }
.map-node {
  position: absolute; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: none; border: 0; padding: 0; cursor: pointer; min-width: var(--tap); z-index: 2;
}
.node-disc {
  width: clamp(48px, 13vw, 62px); height: clamp(48px, 13vw, 62px); border-radius: 50%; display: grid; place-items: center;
  font-family: var(--font-display); font-size: clamp(1.2rem, 4vw, 1.6rem); background: var(--paper); border: var(--line) solid var(--ink); box-shadow: var(--shadow-sm);
}
.node-title { font-weight: 700; font-size: .78em; background: var(--paper); border: 2px solid var(--ink); border-radius: 8px; padding: 0 6px; white-space: nowrap; max-width: 150px; overflow: hidden; text-overflow: ellipsis; }
.node-stars { display: flex; min-height: 18px; color: #ffd23f; }
.node-stars .icon { width: 17px; height: 17px; }
.node-stars .star-off { color: var(--muted); opacity: 1; }
.node-done .node-disc { background: var(--accent-2); }
.node-open .node-disc { background: var(--paper); }
.node-locked { cursor: not-allowed; }
.node-locked .node-disc { background: var(--paper-2); color: var(--muted); border-style: dashed; box-shadow: none; }
.node-locked .node-title { opacity: 1; color: var(--muted); }
.is-current .node-disc { background: var(--accent); color: var(--accent-ink); animation: bob 1.6s ease-in-out infinite; }
.node-flag { font-size: .72em; font-weight: 700; background: var(--ink); color: var(--paper); border-radius: 6px; padding: 0 6px; }
.map-node:hover .node-disc { transform: scale(1.06); }

/* ------------------------------------------------------------------ pages */
.page { display: flex; flex-direction: column; gap: 18px; }
.page-intro { margin: 0; }
.section-title { font-family: var(--font-display); font-weight: 400; color: var(--on-bg); font-size: 1.6rem; margin: 10px 0 0; }
.bar { height: 16px; border: var(--line) solid var(--ink); border-radius: 999px; background: var(--paper-2); overflow: hidden; }
.bar span { display: block; height: 100%; background: var(--accent); }
.bar.small { height: 11px; border-width: 2px; margin-top: 6px; }
.progress-block p { margin-bottom: 10px; }

.note-grid, .wardrobe-grid, .theme-grid, .ach-list, .ending-grid { list-style: none; padding: 0; margin: 0; display: grid; gap: 16px; }
.note-grid { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.note-card { position: relative; background: var(--paper-2); border: var(--line) dashed var(--ink); border-radius: var(--r-md); padding: 14px 16px 16px; min-height: 140px; }
.note-card.found { background: var(--paper); border-style: solid; box-shadow: var(--shadow-sm); }
.note-card h2 { font-family: var(--font-display); font-weight: 400; font-size: 1.25rem; }
.note-card p { margin: 0; font-size: .95em; }
.note-level { font-size: .8em; font-weight: 700; color: var(--muted); }
.stamp-mini { position: absolute; right: 10px; top: 10px; display: inline-flex; gap: 3px; align-items: center; font-weight: 700; font-size: .8em; color: var(--good); border: 2px solid var(--good); border-radius: 6px; padding: 0 6px; transform: rotate(6deg); }

.wardrobe-grid { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }
.wardrobe-card, .theme-card { background: var(--paper); border: var(--line) solid var(--ink); border-radius: var(--r-lg); padding: 14px; text-align: center; box-shadow: var(--shadow-sm); display: flex; flex-direction: column; align-items: center; gap: 6px; }
.wardrobe-card.selected, .theme-card.selected { outline: 5px solid var(--accent-2); outline-offset: -1px; box-shadow: var(--shadow); }
.wardrobe-card h2, .theme-card h2 { font-family: var(--font-display); font-weight: 400; font-size: 1.3rem; margin: 0; }
.wardrobe-art { width: 120px; height: 120px; }
.wardrobe-art svg { width: 100%; height: 100%; }
.silhouette { filter: grayscale(1) brightness(.35); opacity: .35; }
.status { margin: 0; font-weight: 700; display: inline-flex; gap: 5px; align-items: center; font-size: .92em; }
.status.small { font-weight: 400; }
.locked .status { color: var(--muted); }

.theme-grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.theme-preview { width: 100%; aspect-ratio: 16 / 10; border: var(--line) solid var(--ink); border-radius: var(--r-md); overflow: hidden; background: var(--bg); background-image: radial-gradient(var(--bg-2) 1.5px, transparent 1.7px); background-size: 14px 14px; display: grid; grid-template-rows: 18% 1fr; gap: 6px; padding: 6px; }
.theme-preview[data-theme="sunset"] { background-image: linear-gradient(180deg, #2c1340, #a8455f); }
.tp-bar { background: var(--paper); border: 2px solid var(--ink); border-radius: 6px; grid-column: 1 / -1; }
.theme-preview { grid-template-columns: 1fr 1fr; }
.tp-panel { background: var(--paper); border: 2px solid var(--ink); border-radius: 8px; display: flex; flex-direction: column; gap: 5px; padding: 6px; }
.tp-btn { height: 14px; border: 2px solid var(--ink); border-radius: 5px; background: var(--accent); }
.tp-btn.alt { background: var(--accent-2); }
.tp-stage { background: var(--stage); border: 2px solid var(--ink); border-radius: 8px; display: grid; place-items: center; }
.tp-stage span { width: 40%; aspect-ratio: 1; border-radius: 50%; background: var(--accent); border: 2px solid var(--ink); }
.locked .theme-preview { filter: grayscale(.85); opacity: .6; }

.ach-list { gap: 10px; }
.ach { display: grid; grid-template-columns: auto 1fr auto; gap: 14px; align-items: center; background: var(--paper-2); border: var(--line) solid var(--ink); border-radius: var(--r-md); padding: 12px 16px; }
.ach.got { background: var(--paper); box-shadow: var(--shadow-sm); }
.ach h2 { font-size: 1.05em; margin: 0; }
.ach p { margin: 0; font-size: .92em; color: var(--muted); }
.ach-badge { width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; border: var(--line) solid var(--ink); background: var(--paper); color: var(--muted); }
.ach.got .ach-badge { background: var(--accent-2); color: var(--ink); }
.ach-state { font-weight: 700; white-space: nowrap; }
.ending-grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.ending-card { background: var(--paper-2); border: var(--line) dashed var(--ink); border-radius: var(--r-lg); padding: 16px; }
.ending-card.seen { background: var(--paper); border-style: solid; box-shadow: var(--shadow-sm); }
.ending-card h3 { font-family: var(--font-display); font-weight: 400; font-size: 1.3rem; }

.settings .setting { margin: 0; }
fieldset.setting { border: var(--line) solid var(--ink); }
fieldset legend { padding: 2px 10px; background: var(--paper); border: 2px solid var(--ink); border-radius: 8px; }
fieldset legend h2 { margin: 0; }
.setting h2 { font-size: 1.15em; }
.radio { display: flex; align-items: center; gap: 10px; min-height: var(--tap); cursor: pointer; }
.radio input { width: 24px; height: 24px; accent-color: var(--accent); }
.switch { display: inline-flex; align-items: center; gap: 10px; min-height: var(--tap); padding: 4px 14px 4px 6px; border: var(--line) solid var(--ink); border-radius: 999px; background: var(--paper-2); cursor: pointer; font-weight: 700; margin-bottom: 8px; }
.switch .knob { width: 46px; height: 28px; border-radius: 999px; background: var(--muted); position: relative; border: 2px solid var(--ink); }
.switch .knob::after { content: ''; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: var(--paper); border: 2px solid var(--ink); transition: left .15s; }
.switch[aria-checked="true"] .knob { background: var(--good); }
.switch[aria-checked="true"] .knob::after { left: 20px; }
.credits p { max-width: 70ch; }

/* ------------------------------------------------------------------ level */
.level-bar { margin-bottom: 12px; }
.level-title { margin: 0; display: flex; flex-direction: column; line-height: 1.05; flex: 1 1 auto; min-width: 0; color: var(--on-bg); }
.lvl-num { font-weight: 700; font-size: .8rem; letter-spacing: .02em; opacity: .85; }
.lvl-name { font-family: var(--font-display); font-weight: 400; font-size: clamp(1.25rem, 3.6vw, 2rem); }
.level-body { display: grid; grid-template-columns: minmax(220px, 300px) minmax(0, 1fr); gap: 22px; align-items: start; }
.narrator-panel { display: flex; flex-direction: column; align-items: center; gap: 12px; position: sticky; top: 12px; }
.narrator-btn { width: 100%; max-width: 230px; aspect-ratio: 1; background: none; border: 0; padding: 0; cursor: pointer; border-radius: 30px; position: relative; }
.narrator-btn svg { width: 100%; height: 100%; display: block; }
.narrator-btn .narrator-svg { animation: float 3.2s ease-in-out infinite; transform-origin: 50% 90%; }
.narrator-btn[data-mood="panicked"] .narrator-svg { animation: jitter .25s linear infinite; }
.narrator-btn.drop-target { outline: 4px dashed var(--accent); outline-offset: 4px; background: color-mix(in srgb, var(--accent-2) 35%, transparent); }
.bubble-narrator { width: 100%; max-width: none; min-height: 7.5em; }
.bubble-narrator::before { content: ''; position: absolute; top: -20px; left: 50%; margin-left: -10px; border: 10px solid transparent; border-bottom: 16px solid var(--ink); }
.bubble-narrator p { margin: 0; font-size: 1.02em; }
.bubble.pop { animation: pop .22s ease-out; }
.bubble[data-mood="panicked"], .bubble[data-mood="annoyed"] { background: #fff4f4; }
.stage-col { display: flex; flex-direction: column; gap: 10px; min-width: 0; width: 100%; max-width: 640px; justify-self: center; }
.objective { margin: 0; background: var(--paper); border: var(--line) solid var(--ink); border-radius: var(--r-md); padding: 6px 12px; font-size: .95em; }
.stage {
  position: relative; width: 100%; max-width: 640px; aspect-ratio: 1 / 1; margin: 0 auto;
  background: linear-gradient(180deg, var(--stage) 0 74%, var(--stage-floor) 74% 100%);
  border: var(--line) solid var(--ink); border-radius: var(--r-lg); box-shadow: var(--shadow);
  overflow: hidden; container-type: inline-size;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
.stage.flash-fail { animation: flash-fail .5s ease-out; }
.pick-status { margin: 0; min-height: 1.2em; font-weight: 700; text-align: center; color: var(--on-bg); }
.pick-status:empty { display: none; }
.hint-box { background: var(--accent-2); border: var(--line) solid var(--ink); border-radius: var(--r-md); padding: 10px 14px; box-shadow: var(--shadow-sm); }
.hint-box p { margin: 0 0 4px; }
.hint-box .small { color: var(--ink); opacity: .8; }
.score-rule { text-align: center; margin: 0; color: var(--on-bg); opacity: .85; }

/* stage objects */
.obj { position: absolute; padding: 0; margin: 0; border: 0; background: none; display: flex; align-items: center; justify-content: center; text-align: center; border-radius: 12px; touch-action: manipulation; color: var(--ink); --fx: 1; font-size: calc(var(--fx) * clamp(12px, 3.3cqi, 20px)); line-height: 1.2; }
button.obj { cursor: pointer; }
/* Small stage buttons get an invisible hit area of at least 44×44 px. */
button.obj::after { content: ''; position: absolute; top: min(0px, calc(50% - 22px)); bottom: min(0px, calc(50% - 22px)); left: min(0px, calc(50% - 22px)); right: min(0px, calc(50% - 22px)); }
button.obj:disabled { cursor: default; }
.obj > svg.art { width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.obj svg text { font-family: var(--font-display); }
button.obj.has-art:not(:disabled):hover > svg { transform: translateY(-2%) scale(1.03); }
button.obj:active > svg { transform: scale(.97); }
.obj > svg { transition: transform .12s ease; }
.obj.is-drag { touch-action: none; cursor: grab; }
.obj.is-hold { touch-action: none; }
.obj.dragging { cursor: grabbing; transition: none; filter: drop-shadow(6px 8px 0 color-mix(in srgb, var(--ink) 30%, transparent)); }
.obj.is-held { outline: 4px solid var(--accent); outline-offset: 2px; background: color-mix(in srgb, var(--accent-2) 40%, transparent); }
.obj.drop-target { outline: 4px dashed var(--accent); outline-offset: 2px; background: color-mix(in srgb, var(--accent-2) 30%, transparent); }
.obj.holding > svg, .obj.holding .obj-text { animation: jitter .18s linear infinite; }
.obj.zone-ghost { border: 3px dashed var(--accent); }
.obj.pop-in > svg { animation: pop .3s ease-out; }
.obj.subtle { opacity: .75; }
.obj.subtle:hover, .obj.subtle:focus-visible { opacity: 1; }
.obj-text { white-space: pre-line; pointer-events: none; }
.obj.has-art .obj-text { position: absolute; bottom: -1.3em; font-weight: 700; }

/* text objects */
.obj.btn-card, .obj.sign-card, .obj.timer-card, .obj.display-card, .obj.ticket-card, .obj.plaque-card, .obj.tutorial-card, .obj.book-card, .obj.honest-card, .obj.panel-card, .obj.tag-card, .obj.speech-card, .obj.color-btn, .obj.panel-lights {
  border: var(--line) solid var(--ink); border-radius: var(--r-sm); background: var(--paper); font-weight: 700; padding: 2px 6px; box-shadow: var(--shadow-sm);
}
.obj.btn-card { background: var(--paper); }
.obj.btn-card:hover:not(:disabled) { transform: translate(-1px, -1px); box-shadow: var(--shadow-hover); }
.obj.btn-card:active { transform: translate(2px, 2px); box-shadow: var(--shadow-press); }
.obj.btn-card.accent { background: var(--accent); color: var(--accent-ink); }
.obj.btn-card.small { --fx: 1.4; padding: 0; }
.obj.btn-card.big { font-family: var(--font-display); font-weight: 400; --fx: 1.15; }
.obj.btn-card.ghost { background: var(--paper-2); border-style: dashed; box-shadow: none; }
.obj.btn-card.option { justify-content: flex-start; text-align: left; padding: 2px 10px; }
.obj.btn-card.option.warn { background: #fff0f0; }
.obj.btn-card.key { font-family: var(--font-display); font-weight: 400; --fx: 1.2; }
.obj.btn-card.key.ghost { font-family: var(--font-body); font-weight: 700; --fx: 1; }
.obj.hold-btn { background: var(--accent-2); font-family: var(--font-display); font-weight: 400; --fx: 1.15; overflow: hidden; }
.obj.hold-btn::before { content: ''; position: absolute; inset: 0; background: var(--good); transform: scaleX(0); transform-origin: left; opacity: .5; }
.obj.hold-btn.charging::before { transform: scaleX(1); transition: transform 2s linear; }
.obj.hold-btn.done { background: var(--good); color: #fff; }
.obj.obey-btn { background: var(--accent); color: var(--accent-ink); font-family: var(--font-display); font-weight: 400; --fx: 1.8; border-radius: 999px; }
.obj.sign-card { font-family: var(--font-display); font-weight: 400; --fx: 1.6; background: var(--accent-2); transform: rotate(-2deg); }
.obj.timer-card { font-family: var(--font-display); font-weight: 400; --fx: 3; border-radius: 50%; }
.obj.timer-card.urgent { background: var(--accent); color: var(--accent-ink); }
.obj.display-card { background: #1c1640; color: #7dffb2; font-family: var(--font-display); font-weight: 400; --fx: 1.35; letter-spacing: .03em; }
.obj.display-card.ready { color: var(--accent-2); }
.obj.ticket-card { background: #fff3c4; border-style: dashed; transform: rotate(-4deg); --fx: 1; }
.obj.plaque-card { justify-content: flex-start; text-align: left; padding: 2px 14px; background: var(--paper); --fx: 1.05; }
.obj.tutorial-card { align-items: flex-start; padding: 6% 6% 0; --fx: 1.15; background: #fff; border-width: 4px; }
.obj.tutorial-card::before { content: 'Tutorial'; position: absolute; top: -.9em; left: 1em; background: var(--accent); color: var(--accent-ink); border: 2px solid var(--ink); border-radius: 6px; padding: 0 8px; font-size: .75em; }
.obj.book-card { align-items: flex-start; justify-content: flex-start; text-align: left; padding: 3% 4%; background: #fff8dd; font-weight: 400; --fx: 1; line-height: 1.45; }
.obj.honest-card { background: #e8fff3; font-weight: 400; --fx: 1; padding: 4px 10px; text-align: left; }
.obj.panel-card { background: #2d2850; color: #7dffb2; --fx: 1; }
.obj.keypad-bg { background: #4b4466; border: var(--line) solid var(--ink); border-radius: var(--r-md); box-shadow: var(--shadow-sm); }
.obj.panel-card.ok { color: var(--accent-2); }
.obj.tag-card { background: var(--paper-2); font-weight: 400; --fx: 1; box-shadow: none; }
.obj.speech-card { font-weight: 400; text-align: left; padding: 6px 10px; --fx: 1; }
.obj.glow-text { font-family: var(--font-display); color: #7dffb2; --fx: 1.6; text-shadow: 0 0 8px #7dffb2, 0 0 18px #2bf07f; z-index: 50; }
.obj.fine-print { font-size: max(11px, calc(.6 * clamp(12px, 3.3cqi, 20px))); color: var(--ink); text-decoration: underline dotted; opacity: .8; z-index: 20; }
.obj.color-btn { --fx: 1.9; border-radius: 50%; color: #fff; text-shadow: 0 2px 0 var(--ink); }
.obj.color-btn.red { background: #e5243b; }
.obj.color-btn.yellow { background: #ffc31f; color: var(--ink); text-shadow: none; }
.obj.color-btn.blue { background: #2f6fe4; }
.obj.panel-lights { background: #2d2850; color: #ffde3b; --fx: 1.4; letter-spacing: .15em; }
.obj.panel-lights.wrong { color: #ff6b6b; }
.obj.panel-lights.ok { color: #7dffb2; }
.obj.backdrop { border-radius: 0; z-index: 0; }
.obj.hero-sprite { transition: left .35s cubic-bezier(.3, 1.4, .5, 1); }
.obj.shimmer > svg { animation: shimmer 1.6s ease-in-out infinite; }
.glow { filter: drop-shadow(0 0 6px #7dffb2); }
.shake { animation: shake-gift .12s linear infinite; transform-origin: 50% 90%; }

/* ---------------------------------------------------------- level complete */
.complete-backdrop { position: fixed; inset: 0; z-index: 300; background: rgba(28, 22, 64, .55); display: grid; place-items: center; padding: 16px; overflow-y: auto; }
.complete-card { position: relative; width: min(520px, 100%); text-align: center; padding-top: 28px; animation: pop .25s ease-out; }
.complete-card h2 { font-family: var(--font-display); font-weight: 400; font-size: 1.8rem; }
.stamp {
  position: absolute; top: -26px; right: -8px; margin: 0; font-family: var(--font-display); font-size: 1.6rem; color: var(--accent);
  border: 5px double var(--accent); border-radius: 10px; padding: 0 12px; background: var(--paper); transform: rotate(9deg);
  animation: stamp-in .45s cubic-bezier(.2, 1.7, .4, 1) .15s both;
}
.big-stars { display: flex; justify-content: center; gap: 6px; color: #ffd23f; margin: 6px 0; }
.big-stars .icon { width: 52px; height: 52px; }
.big-stars .star-off { color: var(--muted); opacity: 1; }
.score-why { color: var(--muted); }
.closing { font-style: italic; }
.unlock-list { list-style: none; padding: 0; margin: 0 0 6px; display: flex; flex-direction: column; gap: 6px; align-items: center; }
.unlock-list li { display: inline-flex; gap: 6px; align-items: center; background: var(--accent-2); border: 2px solid var(--ink); border-radius: 999px; padding: 2px 12px; font-weight: 700; }

/* ------------------------------------------------------------ modal/toast */
.modal-backdrop { position: fixed; inset: 0; z-index: 400; background: rgba(28, 22, 64, .6); display: grid; place-items: center; padding: 16px; overflow-y: auto; }
.modal { width: min(520px, 100%); }
.modal h2 { font-family: var(--font-display); font-weight: 400; font-size: 1.6rem; }
.tutorial .tut-row { display: flex; gap: 14px; align-items: flex-start; }
.tutorial .narrator-mini { width: 92px; }
.tut-try { display: flex; align-items: center; gap: 14px; margin: 8px 0; flex-wrap: wrap; }
.tut-button { width: 84px; height: 84px; background: none; border: 0; cursor: pointer; padding: 0; }
.tut-button svg { width: 100%; height: 100%; }
.tut-result { margin: 0; font-weight: 700; flex: 1 1 180px; }
.toasts { position: fixed; z-index: 500; left: 50%; top: max(12px, env(safe-area-inset-top)); bottom: auto; transform: translateX(-50%); display: flex; flex-direction: column; gap: 8px; width: min(440px, calc(100vw - 24px)); pointer-events: none; }
.toast { display: flex; align-items: center; gap: 10px; background: var(--paper); border: var(--line) solid var(--ink); border-radius: var(--r-md); box-shadow: var(--shadow-sm); padding: 10px 14px; font-weight: 700; animation: toast-drop .25s ease-out; }
.toast.out { opacity: 0; transition: opacity .35s; }
.toast-secret { background: #2d2850; color: #fff; }
.toast-secret .icon { color: #7dffb2; }
.toast-achievement { background: var(--accent-2); }
.toast-warn { background: #fff0f0; }

/* ---------------------------------------------------------------- endings */
.ending { position: relative; min-height: calc(100dvh - 60px); border: var(--line) solid var(--ink); border-radius: var(--r-lg); overflow: hidden; display: grid; place-items: center; padding: 30px 16px; box-shadow: var(--shadow); }
.ending-fx { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.ending-card-wrap { position: relative; width: min(760px, 100%); text-align: center; }
.ending-kicker { display: inline-block; font-weight: 700; background: var(--paper); border: 2px solid var(--ink); border-radius: 999px; padding: 0 12px; }
.ending-title { font-family: var(--font-display); font-weight: 400; font-size: clamp(2.2rem, 8vw, 4.4rem); margin: 8px 0 16px; }
.ending-talk { display: flex; align-items: center; gap: 18px; text-align: left; justify-content: center; flex-wrap: wrap; }
.ending-narrator { width: clamp(120px, 30vw, 190px); }
.ending-narrator svg { width: 100%; height: auto; }
.bubble.big { font-size: 1.15em; max-width: 44ch; flex: 1 1 260px; }
.quill-choices { display: flex; flex-direction: column; gap: 10px; margin-top: 18px; align-items: center; }
.quill-choice { width: min(420px, 100%); justify-content: flex-start; font-size: 1.1em; }
.quill-choice svg { width: 44px; height: 32px; }
.ending-final { background: var(--paper); border: var(--line) solid var(--ink); border-radius: var(--r-lg); padding: 24px; box-shadow: var(--shadow); position: relative; }
.ending-final h2 { font-family: var(--font-display); font-weight: 400; font-size: 2rem; }
.end-stamp { font-family: var(--font-display); font-size: 2.6rem; color: var(--accent); border: 6px double var(--accent); display: inline-block; padding: 0 18px; border-radius: 12px; transform: rotate(-6deg); animation: stamp-in .5s cubic-bezier(.2, 1.7, .4, 1) both; margin: 0 0 10px; }
.quote { font-size: 1.25em; font-weight: 700; }

.ending-hero { background: linear-gradient(180deg, #ffe7a3 0%, #ffb877 45%, #8fd3ff 100%); color: #1c1640; }
.ending-hero .sun { position: absolute; left: 50%; bottom: -160px; width: 420px; height: 420px; margin-left: -210px; border-radius: 50%; background: radial-gradient(#fff6c7, #ffd23f 60%, transparent 70%); animation: rise 2.4s ease-out both; }
.ending-hero .spark { position: absolute; font-size: 1.6rem; color: var(--good); font-weight: 700; animation: float-up 4s ease-in-out infinite; animation-delay: calc(var(--i) * -.37s); }
.ending-chaos { background: repeating-linear-gradient(-45deg, #1c1640 0 22px, #2d1a3d 22px 44px); color: #fff; animation: quake .4s linear 3; }
.ending-chaos .ending-title { color: #ffde3b; text-shadow: 3px 0 #e5243b, -3px 0 #3ec1ff; }
.ending-chaos .ending-kicker { color: #1c1640; }
.ending-chaos .debris { position: absolute; font-family: var(--font-display); font-size: 1.4rem; color: #ffde3b; animation: tumble 3s linear infinite; animation-delay: calc(var(--i) * -.21s); opacity: .8; }
.ending-chaos .bubble, .ending-chaos .ending-final { color: #1c1640; }
.ending-chaos .btn.ghost, .ending-secret .btn.ghost { color: #fff; border-color: #fff; background: rgba(0, 0, 0, .35); }
.ending-secret { background: radial-gradient(ellipse at 50% 30%, #3b2a7a 0%, #140f33 70%); color: #fff; }
.ending-secret .ending-title { color: #ffd23f; }
.ending-secret .ending-kicker { color: #1c1640; background: #ffd23f; }
.ending-secret .star-fx { position: absolute; width: 4px; height: 4px; border-radius: 50%; background: #fff6c7; animation: twinkle 2.4s ease-in-out infinite; animation-delay: calc(var(--i) * -.13s); }
.ending-secret .quill-big { position: absolute; right: 4%; top: 6%; width: min(220px, 34vw); opacity: .85; transform: rotate(-12deg); }
.ending-secret .bubble, .ending-secret .ending-final, .ending-secret .quill-choice { color: #1c1640; }

/* -------------------------------------------------------------- keyframes */
@keyframes stamp-in { 0% { transform: scale(2.4) rotate(-7deg); opacity: 0; } 100% { transform: rotate(-7deg); opacity: 1; } }
.stamp { --r: 9deg; }
@keyframes pop { 0% { transform: scale(.92); } 60% { transform: scale(1.03); } 100% { transform: scale(1); } }
@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
@keyframes jitter { 0% { transform: translate(0, 0); } 25% { transform: translate(-1px, 1px); } 50% { transform: translate(1px, 0); } 75% { transform: translate(0, -1px); } }
@keyframes bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
@keyframes flash-fail { 0% { box-shadow: 0 0 0 0 var(--accent), var(--shadow); } 30% { box-shadow: 0 0 0 8px var(--accent), var(--shadow); } 100% { box-shadow: var(--shadow); } }
@keyframes toast-in { from { transform: translateY(12px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes shake-gift { 0%, 100% { transform: rotate(0); } 25% { transform: rotate(-5deg); } 75% { transform: rotate(5deg); } }
@keyframes shimmer { 0%, 100% { filter: drop-shadow(0 0 2px #ffd23f); } 50% { filter: drop-shadow(0 0 12px #ffd23f); } }
@keyframes rise { from { transform: translateY(160px); } to { transform: none; } }
@keyframes float-up { 0%, 100% { transform: translateY(0); opacity: .4; } 50% { transform: translateY(-20px); opacity: 1; } }
@keyframes quake { 0%, 100% { transform: translate(0); } 25% { transform: translate(-6px, 3px); } 50% { transform: translate(5px, -4px); } 75% { transform: translate(-3px, -2px); } }
@keyframes tumble { from { transform: translateY(-30px) rotate(0); } to { transform: translateY(60px) rotate(360deg); } }
@keyframes twinkle { 0%, 100% { opacity: .2; } 50% { opacity: 1; } }

/* The complete-card stamp keeps its own rotation */
.complete-card .stamp { animation-name: stamp-card; }
@keyframes stamp-card { 0% { transform: scale(2.2) rotate(9deg); opacity: 0; } 100% { transform: rotate(9deg); opacity: 1; } }
.end-stamp { animation-name: stamp-end; }
@keyframes stamp-end { 0% { transform: scale(2.2) rotate(-6deg); opacity: 0; } 100% { transform: rotate(-6deg); opacity: 1; } }

/* --------------------------------------------------------- reduced motion */
.reduce-motion *, .reduce-motion *::before, .reduce-motion *::after {
  animation-duration: .001ms !important; animation-iteration-count: 1 !important; animation-delay: 0s !important;
  transition-duration: .001ms !important; scroll-behavior: auto !important;
}
.reduce-motion .obj.hold-btn.charging::before { transform: scaleX(1); transition: transform 2s steps(4, end) !important; } /* 2.3 E69: discrete steps, not motion */
.reduce-motion .ending-hero .spark, .reduce-motion .ending-chaos .debris { animation: none !important; }

/* ------------------------------------------------------------- responsive */
@media (max-width: 900px) {
  .menu-layout { grid-template-columns: 1fr; min-height: 0; gap: 22px; }
  .map-layout { grid-template-columns: 1fr; }
  .map-side { position: static; }
  .level-body { grid-template-columns: 1fr; gap: 12px; }
  .narrator-panel { position: static; flex-direction: row; align-items: center; }
  .narrator-btn { width: 96px; max-width: 96px; flex: none; }
  .bubble-narrator { min-height: 0; flex: 1 1 auto; }
  .bubble-narrator::before { top: 50%; left: -21px; margin: -10px 0 0; border: 10px solid transparent; border-right: 16px solid var(--ink); }
}
@media (max-width: 520px) {
  .app { padding: 10px 12px 32px; }
  :root { --shadow: 4px 4px 0 var(--ink); }
  .logo-obey { -webkit-text-stroke-width: 3px; text-shadow: 5px 5px 0 var(--ink); }
  .narrator-btn { width: 84px; max-width: 84px; }
  .bubble-narrator { padding: 8px 12px; font-size: .95em; }
  .chip-btn span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .chip-btn { padding: .3em .55em; min-width: 44px; justify-content: center; }
  .topbar { gap: 8px; }
  .level-title { order: 0; }
  .ach { grid-template-columns: auto 1fr; }
  .ach-state { grid-column: 2; }
  .panel { padding: 14px 14px; }
  .node-title { font-size: .7em; max-width: 112px; }
  .menu-narrator .narrator-mini { width: 84px; }
  .score-rule { font-size: .78em; }
}
@media (hover: none) {
  button.obj.has-art:hover > svg { transform: none; }
}
@media print { body { background: #fff; } }

/* ======================================================================
   2.0 — voice, wrong-answer gags, "Show me how", difficulty, trophies
   ====================================================================== */
.obj-static { pointer-events: none; }

/* Bossworth talks: the mouth flaps while a line is spoken */
.narrator-btn.talking .mouth { animation: talk .13s ease-in-out infinite alternate; transform-box: fill-box; transform-origin: center; }
@keyframes talk { from { transform: scaleY(.35) scaleX(1.05); } to { transform: scaleY(1.15); } }
.laugh-shake { animation: laugh .18s ease-in-out infinite alternate; transform-box: view-box; transform-origin: 50% 80%; }
@keyframes laugh { from { transform: rotate(-3deg) translateY(0); } to { transform: rotate(3deg) translateY(-3px); } }
@keyframes zzz { 0%, 100% { opacity: .2; } 50% { opacity: 1; } }

/* Gags over the stage */
.stage-wrap { position: relative; width: 100%; max-width: 640px; margin: 0 auto; }
.gag-layer { position: absolute; inset: 0; pointer-events: none; z-index: 600; overflow: hidden; border-radius: var(--r-lg); }
.gag { position: absolute; inset: 0; display: grid; place-items: center; }
.gag > svg { position: absolute; width: 62%; height: 62%; }
.gag-word {
  position: relative; font-family: var(--font-display); font-size: clamp(2rem, 11cqi, 4.6rem); color: var(--accent);
  background: var(--paper); border: 6px double var(--accent); border-radius: 14px; padding: 0 .35em; transform: rotate(-10deg);
  animation: gag-stamp .45s cubic-bezier(.2, 1.7, .4, 1) .25s both;
}
.gag-layer { container-type: inline-size; }
@keyframes gag-stamp { 0% { transform: scale(2.6) rotate(-10deg); opacity: 0; } 100% { transform: rotate(-10deg); opacity: 1; } }
.gag-pie > svg { animation: pie-fly .5s cubic-bezier(.3, .1, .4, 1) both, gag-fade 1.9s ease-in forwards; }
@keyframes pie-fly { from { transform: translate(-90%, -80%) scale(.3) rotate(-40deg); } 70% { transform: scale(1.15, .8); } to { transform: none; } }
.gag-chicken > svg { animation: chicken-fly 1.2s linear both; }
@keyframes chicken-fly { from { transform: translateX(-130%) rotate(0); } to { transform: translateX(130%) rotate(720deg); } }
.gag-trombone > svg { animation: trombone-rise 1.6s ease-in-out both; }
@keyframes trombone-rise { 0% { transform: translateY(120%); } 30% { transform: translateY(0) rotate(-6deg); } 60% { transform: rotate(6deg); } 100% { transform: translateY(0) rotate(-12deg) scale(.95); opacity: .2; } }
.gag-zap > svg { animation: zap-flash .34s steps(2) 3; } /* 2.3 E67: 2.9 Hz, under the 3 Hz flash limit */
.gag-zap { animation: zap-bg .34s steps(2) 3; }
@keyframes zap-flash { 50% { opacity: .2; transform: translateX(6px); } }
@keyframes zap-bg { 50% { background: rgba(255, 230, 102, .4); } }
.gag-splash > svg { animation: splash-up .7s cubic-bezier(.2, 1.4, .4, 1) both, gag-fade 1.9s ease-in forwards; transform-origin: 50% 100%; }
@keyframes splash-up { from { transform: translateY(80%) scaleY(.2); } to { transform: none; } }
@keyframes gag-fade { 0%, 70% { opacity: 1; } 100% { opacity: 0; } }
.stage.flash-fail { animation: flash-fail .5s ease-out, wobble .5s ease-in-out; }
@keyframes wobble { 0%, 100% { transform: none; } 20% { transform: rotate(-1.5deg) scale(.99); } 40% { transform: rotate(1.5deg); } 60% { transform: rotate(-.8deg); } 80% { transform: rotate(.5deg); } }
.reduce-motion .gag > svg { animation: none !important; opacity: .85; }

/* Harmless wrong moves */
.obj.nope-shake { animation: nope-shake .4s ease-in-out; }
@keyframes nope-shake { 0%, 100% { translate: 0; } 20% { translate: -8px 0; } 40% { translate: 7px 0; } 60% { translate: -5px 0; } 80% { translate: 3px 0; } }
.nope-sticker {
  position: absolute; left: 50%; top: -6px; translate: -50% -100%; z-index: 700; pointer-events: none; white-space: nowrap;
  font-family: var(--font-display); font-size: max(13px, 4cqi); color: #fff; background: var(--accent); border: 3px solid var(--ink);
  border-radius: 8px; padding: 0 8px; rotate: -8deg; animation: nope-pop .9s ease-out forwards;
}
@keyframes nope-pop { 0% { opacity: 0; scale: .4; } 20% { opacity: 1; scale: 1.15; } 80% { opacity: 1; scale: 1; } 100% { opacity: 0; translate: -50% -160%; } }
.stage.stage-nope { animation: nope-shake .35s ease-in-out; }

/* "Show me how" */
.obj.guide-target, .narrator-btn.guide-target { outline: 5px solid var(--good); outline-offset: 3px; border-radius: 14px; }
.obj.guide-target:not(.hold-btn)::before {
  content: '▼'; position: absolute; left: 50%; top: -4px; translate: -50% -100%; z-index: 650; color: var(--good);
  font-size: max(18px, 6cqi); text-shadow: 0 2px 0 var(--ink); animation: guide-bob .7s ease-in-out infinite alternate; pointer-events: none;
}
@keyframes guide-bob { from { translate: -50% -100%; } to { translate: -50% -140%; } }
.guide-box, .wrong-card { border: var(--line) solid var(--ink); border-radius: var(--r-md); padding: 12px 14px; box-shadow: var(--shadow-sm); }
.guide-box { background: #e8fff3; }
.guide-box .guide-title { margin: 0 0 6px; }
.guide-note { font-weight: 700; color: var(--accent); margin: 0 0 6px; }
.guide-steps { margin: 0 0 8px; padding-left: 1.4em; }
.guide-steps li { margin: 3px 0; color: var(--muted); }
.guide-steps li.current { color: var(--ink); font-weight: 700; }
.guide-steps li.done { text-decoration: line-through; }
.guide-steps li .icon { color: var(--good); margin-right: 4px; }
.wrong-card { background: #fff0f0; animation: toast-in .25s ease-out; scroll-margin: 16px; }
.wrong-card p { margin: 0 0 6px; }
.wrong-title { display: flex; gap: 8px; align-items: center; color: var(--accent); font-size: 1.1em; }
.wrong-card .btn-row { margin-top: 6px; }
.chip-btn.locked-chip { opacity: .6; border-style: dashed; }

/* Difficulty */
.diff-badge { display: inline-block; font-size: .78rem; font-weight: 700; padding: 0 6px; border-radius: 6px; border: 2px solid var(--ink); background: var(--paper); color: var(--ink); vertical-align: 1px; }
.diff-badge.diff-easy { background: #c9f7dd; } .diff-badge.diff-hard { background: #ffc9c9; }
.diff-options { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.diff-option { text-align: left; display: flex; flex-direction: column; gap: 2px; padding: 12px 14px; border: var(--line) solid var(--ink); border-radius: var(--r-md); background: var(--paper); cursor: pointer; box-shadow: var(--shadow-sm); min-height: var(--tap); }
.diff-option:hover { transform: translate(-1px, -1px); box-shadow: var(--shadow-hover); }
.diff-option.current { outline: 4px solid var(--accent-2); }
.diff-option.diff-easy { border-left-width: 12px; border-left-color: var(--good); }
.diff-option.diff-medium { border-left-width: 12px; border-left-color: #f5b400; }
.diff-option.diff-hard { border-left-width: 12px; border-left-color: var(--accent); }
.diff-name { font-family: var(--font-display); font-size: 1.3em; }
.diff-name em { font-family: var(--font-body); font-size: .65em; font-style: normal; color: var(--muted); }
.diff-blurb { font-size: .92em; color: var(--muted); }
.btn.small-btn { min-height: 36px; padding: .15em .7em; font-size: .85em; margin-left: 6px; }
.diff-line { color: var(--on-bg); margin: 12px 0 0; display: flex; align-items: center; flex-wrap: wrap; gap: 4px; }
.node-disc { position: relative; }
.node-medal { position: absolute; right: -8px; bottom: -6px; width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; font-family: var(--font-body); font-weight: 700; font-size: 12px; border: 2px solid var(--ink); }
.medal-easy { background: #d08a4b; color: var(--ink); } .medal-medium { background: #c9d1dc; color: var(--ink); } .medal-hard { background: #ffd23f; color: var(--ink); }

/* Trophy room */
.trophy-grid { list-style: none; padding: 0; margin: 0; display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
.trophy-card { background: var(--paper-2); border: var(--line) dashed var(--ink); border-radius: var(--r-lg); padding: 14px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.trophy-card.won { background: var(--paper); border-style: solid; box-shadow: var(--shadow-sm); }
.trophy-card h2 { font-family: var(--font-display); font-weight: 400; font-size: 1.2rem; margin: 0; }
.trophy-card .bar { width: 100%; }
.trophy-card p { margin: 0; }
.trophy-art { width: 110px; height: 110px; }
.trophy-art svg { width: 100%; height: 100%; }
.trophy-card.won .trophy-art { animation: trophy-shine 3s ease-in-out infinite; }
@keyframes trophy-shine { 0%, 100% { filter: none; } 50% { filter: drop-shadow(0 0 10px rgba(255, 210, 63, .9)); } }
.trophy-tier { font-weight: 700; display: inline-flex; gap: 4px; align-items: center; }
.tier-3 .trophy-tier, .tier-4 .trophy-tier { color: #9a6b00; }
.unlock-list li.unlock-trophy { background: #fff1b8; }

/* 2.0 level objects */
.obj.mirror-text { transform: scaleX(-1); font-family: var(--font-display); color: #2d2850; opacity: .8; --fx: 1; line-height: 1.3; white-space: pre-line; }
.obj.tv-text { color: #7dffb2; font-family: var(--font-body); font-weight: 700; padding: 4px 8px; text-align: center; }
.obj.tv-text.static { color: #1c1640; animation: tv-static .6s steps(2) infinite; }
@keyframes tv-static { 50% { opacity: .7; } }
.obj.shape-btn { border: var(--line) solid var(--ink); border-radius: var(--r-md); background: var(--paper); --fx: 3.2; box-shadow: var(--shadow-sm); -webkit-text-stroke: 3px var(--ink); paint-order: stroke fill; text-shadow: none; }
.obj.shape-btn.green { color: #2bc46f; } .obj.shape-btn.purple { color: #9b5de5; } .obj.shape-btn.orange { color: #ff8c1a; }
.obj.card-slide { transition: left .9s cubic-bezier(.5, 0, .3, 1); }
.obj.floaty > svg { animation: floaty 3s ease-in-out infinite; }
.obj.floaty.slow > svg { animation-duration: 4.5s; }
@keyframes floaty { 0%, 100% { transform: translateY(0) rotate(-6deg); } 50% { transform: translateY(-10%) rotate(6deg); } }
.spin { animation: spin .25s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.drip-fall { animation: drip 1s ease-in infinite; }
@keyframes drip { from { transform: translateY(0); opacity: 1; } to { transform: translateY(110px); opacity: .2; } }
.obj.art-water { transition: top .6s ease, height .6s ease; }
.wet-drips { animation: floaty 2s ease-in-out infinite; }
.reduce-motion .obj.floaty > svg, .reduce-motion .spin, .reduce-motion .drip-fall { animation: none !important; }

/* ======================================================================
   2.1 — iPad/touch, accessibility options, asides, U.N.D.O., ruins,
   Daily Dare, stats, Sabotage file, bonus objects
   ====================================================================== */

/* ---- accessibility options ------------------------------------------- */
[data-text="xl"] { --fs: 23px; }
[data-font="plain"] { --font-display: var(--font-body); }
[data-font="plain"] .logo, [data-font="plain"] .lvl-name, [data-font="plain"] .screen-title, [data-font="plain"] .slip-primary,
[data-font="plain"] .section-title, [data-font="plain"] h2 { font-weight: 700; letter-spacing: 0; }
html[data-contrast="high"] {
  --bg: #ffffff; --bg-2: #e6e6e6; --paper: #ffffff; --paper-2: #f0f0f0; --ink: #000000; --muted: #2b2b2b;
  --accent: #b34700; --accent-ink: #ffffff; --accent-2: #ffd400; --good: #0050b3; --stage: #ffffff; --stage-floor: #e9e9e9; --on-bg: #000000;
  --line: 4px;
}
html[data-contrast="high"] body { background-image: none; }
html[data-contrast="high"] .obj.drop-target, html[data-contrast="high"] .obj.is-held { outline-width: 6px; }
html[data-contrast="high"] .small, html[data-contrast="high"] .map-help { color: #000; }

/* ---- touch & iPad hygiene --------------------------------------------- */
html { touch-action: manipulation; }
button, .slip, .chip-btn, .btn, .map-node, .narrator-btn, .obj { -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none; }
.obj, .narrator-btn, .map-node, .chip-btn, .slip { -webkit-user-select: none; user-select: none; }
.app { padding-top: max(14px, env(safe-area-inset-top)); padding-bottom: max(40px, env(safe-area-inset-bottom)); }
.complete-backdrop, .modal-backdrop { padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); }
/* Hover effects only where hovering exists (no "stuck" hover after a tap on iPad). */
@media (hover: none) {
  .btn:hover, .chip-btn:hover, .slip:hover, .diff-option:hover, .obj.btn-card:hover:not(:disabled) { transform: none; box-shadow: var(--shadow-sm); }
  .slip:nth-child(odd):hover { transform: rotate(-.6deg); } .slip:nth-child(even):hover { transform: rotate(.5deg); }
  .map-node:hover .node-disc { transform: none; }
}
@media (hover: hover) and (pointer: fine) {
  button.obj:not(:disabled):hover { filter: brightness(1.04); }
  .map-node:hover .node-title { background: var(--accent-2); }
}
/* Comfortable touch targets on touch screens (Apple HIG: 44 pt). */
@media (pointer: coarse) {
  :root { --tap: 50px; }
  .chip-btn { min-height: 46px; min-width: 46px; }
  .btn.small-btn { min-height: 44px; }
  .radio { min-height: 50px; }
}

/* Tablets in landscape (iPad 1024–1366 wide): the stage fits the screen height, no scrolling to play. */
@media (min-width: 901px) and (orientation: landscape) {
  .stage-col, .stage-wrap, .stage { max-width: min(640px, calc(100dvh - 230px)); }
  .stage-col { min-width: min(420px, 100%); }
  .level-body { grid-template-columns: minmax(220px, 320px) minmax(0, 1fr); }
}
@media (min-width: 901px) and (max-height: 860px) and (orientation: landscape) {
  .narrator-btn { max-width: 170px; }
  .bubble-narrator { min-height: 5.5em; }
  .level-bar { margin-bottom: 8px; }
}
/* Tablet portrait (iPad 744–1024 wide): bigger stage, narrator on top. */
@media (min-width: 700px) and (max-width: 900px) and (orientation: portrait) {
  .stage-col, .stage-wrap, .stage { max-width: min(700px, 100%, calc(100dvh - 400px)); }
  .narrator-btn { width: 120px; max-width: 120px; }
}
/* Phones and Slide Over in landscape (short screens): side-by-side, stage sized by height. */
@media (max-height: 520px) and (orientation: landscape) {
  .level-body { grid-template-columns: minmax(150px, 34%) minmax(0, 1fr); gap: 12px; }
  .narrator-panel { position: static; flex-direction: column; }
  .narrator-btn { width: 72px; max-width: 72px; }
  .stage-col, .stage-wrap, .stage { max-width: calc(100dvh - 40px); }
  .menu-layout { min-height: 0; }
}
/* Left-handed layout. */
@media (min-width: 901px) {
  [data-hand="left"] .level-body { grid-template-columns: minmax(0, 1fr) minmax(220px, 300px); }
  [data-hand="left"] .narrator-panel { order: 2; }
  [data-hand="left"] .level-bar .tools { order: -1; margin-left: 0; margin-right: auto; }
}
@media (max-width: 900px) {
  [data-hand="left"] .level-bar .tools { order: -1; margin-left: 0; }
  [data-hand="left"] .narrator-panel { flex-direction: row-reverse; }
}

/* ---- narrator asides, composure, timer --------------------------------- */
.narrator-text { display: flex; flex-direction: column; gap: 8px; width: 100%; min-width: 0; }
.aside { margin: 0; font-size: .9em; background: var(--paper-2); border: 2px dashed var(--ink); border-radius: var(--r-md); padding: 6px 10px; }
.aside-phone { background: #fff3c4; }
.aside-nudge { background: var(--accent-2); border-style: solid; }
.aside-dare { background: #e8fff3; border-style: solid; }
.aside .small-btn { margin: 4px 0 0; }
.composure { font-size: .9em; }
.composure .bar { margin-top: 2px; }
.bar.comp-calm span { background: var(--good); } .bar.comp-twitchy span { background: #f5b400; }
.bar.comp-frazzled span { background: #ff7a29; } .bar.comp-meltdown span { background: var(--accent); }
.run-timer { font-variant-numeric: tabular-nums; background: var(--ink); color: var(--paper); border-radius: 6px; padding: 0 6px; font-size: .78rem; }
@media (max-width: 900px) {
  .narrator-text { flex: 1 1 auto; }
  .composure { display: none; }
}

/* ---- U.N.D.O. sidekick ------------------------------------------------- */
.undo-chat { width: 100%; background: #1b1838; color: #d8ffe9; border: var(--line) solid var(--ink); border-radius: var(--r-md); padding: 8px 10px; font-size: .85em; box-shadow: var(--shadow-sm); }
.undo-head { display: flex; align-items: center; gap: 8px; margin: 0 0 4px; }
.undo-head .small { color: #9fe6c1; }
.undo-head .btn { margin-left: auto; }
.undo-bot { width: 30px; height: 30px; flex: none; }
.undo-log { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; max-height: 12em; overflow-y: auto; }
.undo-msg { font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; line-height: 1.35; }
.undo-msg.leak { color: #ffe08a; padding-left: 8px; border-left: 3px solid #ffe08a; }
.undo-chat.collapsed .undo-log { display: none; }
.undo-chat.glitch { animation: glitch .5s steps(2) 1; }
.undo-bot.glitching { animation: glitch .4s steps(2) 2; }
@keyframes glitch { 0% { transform: translate(0); filter: none; } 25% { transform: translate(-3px, 1px); filter: hue-rotate(90deg); } 50% { transform: translate(2px, -1px); clip-path: inset(10% 0 30% 0); } 75% { transform: translate(-1px, 0); filter: hue-rotate(-60deg); } 100% { transform: none; filter: none; clip-path: none; } }
/* The chat sits under the narrator on wide screens and under the stage on narrow ones. */
.level-body { grid-template-areas: "narr stage" "undo stage"; grid-template-rows: auto 1fr; }
.narrator-panel { grid-area: narr; }
.stage-col { grid-area: stage; }
.undo-chat { grid-area: undo; align-self: start; }
@media (min-width: 901px) { [data-hand="left"] .level-body { grid-template-areas: "stage narr" "stage undo"; } }
@media (max-width: 900px) {
  .level-body { grid-template-areas: "narr" "stage" "undo"; grid-template-rows: none; }
  .narrator-text { width: auto; flex: 1 1 0; }
}
@media (max-height: 520px) and (orientation: landscape) {
  .level-body { grid-template-areas: "narr stage" "undo stage"; grid-template-rows: auto 1fr; }
}

/* ---- overlays: chapter card, fake game over, captions ------------------ */
.fx-layer { position: fixed; inset: 0; z-index: 450; pointer-events: none; display: grid; place-items: center; }
.chapter-card { display: flex; flex-direction: column; align-items: center; gap: 4px; background: var(--paper); border: var(--line) solid var(--ink); border-radius: var(--r-lg); box-shadow: var(--shadow); padding: 18px 34px; animation: card-in 1.9s ease both; }
.cc-kicker { font-weight: 700; color: var(--muted); }
.cc-title { font-family: var(--font-display); font-size: clamp(2rem, 7vw, 3.4rem); color: var(--accent); }
@keyframes card-in { 0% { opacity: 0; transform: scale(.7) rotate(-4deg); } 15% { opacity: 1; transform: scale(1.04) rotate(-2deg); } 25% { transform: none; } 80% { opacity: 1; } 100% { opacity: 0; transform: translateY(-20px); } }
.fake-over { background: #000; color: #fff; padding: 28px 40px; border: 6px solid #e5243b; border-radius: 12px; text-align: center; box-shadow: 0 0 0 9999px rgba(0, 0, 0, .55); animation: pop .3s ease-out; }
.fo-title { font-family: var(--font-display); font-size: clamp(2.4rem, 10vw, 4.6rem); color: #e5243b; margin: 0; letter-spacing: .04em; }
.fo-sub { margin: 6px 0 0; font-weight: 700; }
.captions { position: fixed; z-index: 520; left: 50%; top: auto; bottom: max(12px, env(safe-area-inset-bottom)); transform: translateX(-50%); background: rgba(0, 0, 0, .82); color: #fff; font-weight: 700; padding: 4px 12px; border-radius: 8px; pointer-events: none; max-width: calc(100vw - 24px); }

/* ---- stage extras ------------------------------------------------------ */
.obj.warm-glow { animation: warm .9s ease-out; }
@keyframes warm { 0% { box-shadow: 0 0 0 0 rgba(255, 210, 63, .9); } 100% { box-shadow: 0 0 0 18px rgba(255, 210, 63, 0); } }
.obj.jigsaw-piece { z-index: 90 !important; animation: jig-wiggle 2.4s ease-in-out infinite; }
.obj.jigsaw-piece::after { top: min(0px, calc(50% - 24px)); bottom: min(0px, calc(50% - 24px)); left: min(0px, calc(50% - 24px)); right: min(0px, calc(50% - 24px)); }
@keyframes jig-wiggle { 0%, 80%, 100% { transform: none; } 85% { transform: rotate(-12deg); } 90% { transform: rotate(10deg); } 95% { transform: rotate(-6deg); } }
.reduce-motion .obj.jigsaw-piece { animation: none; }

/* ---- completion card extras -------------------------------------------- */
.stamp.stamp-ruined { color: #fff; background: var(--accent); border-color: var(--ink); }
.trick, .bonus-line { background: var(--paper-2); border: 2px solid var(--ink); border-radius: var(--r-md); padding: 6px 10px; text-align: left; font-size: .95em; }
.bonus-line { background: #fff3c4; }
.bests { margin: 4px 0 8px; }
.roast { background: #2d2850; color: #fff; border-radius: var(--r-md); padding: 8px 12px; margin: 8px 0; text-align: left; }
.roast p { margin: 0; }
.dare-result { font-weight: 700; } .dare-result.ok { color: var(--good); }
.btn .icon { margin-right: -.1em; }

/* ---- menu additions ---------------------------------------------------- */
.goal-line { color: var(--on-bg); margin: 10px 0 0; }
.trust-line { color: var(--on-bg); margin: 10px 0 0; opacity: .85; }
.whats-new { margin-top: 14px; padding: 12px 16px; }
.whats-new h2 { font-family: var(--font-display); font-weight: 400; font-size: 1.25rem; margin-bottom: 6px; }
.whats-new ul { margin: 0 0 8px; padding-left: 1.2em; font-size: .92em; }
.whats-new li { margin: 2px 0; }
.screen-quip { margin: -6px 0 14px; color: var(--on-bg); font-weight: 700; }
.screen-quip .speaker { font-family: var(--font-display); font-weight: 400; color: var(--accent); }

/* ---- map markers ------------------------------------------------------- */
.node-skipped .node-disc { background: var(--paper-2); border-style: dashed; }
.skip-flag { background: var(--muted); }
.node-secret { position: absolute; left: -8px; top: -6px; width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; background: #2d2850; color: #7dffb2; border: 2px solid var(--ink); }
.node-secret .icon { width: 14px; height: 14px; }
.node-ruined { position: absolute; left: 50%; top: -14px; translate: -50% 0; font-family: var(--font-body); font-weight: 700; font-size: 9px; letter-spacing: .05em; background: var(--accent); color: #fff; border: 2px solid var(--ink); border-radius: 4px; padding: 0 3px; rotate: -8deg; }

/* ---- settings additions ------------------------------------------------ */
.switch-row { margin: 6px 0; }
.switch-row .switch { margin-bottom: 2px; }
.switch-row .small { margin: 0 0 6px; }
.slider { display: grid; grid-template-columns: minmax(8em, auto) 1fr 3.4em; align-items: center; gap: 10px; min-height: var(--tap); }
.slider input[type="range"] { width: 100%; accent-color: var(--accent); min-height: 32px; }
.slider output { font-variant-numeric: tabular-nums; font-weight: 700; text-align: right; }
.field { display: flex; flex-direction: column; gap: 4px; font-weight: 700; margin-top: 10px; }
.field input, .field textarea, .code-box { font: inherit; font-weight: 400; border: var(--line) solid var(--ink); border-radius: var(--r-sm); padding: 8px 10px; background: var(--paper); color: var(--ink); width: 100%; min-height: var(--tap); }
.code-box { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .85em; word-break: break-all; }
.profile-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.profile { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; background: var(--paper-2); border: 2px solid var(--ink); border-radius: var(--r-md); padding: 6px 10px; }
.profile.current { background: var(--paper); box-shadow: var(--shadow-sm); }
.keys { border-collapse: collapse; width: 100%; }
.keys th { text-align: left; padding: 4px 12px 4px 0; white-space: nowrap; }
.keys td { padding: 4px 0; }
kbd { font-family: ui-monospace, Menlo, Consolas, monospace; font-weight: 700; background: var(--paper-2); border: 2px solid var(--ink); border-bottom-width: 4px; border-radius: 6px; padding: 0 6px; }

/* ---- Daily Dare, stats, Sabotage file ---------------------------------- */
.dare-card h2 { font-family: var(--font-display); font-weight: 400; font-size: 1.6rem; }
.day-strip { list-style: none; padding: 0; margin: 8px 0 14px; display: grid; grid-template-columns: repeat(14, minmax(0, 1fr)); gap: 4px; }
.day { aspect-ratio: 1; display: grid; place-items: center; border: 2px solid var(--ink); border-radius: 8px; background: var(--paper-2); font-size: .8em; font-weight: 700; }
.day.hit { background: var(--good); color: #fff; }
.day.today { outline: 3px solid var(--accent); outline-offset: 1px; }
.badge-row { list-style: none; padding: 0; margin: 0; display: flex; gap: 10px; flex-wrap: wrap; }
.badge { display: inline-flex; gap: 6px; align-items: center; border: 2px dashed var(--ink); border-radius: 999px; padding: 4px 12px; font-weight: 700; color: var(--muted); }
.badge.got { border-style: solid; background: var(--accent-2); color: var(--ink); }
.review-card .review-stars { font-size: 1.8rem; color: #f5b400; margin: 0; letter-spacing: .1em; }
.ending-final .review-card { text-align: left; background: var(--paper-2); border: 2px solid var(--ink); border-radius: var(--r-md); padding: 10px 14px; margin: 10px 0; }
.ending-final .review-card .review-stars { font-size: 1.2rem; }
.stat-table { margin: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 8px; }
.stat-table div { display: flex; justify-content: space-between; gap: 10px; border-bottom: 2px dotted var(--muted); padding: 4px 0; }
.stat-table dt { color: var(--muted); } .stat-table dd { margin: 0; font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; }
.bonus-list { list-style: none; padding: 0; margin: 10px 0 0; display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.bonus-list .slip em { display: inline-flex; color: var(--accent-2); }
.note-card.ruined { border-color: var(--accent); }
.ruin-mini { color: var(--accent); border-color: var(--accent); }
.jigsaw-panel { display: grid; grid-template-columns: minmax(0, 300px) 1fr; gap: 18px; align-items: center; }
.jigsaw-frame svg { width: 100%; height: auto; display: block; border-radius: var(--r-sm); }
@media (max-width: 600px) { .jigsaw-panel { grid-template-columns: 1fr; } .day-strip { grid-template-columns: repeat(7, minmax(0, 1fr)); } }

/* ---- Sabotage Studio objects ------------------------------------------- */
.obj.btn-card.word-red { color: #d61e35; font-family: var(--font-display); font-weight: 400; --fx: 1.7; }
html[data-contrast="high"] .obj.btn-card.word-red { color: #b34700; }
.obj.color-btn.peeling { rotate: -4deg; border-style: dashed; }
.obj.peg-selected { outline: 4px solid var(--accent-2); outline-offset: 2px; border-radius: 12px; }
.obj.disc-1, .obj.disc-2, .obj.disc-3 { border: var(--line) solid var(--ink); border-radius: 999px; box-shadow: var(--shadow-sm); transition: top .2s ease, left .2s ease; }
.obj.disc-1 { background: #ff6f91; } .obj.disc-2 { background: #ffd23f; } .obj.disc-3 { background: #3ec1ff; }

/* ---- 2.1 QA fixes -------------------------------------------------------- */
/* D5: narrow-but-tall windows (Split View) get a height-capped stage; squarer windows go side by side. */
@media (min-width: 540px) and (max-width: 900px) and (orientation: portrait) {
  .stage-col, .stage-wrap, .stage { max-width: min(700px, 100%, calc(100dvh - 400px)); }
}
@media (min-width: 540px) and (max-width: 900px) and (min-aspect-ratio: 3/4) {
  .level-body { grid-template-columns: minmax(170px, 32%) minmax(0, 1fr); grid-template-areas: "narr stage" "undo stage"; grid-template-rows: auto 1fr; gap: 14px; }
  .narrator-panel { flex-direction: column; align-items: stretch; }
  .narrator-btn { width: 84px; max-width: 84px; align-self: center; }
  .stage-col, .stage-wrap, .stage { max-width: min(640px, 100%, calc(100dvh - 150px)); }
}
@media (max-height: 520px) and (orientation: landscape) {
  .stage-col, .stage-wrap, .stage { max-width: min(640px, 100%, calc(100dvh - 120px)); }
  .level-bar { margin-bottom: 4px; }
  .score-rule { display: none; }
  .objective { padding: 2px 10px; font-size: .85em; }
}
@media (min-width: 901px) and (max-height: 620px) and (orientation: landscape) {
  .stage-col, .stage-wrap, .stage { max-width: min(640px, calc(100dvh - 130px)); }
  .score-rule { display: none; }
}
/* D6: sliders keep a usable track at any width and text size. */
.slider { grid-template-columns: 1fr auto; grid-template-areas: "label out" "track track"; row-gap: 2px; }
.slider > span { grid-area: label; }
.slider output { grid-area: out; }
.slider input[type="range"] { grid-area: track; min-width: 0; }
/* D17: long menu badges wrap instead of pushing the page sideways. */
.slip { min-width: 0; flex-wrap: wrap; }
.slip span { min-width: 0; overflow-wrap: anywhere; }
.stat-row li { min-width: 0; }
/* D18: contrast. */
html[data-contrast="high"] .undo-chat .small, html[data-contrast="high"] .undo-chat { color: #e6fff2; }
.undo-head .small { color: #c8f5dc; }
.screen-quip .speaker { color: var(--ink); background: var(--paper); border: 2px solid var(--ink); border-radius: 6px; padding: 0 6px; }
.composure .small { color: var(--on-bg); opacity: 1; }
.review-card .review-stars { color: var(--ink); text-shadow: 0 0 0 var(--ink); }
.ruin-mini { color: var(--ink); border-color: var(--accent); background: #ffe3e6; }
/* Short landscape windows (phones, Slide Over): icon-only tools keep the title bar to one row. */
@media (max-height: 520px) and (orientation: landscape) {
  .level-bar .chip-btn span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .level-bar .chip-btn { padding: .3em .55em; min-width: 44px; }
  .level-bar { flex-wrap: nowrap; }
  .stage-col, .stage-wrap, .stage { max-width: min(640px, 100%, calc(100dvh - 118px)); }
}
/* The "Bossworth" speaker label meets 4.5:1 on paper in every theme. */
.bubble .speaker { color: color-mix(in srgb, var(--accent) 82%, var(--ink)); }
/* Short landscape: the stage takes exactly the height left under the title bar and goal line. */
@media (max-height: 520px) and (orientation: landscape) {
  .stage-col { height: calc(100dvh - 76px); max-width: none; display: flex; flex-direction: column; }
  .stage-wrap { flex: 1 1 0; min-height: 0; width: auto; max-width: 100%; aspect-ratio: 1 / 1; margin: 0 auto; }
  .stage-wrap .stage { width: 100%; height: 100%; max-width: none; }
}

/* Art review 2.1 must-fixes: inert information is flat (only pressable things cast a shadow);
   the chapter card stays visible with reduced motion. */
.obj.obj-static { box-shadow: none; }
.reduce-motion .chapter-card { animation: none !important; }

/* ======================================================================
   2.3 art review, group A (docs/ART-REVIEW-2.3.md). Items are tagged E<n>.
   ====================================================================== */

/* E3: on iPad portrait the 790 px slips tilt less, so neighbours no longer cross. */
@media (min-width: 600px) and (max-width: 900px) {
  .slip:nth-child(odd), .slip:nth-child(odd):hover { transform: rotate(-.25deg); }
  .slip:nth-child(even), .slip:nth-child(even):hover { transform: rotate(.2deg); }
}
@media (min-width: 600px) and (max-width: 900px) and (hover: hover) {
  .slip:hover { transform: translate(-1px, -2px) rotate(0); }
}

/* E5: toasts drop in at the top (top-right on desktop), clear of the stage's control row. */
@keyframes toast-drop { from { transform: translateY(-12px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (min-width: 901px) {
  .toasts { left: auto; right: max(16px, env(safe-area-inset-right)); transform: none; width: min(380px, calc(100vw - 32px)); }
}

/* E6: screen titles get a small version of the logo's hard shadow. */
.topbar .screen-title, .lvl-name { -webkit-text-stroke: 0; text-shadow: 2px 2px 0 color-mix(in srgb, var(--ink) 35%, transparent); }

/* E7: the bonus play icon stays on the label's line. */
.bonus-list .slip { flex-wrap: nowrap; }
.bonus-list .slip span { min-width: 0; }

/* E9: phone stat chips sit in three even columns. */
@media (max-width: 520px) {
  .stat-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .stat-row li { flex-direction: column; align-items: flex-start; gap: 0; }
}

/* E12: Bossworth blinks (hook: <g class="eyes"> from art.js). */
.narrator-svg .eyes:not(.eyes-closed) { transform-box: fill-box; transform-origin: center; animation: blink 5.2s infinite; }
.narrator-mini .narrator-svg .eyes:not(.eyes-closed) { animation-delay: -1.7s; }
@keyframes blink { 0%, 95%, 100% { transform: none; } 97% { transform: scaleY(.1); } }

/* E14: one-property costume idles, all small (hooks: acc-* classes from art.js). */
.narrator-svg .acc-star { animation: acc-glint 2.4s ease-in-out infinite; }
.narrator-svg .acc-bulb { animation: acc-bulb 1.2s ease-in-out infinite; }
.narrator-svg .acc-antenna { transform-box: view-box; transform-origin: 100px 34px; animation: acc-sway 2.8s ease-in-out infinite; }
.narrator-svg .acc-tails { transform-box: view-box; transform-origin: 168px 96px; animation: acc-flutter 1.6s ease-in-out infinite; }
.narrator-svg .acc-crown-jewel { animation: acc-jewel 3s ease-in-out infinite; }
@keyframes acc-glint { 0%, 100% { opacity: .6; } 50% { opacity: 1; } }
@keyframes acc-bulb { 0%, 100% { fill: #ff4f6d; } 50% { fill: #ffd23f; } }
@keyframes acc-sway { 0%, 100% { transform: rotate(-4deg); } 50% { transform: rotate(4deg); } }
@keyframes acc-flutter { 0%, 100% { transform: rotate(-5deg); } 50% { transform: rotate(5deg); } }
@keyframes acc-jewel { 0%, 100% { opacity: .7; } 50% { opacity: 1; } }
.reduce-motion .narrator-svg .eyes, .reduce-motion .narrator-svg [class*="acc-"] { animation: none !important; }

/* E58: progress is good news, so progress bars are green. Red stays for the composure meter. */
.ach .bar span, .trophy-card .bar span, .progress-block .bar span { background: var(--good); }

/* E59: settings in two columns on desktop (sound and voice first, the rest flows to the right). */
@media (min-width: 1000px) {
  .page.settings { display: block; columns: 2; column-gap: 18px; }
  .page.settings > * { break-inside: avoid; margin: 0 0 18px; }
  .page.settings > :first-child { margin-top: 0; }
}

/* E60: stats table cells wide enough for "0:00.0 (44 levels)". */
.stat-table { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.stat-table dd { white-space: nowrap; }
@media (max-width: 360px) { .stat-table dd { white-space: normal; } }

/* E61: hit days carry a tick, not only a colour. */
.day.hit::after { content: '✓'; font-size: .8em; margin-left: 1px; }

/* E64: each ending's final card has its own finish. */
.ending-hero .end-stamp { color: var(--good); border-color: var(--good); }
.ending-chaos .ending-final { transform: rotate(-1.5deg); }
.ending-chaos .end-stamp { clip-path: polygon(0 0, 100% 6%, 96% 100%, 3% 92%); }
.ending-secret .ending-final { border: 6px double #ffd23f; }

/* E68: stars land one after another, 120 ms apart. With .29s and this overshoot curve each star's
   pop peaks (scale 1.11) 120 ms after its own delay, i.e. at 120 / 240 / 360 ms, where the E80 star
   chimes play (App.STAR_POP_MS = 120 in app.js). Change both together. */
.big-stars .icon { animation: star-pop .29s cubic-bezier(.2, 1.6, .4, 1) both; }
.big-stars .icon:nth-child(2) { animation-delay: .12s; }
.big-stars .icon:nth-child(3) { animation-delay: .24s; }
@keyframes star-pop { from { transform: scale(0) rotate(-30deg); } to { transform: none; } }

/* E70: screens fade up in 160 ms. The level screen keeps its own banner timing. */
.screen:not([hidden]):not(#screen-level) { animation: screen-in .16s ease-out; }
@keyframes screen-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* E71: a cut-off U.N.D.O. line fades out instead of being sliced; the newest message stays in view.
   The bottom padding is where the fade lives, so a fully scrolled log is never faded. */
.undo-log {
  padding-bottom: 1.1em; scroll-snap-type: y proximity;
  -webkit-mask-image: linear-gradient(#000 calc(100% - 1.6em), transparent);
  mask-image: linear-gradient(#000 calc(100% - 1.6em), transparent);
}
.undo-msg:last-child { scroll-snap-align: end; scroll-margin-bottom: 1.1em; }

/* E72: Sunset and the dark endings get a sunny hard shadow; surfaces on paper keep ink. */
/* The dark ending boxes keep an ink shadow on the page; everything inside them gets the sunny one. */
[data-theme="sunset"] :is(.app, .toasts), :is(.ending-chaos, .ending-secret) > * {
  --shadow: 5px 5px 0 #ffc145; --shadow-sm: 3px 3px 0 #ffc145;
  --shadow-hover: 4px 4px 0 #ffc145; --shadow-press: 1px 1px 0 #ffc145;
}
:is([data-theme="sunset"] :is(.stage, .panel, .bubble, .map-world, .complete-card, .modal, .ending-final),
    :is(.ending-chaos, .ending-secret) :is(.bubble, .ending-final, .panel)) > * {
  --shadow: 5px 5px 0 var(--ink); --shadow-sm: 3px 3px 0 var(--ink);
  --shadow-hover: 4px 4px 0 var(--ink); --shadow-press: 1px 1px 0 var(--ink);
}
[data-theme="sunset"] .logo-obey { text-shadow: 7px 7px 0 #ffc145; }
@media (max-width: 520px) {
  [data-theme="sunset"] :is(.app, .toasts), :is(.ending-chaos, .ending-secret) > * { --shadow: 4px 4px 0 #ffc145; }
  :is([data-theme="sunset"] :is(.stage, .panel, .bubble, .map-world, .complete-card, .modal, .ending-final),
      :is(.ending-chaos, .ending-secret) :is(.bubble, .ending-final, .panel)) > * { --shadow: 4px 4px 0 var(--ink); }
  [data-theme="sunset"] .logo-obey { text-shadow: 5px 5px 0 #ffc145; }
}

/* E73: a flat contact shadow under objects that stand on the floor band (stage.js adds .grounded
   and places it with --gl / --gr / --gb, in % of the object box). No blur: bible §8. */
.obj > svg.art { position: relative; }
.obj.grounded:not(.guide-target):not(.dragging)::before {
  content: ''; position: absolute; left: var(--gl, 14%); right: var(--gr, 14%); bottom: var(--gb, 0%); aspect-ratio: 7 / 1;
  transform: translateY(50%); border-radius: 50%; background: color-mix(in srgb, var(--ink) 14%, transparent); pointer-events: none;
}

/* E86: the hint count stays visible on phones as a badge (markup from app.js, E8). */
.chip-btn .count-badge {
  display: none; position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px; padding: 0 3px;
  border-radius: 999px; background: var(--accent-2); color: var(--ink); border: 2px solid var(--ink);
  font-size: 11px; line-height: 14px; text-align: center; font-weight: 700;
}
@media (max-width: 520px) { .chip-btn { position: relative; } .chip-btn .count-badge { display: block; } }

/* E92: iPad portrait menu is centred, with the slips in two columns. */
@media (min-width: 700px) and (max-width: 900px) and (orientation: portrait) {
  .menu-layout > :first-child { justify-self: center; text-align: center; }
  .logo { align-items: center; }
  .tagline { margin-left: auto; margin-right: auto; }
  .menu-narrator { justify-content: center; }
  .menu-narrator .bubble { text-align: left; }
  .menu-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
  .menu-nav .slip-primary { grid-column: 1 / -1; }
}

/* E93: on phones a flavour aside takes one line; tap (or focus) to read the rest.
   Nudges, dares and asides with a button carry information and stay whole. */
@media (max-width: 520px) {
  .aside:not(.aside-nudge):not(.aside-dare):not(:has(button)) {
    display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; cursor: pointer;
  }
  .aside:not(.aside-nudge):not(.aside-dare):not(:has(button)):is(:hover, :active, :focus-within) { -webkit-line-clamp: unset; display: block; }
}

/* E94: two cups per row in the phone trophy room. */
@media (max-width: 520px) {
  .trophy-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .trophy-art { width: 72px; height: 72px; }
}

/* E95: no one-word orphans under the stage. */
.score-rule, .objective { text-wrap: balance; }

/* E96: high contrast drops the map tints and separates regions with dashed ink rules. */
html[data-contrast="high"] { --region-1: transparent; --region-2: transparent; --region-3: transparent; --region-4: transparent; }
html[data-contrast="high"] .map-svg rect[fill^="var(--region"] { stroke: var(--ink); stroke-width: 3px; stroke-dasharray: 9 7; vector-effect: non-scaling-stroke; }

/* E97: outline weight follows rendered size (stage.js sets --ow on each non-stretch art svg).
   CSS beats the SVG presentation attribute; bespoke widths (5, 8, 10, …) stay as drawn. */
.obj > svg.art [stroke="var(--ink)"][stroke-width="4"] { stroke-width: calc(4px * var(--ow, 1)); }
.obj > svg.art [stroke="var(--ink)"][stroke-width="3"] { stroke-width: calc(3px * var(--ow, 1)); }

/* E66 (markup from app-extra.js): the chapter card leads with its landmark icon and a small stamp. */
.chapter-card .cc-icon { width: 40px; height: 40px; color: var(--accent); }
.chapter-card .cc-stamp {
  display: inline-block; transform: rotate(-4deg); background: var(--paper); color: var(--accent);
  border: 3px double var(--accent); border-radius: 6px; padding: 0 10px; font-size: .9em; letter-spacing: .03em;
}
/* E86 extra: no hints left, so the badge goes quiet. */
.chip-btn .count-badge.empty { background: var(--paper-2); color: var(--muted); border-style: dashed; }

/* Handed over by group B (2.3): credits cast strip, ending machine, map region marks. */
.cast-art svg { width: 100%; height: 100%; display: block; }
.cast-name { font-weight: 700; font-size: .85em; line-height: 1.2; }
.cast-member.locked .cast-name { color: var(--muted); }
.credits-stamp { font-size: 2rem; margin: 14px 0 4px; }
.credits-end { overflow: hidden; padding: 10px 0; } /* the stamp starts at 2.2× (stamp-end); its scrollable overflow must not widen the page on phones */
.silhouette { filter: grayscale(1) brightness(.3); opacity: .6; } /* was .35: too light to read as a shape on paper */
.ending-machine .machine-note.pop { animation: note-out .4s cubic-bezier(.2, 1.4, .4, 1) .35s both; }
@keyframes note-out { from { transform: translateY(-30px); opacity: 0; } to { transform: none; opacity: 1; } }
.ending-chaos .machine-debris { animation-name: tumble-small; animation-duration: 2.4s; }
@keyframes tumble-small { from { transform: translateY(-8px) rotate(0); } to { transform: translateY(14px) rotate(360deg); } }
/* The ink machine on the dark chaos/secret backdrops gets the same sunny hard shadow as E72. */
:is(.ending-chaos, .ending-secret) .ending-machine > svg { filter: drop-shadow(3px 3px 0 #ffc145); }
.reduce-motion .ending-machine .machine-note, .reduce-motion .ending-chaos .machine-debris { animation: none !important; }
/* Region labels stay readable where a path or node edge runs under them. */
.region-label { paint-order: stroke fill; stroke: var(--paper); stroke-width: 4px; stroke-linejoin: round; }

/* 2.4.1: the completion card can grow (achievements, chapter review, unlocks). Keep it inside the screen
   and its buttons always visible: the card scrolls and the button row sticks to its bottom edge. */
.complete-card { max-height: calc(100dvh - 24px); overflow-y: auto; overscroll-behavior: contain; }
.complete-card > .btn-row:last-child { position: sticky; bottom: -14px; margin-bottom: -14px; padding: 10px 0 14px; background: var(--paper); border-top: 2px dashed var(--line-soft, rgba(28, 22, 64, .2)); z-index: 2; }

/* 2.5: sound & music panel (opened from the speaker chip on every top bar, the menu, or the S key). */
.sound-panel { width: min(460px, 100%); }
.sound-panel h2 { display: flex; align-items: center; gap: 8px; }
.sound-panel h2 .icon { width: 26px; height: 26px; color: var(--accent); }
.sp-row { border-top: 2px dashed rgba(28, 22, 64, .18); padding: 10px 0 6px; display: grid; gap: 8px; }
.sp-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.sp-head h3 { margin: 0; font-size: 1.05em; }
.sp-voices { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.sp-row .btn.small-btn { justify-self: start; }
.sp-row input[type="range"]:disabled { opacity: .45; }
.sp-now { margin: 0; min-height: 1.3em; }
.sound-chip .icon { width: 22px; height: 22px; }
