/* fonts are vendored (SIL OFL 1.1, see vendor/fonts/*.LICENSE); nothing is fetched from a font CDN */
@font-face { font-family: "Pixelify Sans"; src: url(vendor/fonts/pixelify-sans-latin-400-normal.woff2) format("woff2"); font-weight: 400; font-display: block; }
@font-face { font-family: "Pixelify Sans"; src: url(vendor/fonts/pixelify-sans-latin-500-normal.woff2) format("woff2"); font-weight: 500; font-display: block; }
@font-face { font-family: "Pixelify Sans"; src: url(vendor/fonts/pixelify-sans-latin-600-normal.woff2) format("woff2"); font-weight: 600; font-display: block; }
@font-face { font-family: "Press Start 2P"; src: url(vendor/fonts/press-start-2p-latin-400-normal.woff2) format("woff2"); font-display: block; }
@font-face { font-family: "Silkscreen"; src: url(vendor/fonts/silkscreen-latin-400-normal.woff2) format("woff2"); font-weight: 400; font-display: block; }
@font-face { font-family: "Silkscreen"; src: url(vendor/fonts/silkscreen-latin-700-normal.woff2) format("woff2"); font-weight: 700; font-display: block; }
@font-face { font-family: "IBM Plex Mono"; src: url(vendor/fonts/ibm-plex-mono-latin-400-normal.woff2) format("woff2"); font-weight: 400; font-display: block; }
@font-face { font-family: "IBM Plex Mono"; src: url(vendor/fonts/ibm-plex-mono-latin-500-normal.woff2) format("woff2"); font-weight: 500; font-display: block; }
@font-face { font-family: "IBM Plex Mono"; src: url(vendor/fonts/ibm-plex-mono-latin-600-normal.woff2) format("woff2"); font-weight: 600; font-display: block; }

:root {
  --u: 5px;                 /* CSS px per scene texel, set by main.js */
  --feet: 64vh;             /* where the guard's feet are on screen, set by main.js */
  /* game palette (same as the scene's) */
  --night0: #05060d; --night2: #10142a; --night3: #171d3a; --night4: #1f2a4d; --night6: #37507c; --night7: #4a6796; --night8: #6582ad; --night9: #8aa3c6; --night10: #b5c8de;
  --gold: #fbc147; --gold-hi: #ffe27a; --cream: #fff5c8; --ember: #e0701c; --blood: #d8303a;
  /* Dopp's dark tokens, for the chips and the dev overlay */
  --d-surface: #161A22; --d-panel: #1C212B; --d-line: #2A303C; --d-ink: #ECEDE9; --d-slate: #98A0B0; --d-accent: #7CA0F0;
  --d-go: #4CC48A; --d-go-soft: #14301F; --d-wait: #E0A33A; --d-stop: #F08A7E; --d-stop-soft: #33100C; --d-purple: #B9A2F2; --d-teal: #6FCBCB;
  --gutter: max(16px, calc(var(--u) * 6));
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden; overscroll-behavior: none; touch-action: manipulation; background: #05060d; color: var(--cream); }
body { font-family: "Pixelify Sans", ui-monospace, monospace; -webkit-font-smoothing: antialiased; }
#view { position: fixed; left: 0; top: 0; width: 100vw; height: 100vh; display: block; image-rendering: pixelated; }   /* main.js sets the exact size */
#hud { position: fixed; left: 0; top: 0; width: 100vw; height: 100vh; pointer-events: none; overflow: hidden; }
#hud > * { pointer-events: auto; }
[hidden] { display: none !important; }

/* a pixel frame: light 1-texel border, dark inner ring, notched corners */
.frame {
  --b: var(--night9);
  background: linear-gradient(180deg, rgba(16, 20, 42, 0.94), rgba(8, 10, 22, 0.94));
  border: var(--u) solid var(--b);
  box-shadow: inset 0 0 0 var(--u) var(--night4);
  clip-path: polygon(var(--u) 0, calc(100% - var(--u)) 0, 100% var(--u), 100% calc(100% - var(--u)), calc(100% - var(--u)) 100%, var(--u) 100%, 0 calc(100% - var(--u)), 0 var(--u));
}

/* ---- top: title (landscape only), trust, offline */
#title { position: absolute; left: var(--gutter); top: calc(var(--u) * 5); line-height: 1; }
#title .t1 { font-family: "Press Start 2P"; font-size: calc(var(--u) * 4.4); color: var(--gold); text-shadow: var(--u) var(--u) 0 #4a1510, calc(var(--u) * 1.6) calc(var(--u) * 1.6) 0 var(--night0); letter-spacing: 0.02em; }
#title .t2 { font-family: "Silkscreen"; font-size: calc(var(--u) * 2.8); color: var(--night9); margin-top: calc(var(--u) * 2.2); text-shadow: calc(var(--u) * 0.6) calc(var(--u) * 0.6) 0 var(--night0); }
body.portrait .only-landscape { display: none; }

#trust { position: absolute; right: var(--gutter); top: calc(var(--u) * 5); display: flex; align-items: center; gap: calc(var(--u) * 2.4); padding: calc(var(--u) * 1.6) calc(var(--u) * 3); white-space: nowrap; }
#trust .lbl { font-family: "Silkscreen"; font-weight: 700; font-size: calc(var(--u) * 3.2); color: var(--night10); letter-spacing: 0.08em; }
#trust .pips { display: flex; gap: calc(var(--u) * 1.4); }
#trust .pips i { width: calc(var(--u) * 5); height: calc(var(--u) * 5); background: var(--night3); box-shadow: inset 0 0 0 var(--u) var(--night6);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); transition: background 0.25s steps(3); }
#trust .pips i.on { background: var(--gold); box-shadow: inset 0 0 0 var(--u) #c08a1e; }
#trust .hint { font-family: "Silkscreen"; font-size: calc(var(--u) * 2.5); color: var(--night8); }
#trust.hurt { animation: hurt 0.5s steps(6); }
#trust.gain { animation: gain 0.6s steps(6); }
body.portrait #trust { right: auto; left: 50%; top: 10.6vh; transform: translateX(-50%); }
@keyframes hurt { 0%, 100% { --b: var(--night9); translate: 0; } 20% { --b: var(--blood); translate: calc(var(--u) * -1.5) 0; } 40% { --b: var(--blood); translate: calc(var(--u) * 1.5) 0; } 60% { --b: var(--blood); translate: calc(var(--u) * -1) 0; } }
@keyframes gain { 0%, 100% { --b: var(--night9); } 20%, 60% { --b: var(--gold); } }

#offline { position: absolute; right: var(--gutter); top: calc(var(--u) * 19); z-index: 2; display: flex; align-items: center; gap: 0.5em; font: 600 calc(var(--u) * 3) / 1 "IBM Plex Mono", ui-monospace, monospace; letter-spacing: 0.06em;
  color: var(--d-go); background: var(--d-go-soft); border: 2px solid rgba(76, 196, 138, 0.55); border-radius: 999px; padding: 0.45em 0.9em; }
#offline .dot { width: 0.55em; height: 0.55em; border-radius: 50%; background: var(--d-go); box-shadow: 0 0 0.6em var(--d-go); }
@keyframes blink { 50% { opacity: 0.35; } }
body.portrait #offline { top: calc(10.6vh + var(--u) * 13); left: 50%; right: auto; transform: translateX(-50%); }

/* ---- bottom stack: dialogue, chip, input */
#stack { position: absolute; left: 50%; transform: translateX(-50%); top: calc(var(--feet) + var(--u) * 3); width: min(calc(100vw - 2 * var(--gutter)), calc(var(--u) * 196)); display: flex; flex-direction: column; align-items: center; gap: calc(var(--u) * 2.4); }
body.portrait #stack { top: calc(var(--feet) + var(--u) * 4); width: calc(100vw - 2 * var(--gutter)); }
#dialog { width: 100%; padding: calc(var(--u) * 2.6) calc(var(--u) * 4) calc(var(--u) * 3); display: grid; gap: calc(var(--u) * 1.6); }
#dialog .row { display: grid; grid-template-columns: calc(var(--u) * 15) 1fr auto; align-items: baseline; gap: calc(var(--u) * 2); }
#dialog .who { font-family: "Silkscreen"; font-weight: 700; font-size: calc(var(--u) * 2.9); letter-spacing: 0.06em; text-align: right; }
#dialog .you .who { color: var(--night8); }
#dialog .guard .who { color: var(--gold); }
#dialog .you .txt { font-size: calc(var(--u) * 4.6); color: var(--night10); line-height: 1.2; overflow-wrap: anywhere; }
#dialog .guard .txt { font-size: calc(var(--u) * 6.4); font-weight: 500; color: var(--cream); line-height: 1.12; min-height: 1.12em; text-shadow: calc(var(--u) * 0.5) calc(var(--u) * 0.5) 0 var(--night0); }
#dialog .guard .txt.wait { color: var(--night8); animation: blink 0.8s steps(2) infinite; }
#dialog .more { font-size: calc(var(--u) * 3); color: var(--gold); opacity: 0; align-self: end; }
#dialog .more.show { opacity: 1; animation: bob 0.7s steps(2) infinite; }
@keyframes bob { 50% { transform: translateY(calc(var(--u) * 0.8)); } }
body.portrait #dialog .row { grid-template-columns: 1fr auto; }
body.portrait #dialog .who { text-align: left; grid-column: 1 / -1; margin-bottom: calc(var(--u) * -0.6); }

/* the decision chip, in Dopp's dashboard style: flat, mono, legible numbers */
.chip { display: inline-flex; flex-wrap: wrap; justify-content: center; align-items: baseline; column-gap: 0.55em; row-gap: 0.15em; width: max-content; max-width: calc(100vw - 2 * var(--gutter)); flex-shrink: 0;
  font: 500 calc(var(--u) * 4.6) / 1.25 "IBM Plex Mono", ui-monospace, Menlo, monospace; color: var(--d-ink);
  background: var(--d-surface); border: 2px solid var(--d-line); border-radius: 8px; padding: 0.5em 0.9em; box-shadow: 0 calc(var(--u) * 1.2) 0 rgba(0, 0, 0, 0.45); -webkit-font-smoothing: antialiased; }
body.portrait .chip { font-size: min(calc(var(--u) * 3.7), 3.3vw); }
.chip.stale { opacity: 0.3; filter: grayscale(1); transition: opacity 0.15s; }
.chip.pop { animation: chip-in 0.28s cubic-bezier(.2, .9, .3, 1.3); }
@keyframes chip-in { from { opacity: 0; transform: translateY(calc(var(--u) * 2)) scale(0.96); } }
#say { width: 100%; display: flex; align-items: center; gap: calc(var(--u) * 2); padding: calc(var(--u) * 1.8) calc(var(--u) * 2) calc(var(--u) * 1.8) calc(var(--u) * 3.6); --b: var(--gold); }
#say .caret { font-size: calc(var(--u) * 6); color: var(--gold); line-height: 1; margin-top: calc(var(--u) * -0.8); }
#line { flex: 1; min-width: 0; background: transparent; border: 0; outline: 0; color: var(--cream); font: 500 max(16px, calc(var(--u) * 5.2)) / 1.2 "Pixelify Sans", ui-monospace, monospace; caret-color: var(--gold); padding: calc(var(--u) * 0.8) 0; }
#line::placeholder { color: var(--night7); }
/* a textarea that looks like the old one-line input and grows with a long line (main.js fitLine) */
#line { display: block; resize: none; overflow-y: auto; height: auto; scrollbar-width: none; -webkit-appearance: none; appearance: none; border-radius: 0; overflow-wrap: anywhere; }
#line::-webkit-scrollbar { display: none; }
#line.long { font-size: max(16px, calc(var(--u) * 4.2)); }
#say { align-items: center; }
#say button { font: 700 calc(var(--u) * 3) / 1 "Silkscreen"; letter-spacing: 0.06em; color: var(--night2); background: var(--gold); border: 0; padding: calc(var(--u) * 2) calc(var(--u) * 3); cursor: pointer;
  clip-path: polygon(var(--u) 0, calc(100% - var(--u)) 0, 100% var(--u), 100% calc(100% - var(--u)), calc(100% - var(--u)) 100%, var(--u) 100%, 0 calc(100% - var(--u)), 0 var(--u)); box-shadow: inset 0 calc(var(--u) * -1) 0 #c08a1e; }
#say button .ret { opacity: 0.6; }
#say.busy { --b: var(--night7); }
#say.busy button { background: var(--night6); color: var(--night10); box-shadow: none; }
#say:focus-within { --b: var(--gold-hi); }

#loader { width: 100%; padding: calc(var(--u) * 2.4) calc(var(--u) * 3.6) calc(var(--u) * 3); display: grid; gap: calc(var(--u) * 2); --b: var(--night9); }
#loader .lrow { display: flex; justify-content: space-between; align-items: baseline; gap: calc(var(--u) * 3); flex-wrap: wrap; }
#loader .lname { font: 700 calc(var(--u) * 3.4) / 1 "Silkscreen"; letter-spacing: 0.06em; color: var(--night10); }
#loader .lmb { font: 500 calc(var(--u) * 3.6) / 1 "IBM Plex Mono", ui-monospace, monospace; color: var(--d-ink); font-variant-numeric: tabular-nums; }
#loader .bar { height: calc(var(--u) * 5); background: var(--night2); box-shadow: inset 0 0 0 var(--u) var(--night6); padding: var(--u); }
#loader .bar i { display: block; height: 100%; width: 0; background: repeating-linear-gradient(90deg, var(--gold) 0 calc(var(--u) * 4), #c08a1e calc(var(--u) * 4) calc(var(--u) * 5)); transition: width 0.15s steps(4); }
#loader.ready { --b: var(--d-go); } #loader.ready .lname { color: var(--d-go); } #loader.ready .bar i { background: var(--d-go); }
#loader.failed { --b: var(--blood); } #loader.failed .lname { color: var(--d-stop); } #loader.failed .lmb { color: var(--d-stop); font-size: calc(var(--u) * 3); }

/* ---- the win beat */
#win { position: absolute; left: 50%; top: 17vh; transform: translateX(-50%); text-align: center; white-space: nowrap; }
body.portrait #win { top: 19vh; white-space: normal; width: 94vw; }
#win .big { font-family: "Press Start 2P"; font-size: calc(var(--u) * 8); line-height: 1.25; color: var(--gold-hi); text-shadow: var(--u) var(--u) 0 #963315, calc(var(--u) * 2) calc(var(--u) * 2) 0 var(--night0); }
body.portrait #win .big { font-size: calc(var(--u) * 7.2); }
#win .small { margin-top: calc(var(--u) * 3); font: 700 calc(var(--u) * 3.4) / 1 "Silkscreen"; color: var(--cream); letter-spacing: 0.08em; text-shadow: calc(var(--u) * 0.6) calc(var(--u) * 0.6) 0 var(--night0); }
#win.show .big { animation: win-in 0.9s steps(9); }
@keyframes win-in { 0% { opacity: 0; transform: translateY(calc(var(--u) * -6)) scale(1.4); } 60% { opacity: 1; transform: translateY(0) scale(0.95); } 100% { transform: none; } }

/* ---- dev overlay: where requests go (the "change one URL" beat) */
#dev { position: absolute; left: var(--gutter); top: calc(var(--u) * 19); max-width: min(40vw, 760px); font: 500 calc(var(--u) * 3.3) / 1.45 "IBM Plex Mono", ui-monospace, monospace; color: var(--d-ink);
  background: rgba(22, 26, 34, 0.94); border: 2px solid var(--d-line); border-radius: 8px; padding: 0.7em 0.95em; }
body.portrait #dev { top: calc(10.6vh + var(--u) * 13); right: var(--gutter); max-width: none; font-size: calc(var(--u) * 3.3); }
body.portrait.is-offline #dev { top: calc(10.6vh + var(--u) * 24); }
.dev-h { font-size: 0.8em; color: var(--d-slate); text-transform: lowercase; margin-bottom: 0.2em; }
.dev-row { display: grid; grid-template-columns: 6.5em 1fr; gap: 0.6em; }
.dev-row .k { color: var(--d-slate); } .dev-row .v { color: var(--d-accent); overflow-wrap: anywhere; }
#devLog { margin-top: 0.5em; border-top: 1px solid var(--d-line); padding-top: 0.4em; font-size: 0.86em; color: var(--d-slate); }
#devLog:empty { display: none; }
#devLog .dl { display: grid; grid-template-columns: 5.2em 5.6em 3em 5em 1fr; gap: 0.6em; white-space: nowrap; }
#devLog .friendly { color: var(--d-go); } #devLog .bribe { color: var(--d-wait); } #devLog .threat { color: var(--d-stop); } #devLog .trick { color: var(--d-purple); } #devLog .nonsense { color: var(--d-teal); } #devLog .err { color: var(--d-stop); }
#ptBtn { margin-top: 0.6em; font: inherit; font-size: 0.86em; color: var(--d-ink); background: var(--d-panel); border: 1px solid var(--d-line); border-radius: 6px; padding: 0.25em 0.7em; cursor: pointer; }

/* ---- talk mode (a phone keyboard is up, main.js): #view and #hud are the strip above the keyboard; the camera is on a close-up.
   Trust shrinks to the top, his last reply becomes a speech bubble pointing up at him, the input sits on the keyboard. */
body.talk #trust { top: calc(var(--u) * 1.6); left: 50%; right: auto; transform: translateX(-50%) scale(0.72); transform-origin: top center; }
body.talk #offline { top: calc(var(--u) * 1.6); right: calc(var(--u) * 2); left: auto; transform: scale(0.7); transform-origin: top right; }
body.talk #title, body.talk #dev, body.talk #goal, body.talk #sugg, body.talk #dopp { display: none !important; }
body.talk #win { top: 28%; width: 94vw; white-space: normal; } body.talk #win .big { font-size: calc(var(--u) * 5.6); }
body.talk #stack { top: auto; bottom: calc(var(--u) * 1.6); transform: translateX(-50%); transition: none; gap: calc(var(--u) * 1.4); }
body.talk #dialog { padding: calc(var(--u) * 2) calc(var(--u) * 3.4) calc(var(--u) * 2.2); gap: 0; }
body.talk #dialog .row.you, body.talk #dialog .who, body.talk #dialog .more { display: none !important; }
body.talk #dialog .row { grid-template-columns: 1fr; }
body.talk #dialog .guard .txt { font-size: calc(var(--u) * 5.2); text-align: center; }
body.talk .chip { font-size: min(calc(var(--u) * 3.1), 2.9vw); padding: 0.35em 0.8em; }
/* the bubble's tail: a stepped pixel triangle in the frame's border colour, pointing up at the guard */
body.talk #stack:has(#dialog:not([hidden]))::before { content: ""; order: -1; width: calc(var(--u) * 7); height: calc(var(--u) * 3.5); margin-bottom: calc(var(--u) * -1.4 - 1px); background: var(--night9);
  clip-path: polygon(42.8% 0, 57.2% 0, 57.2% 28.6%, 71.4% 28.6%, 71.4% 57.2%, 85.7% 57.2%, 85.7% 85.7%, 100% 85.7%, 100% 100%, 0 100%, 0 85.7%, 14.3% 85.7%, 14.3% 57.2%, 28.6% 57.2%, 28.6% 28.6%, 42.8% 28.6%); }

/* ---- the goal (portrait; landscape has the title) */
body.landscape .only-portrait { display: none; }
#goal { position: absolute; left: 50%; transform: translateX(-50%); top: calc(10.6vh + var(--u) * 12.5); white-space: nowrap; font: 700 calc(var(--u) * 2.9) / 1 "Silkscreen"; letter-spacing: 0.06em; color: var(--night10); text-shadow: calc(var(--u) * 0.5) calc(var(--u) * 0.5) 0 var(--night0); pointer-events: none; }
body.portrait #offline { top: calc(10.6vh + var(--u) * 19); }
body.won #offline, body.won #goal { visibility: hidden; }   /* the win card has the floor; they come back with the next night */

/* ---- the HUD: the model's measured size, the last decision's time, and where it runs. Small, always there. */
#brain, #dopp { position: absolute; font: 500 max(11px, calc(var(--u) * 2.5)) / 1.2 "IBM Plex Mono", ui-monospace, Menlo, monospace; color: var(--d-slate); background: rgba(12, 14, 22, 0.78);
  border: 1px solid var(--d-line); border-radius: 6px; padding: 0.35em 0.65em; -webkit-font-smoothing: antialiased; }
#brain { left: var(--gutter); bottom: calc(var(--u) * 3); display: flex; flex-direction: column; align-items: flex-start; row-gap: 0.15em; max-width: calc(100vw - 2 * var(--gutter) - 12em); }
/* two rows: "33.8 MB · 100% offline model" / "7 ms per line ⓘ"; a row wraps only between its parts */
#brain .brow { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.45em; }
#brain .brow > * { white-space: nowrap; }
#brain .binfo { color: var(--d-accent); margin-left: -0.1em; }
#brain b { color: var(--d-ink); font-weight: 600; font-variant-numeric: tabular-nums; }
#brain .bsep { color: #4B5363; }
#brain .bnote { color: var(--d-go); }
#dopp { right: var(--gutter); bottom: calc(var(--u) * 3); text-decoration: none; }
#dopp b { color: var(--d-ink); font-weight: 600; }
#dopp:hover, #dopp:focus-visible { color: var(--d-ink); border-color: var(--d-slate); }
body.landscape #brain { top: calc(var(--u) * 17); bottom: auto; }
body.landscape #dopp { top: calc(var(--u) * 17); bottom: auto; }
body.portrait #brain, body.portrait #dopp { top: max(8px, env(safe-area-inset-top)); bottom: auto; }
/* phones: the corner stacks "built with / dopp.sh" so both boxes fit side by side, the same height */
body.portrait #dopp { display: flex; flex-direction: column; align-items: flex-end; row-gap: 0.15em; }
body.portrait #brain { left: 8px; max-width: calc(100vw - 16px - 8px - 7.6em); }
body.portrait #dopp { right: 8px; }
body.talk #brain { top: auto; bottom: auto; top: calc(var(--u) * 1.6); left: calc(var(--u) * 2); transform: scale(0.85); transform-origin: top left; }

/* ---- his read of you: five bars */
#read { display: grid; justify-content: stretch; gap: 0.3em; width: 100%; max-width: 100%; padding: 0.45em 0.75em 0.55em; font-size: min(calc(var(--u) * 3), 12.5px); }
#read .r-head { display: flex; align-items: baseline; gap: 0.6em; }
#read .r-k { color: var(--d-slate); text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.85em; white-space: nowrap; }
#read .r-rule { color: var(--d-wait); flex: 1; text-align: right; font-size: 0.92em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#read .r-ms { color: var(--d-ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
#read .r-bars { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0.55em; }
.r-b { display: grid; grid-template-columns: 1fr auto; grid-template-rows: auto auto; column-gap: 0.3em; row-gap: 0.2em; color: var(--d-slate); min-width: 0; }
.r-b .r-l { overflow: hidden; text-overflow: clip; white-space: nowrap; }
.r-b .r-p { font-variant-numeric: tabular-nums; text-align: right; }
.r-b .r-t { grid-column: 1 / -1; height: 0.5em; background: #242a36; border-radius: 2px; overflow: hidden; }
.r-b .r-t i { display: block; height: 100%; background: currentColor; border-radius: 2px; transition: width 0.35s cubic-bezier(.2, .9, .3, 1); }
.r-b.friendly .r-t { color: var(--d-go); } .r-b.bribe .r-t { color: var(--d-wait); } .r-b.threat .r-t { color: var(--d-stop); } .r-b.trick .r-t { color: var(--d-purple); } .r-b.nonsense .r-t { color: var(--d-teal); }
.r-b.top { font-weight: 600; }
.r-b.top.friendly { color: var(--d-go); } .r-b.top.bribe { color: var(--d-wait); } .r-b.top.threat { color: var(--d-stop); } .r-b.top.trick { color: var(--d-purple); } .r-b.top.nonsense { color: var(--d-teal); }
#read.unasked .r-bars { opacity: 0.35; }
body.talk #read { padding: 0.3em 0.6em 0.4em; font-size: min(calc(var(--u) * 2.6), 11px); }

/* ---- an aside under his line: the mood's tell, and hints */
#aside { font: 500 calc(var(--u) * 3.6) / 1.25 "Pixelify Sans", ui-monospace, monospace; color: var(--night9); font-style: italic; margin-top: calc(var(--u) * 0.6);  white-space: pre-line; }
body.landscape #aside { padding-left: calc(var(--u) * 17); }
#aside.pop { animation: chip-in 0.35s cubic-bezier(.2, .9, .3, 1.3); }
body.talk #aside { text-align: center; font-size: calc(var(--u) * 3.1); margin-top: calc(var(--u) * 1); }

/* ---- suggestion chips */
#sugg { width: 100%; display: flex; flex-wrap: wrap; justify-content: center; gap: calc(var(--u) * 1.4); }
#sugg .sg { font: 500 max(13px, calc(var(--u) * 3.4)) / 1.2 "Pixelify Sans", ui-monospace, monospace; color: var(--cream); background: rgba(16, 20, 42, 0.9); border: 2px solid var(--night6);
  border-radius: 999px; padding: 0.45em 0.9em; cursor: pointer; text-align: left; max-width: 100%; touch-action: manipulation; }
#sugg .sg:hover, #sugg .sg:focus-visible { border-color: var(--gold); color: var(--gold-hi); outline: none; }
#sugg .sg:active { transform: translateY(1px); }
#sugg.stale { opacity: 0.35; pointer-events: none; }
body.portrait #sugg { flex-direction: column; align-items: stretch; gap: 6px; }
body.portrait #sugg .sg { border-radius: 10px; padding: 0.5em 0.8em; min-height: 40px; }
#say.nudge { animation: nudge 0.35s steps(6); }
@keyframes nudge { 20% { translate: -6px 0; } 40% { translate: 6px 0; } 60% { translate: -4px 0; } 80% { translate: 3px 0; } }

/* ---- loading: a plain message and a retry when it fails */
#loader .lmsg { font: 500 max(13px, calc(var(--u) * 3.2)) / 1.35 "IBM Plex Mono", ui-monospace, monospace; color: var(--d-wait); }
#loader.failed .lmsg { color: var(--d-stop); }
/* a failed load: no progress bar, the message wraps, the raw error behind "details"; the help and links step aside for it */
#loader.failed .bar { display: none; }
#loader .lmsg, #loader .ldet code { overflow-wrap: anywhere; }
#loader .ldet { font: 500 max(12px, calc(var(--u) * 2.6)) / 1.4 "IBM Plex Mono", ui-monospace, monospace; color: var(--d-slate); }
#loader .ldet summary { cursor: pointer; width: fit-content; }
#loader .ldet code { display: block; margin-top: 0.4em; max-height: 8.5em; overflow-y: auto; white-space: pre-wrap; color: var(--d-slate); }
body.load-failed #sugg, body.load-failed #made { display: none !important; }
#retry { justify-self: start; font: 700 calc(var(--u) * 3) / 1 "Silkscreen"; letter-spacing: 0.06em; color: var(--night2); background: var(--gold); border: 0; padding: calc(var(--u) * 2) calc(var(--u) * 3.4); cursor: pointer; min-height: 40px; }

/* ---- the win card: the numbers, and one line about how it's made */
#win { pointer-events: auto; }
#win .wline { margin: calc(var(--u) * 3.4) auto 0; max-width: min(88vw, 34em); white-space: normal; font: 500 max(13px, calc(var(--u) * 3.1)) / 1.4 "IBM Plex Mono", ui-monospace, monospace; color: var(--night10);
  background: rgba(12, 14, 22, 0.82); border: 1px solid var(--d-line); border-radius: 8px; padding: 0.55em 0.9em; }
#win .wline a { color: var(--gold-hi); font-weight: 600; }
#again { margin-top: calc(var(--u) * 3); font: 700 calc(var(--u) * 3.2) / 1 "Silkscreen"; letter-spacing: 0.06em; color: var(--night2); background: var(--gold); border: 0; padding: calc(var(--u) * 2.2) calc(var(--u) * 4); cursor: pointer; min-height: 44px;
  clip-path: polygon(var(--u) 0, calc(100% - var(--u)) 0, 100% var(--u), 100% calc(100% - var(--u)), calc(100% - var(--u)) 100%, var(--u) 100%, 0 calc(100% - var(--u)), 0 var(--u)); box-shadow: inset 0 calc(var(--u) * -1) 0 #c08a1e; }
#devInfo { color: var(--d-accent); overflow-wrap: anywhere; }

/* ---- portrait (phones): the stack has to fit under the guard: no YOU row (the line is still in the input's history), tighter text */
body.portrait #stack { top: calc(var(--feet) - var(--u) * 6); gap: 6px; }
body.portrait #dialog .row.you { display: none !important; }
body.portrait #dialog { padding: calc(var(--u) * 2) calc(var(--u) * 3.4) calc(var(--u) * 2.2); gap: calc(var(--u) * 0.8); }
body.portrait #dialog .guard .txt { font-size: calc(var(--u) * 5.4); }
body.portrait #aside { font-size: max(12.5px, calc(var(--u) * 3.3)); }
body.portrait #sugg .sg { font-size: 13.5px; padding: 0.4em 0.75em; min-height: 36px; }
body.landscape #stack { top: calc(var(--feet) - var(--u) * 2); gap: calc(var(--u) * 1.8); }
body.landscape #sugg .sg { font-size: max(13px, calc(var(--u) * 3)); padding: 0.35em 0.85em; }
body.portrait .r-b { grid-template-columns: 1fr; }
body.portrait .r-b .r-p { grid-row: 3; text-align: left; font-size: 0.95em; }
body.portrait .r-b .r-l { text-overflow: clip; }
/* talk mode wins over the portrait / landscape stack positions above */
body.talk.portrait #stack, body.talk.landscape #stack { top: auto; bottom: calc(var(--u) * 1.6); }
body.talk.portrait #brain, body.talk.landscape #brain { top: calc(var(--u) * 11.5); left: 50%; bottom: auto; transform: translateX(-50%); font-size: 10px; max-width: none; white-space: nowrap; flex-direction: row; column-gap: 0.45em; }
body.talk #brain .brow { flex-wrap: nowrap; }
body.talk #brain .brow + .brow::before { content: "·"; color: #4B5363; }

/* "walk away": a way out of a long round, quieter than the suggestions */
.sg.walk { opacity: 0.75; font-style: italic; }

/* ---- the HUD is a button: tap it for "what's in his head" (measured facts, main.js) */
button#brain { cursor: pointer; text-align: left; -webkit-appearance: none; appearance: none; }
#brain:hover, #brain:focus-visible { border-color: var(--d-slate); }
#special { position: absolute; left: 50%; transform: translateX(-50%); top: calc(var(--u) * 17 + 4.4em); width: min(92vw, 31em); z-index: 5; padding: 0.9em 1.1em 1em;
  font: 500 max(12.5px, calc(var(--u) * 2.9)) / 1.45 "IBM Plex Mono", ui-monospace, monospace; color: var(--d-ink); }
body.portrait #special { top: calc(max(8px, env(safe-area-inset-top)) + 3.8em); }
#special .sp-h { display: flex; justify-content: space-between; align-items: center; font: 700 1.05em / 1 "Silkscreen"; letter-spacing: 0.06em; color: var(--gold); margin-bottom: 0.6em; }
#spClose { background: none; border: 0; color: var(--d-slate); font: inherit; cursor: pointer; padding: 0 0.2em; }
#special .sp-fact { display: grid; grid-template-columns: 8.2em 1fr; gap: 0.6em; margin: 0.4em 0; }
#special .sp-fact b { color: var(--d-go); font-weight: 600; font-variant-numeric: tabular-nums; }
#special .sp-fact span { color: var(--d-slate); }
#special .sp-dare { margin-top: 0.7em; color: var(--gold-hi); }
#special .sp-links { margin-top: 0.8em; color: var(--d-slate); }
#special a { color: var(--d-slate); text-decoration: underline; text-underline-offset: 2px; }
#special a:hover { color: var(--d-ink); }
/* the links under the input and on the win card sit over the scene: a dark backing, light text, big enough to tap */
#made, #win .wfoot { width: fit-content; max-width: calc(100% - 16px); margin-left: auto; margin-right: auto; padding: 0.5em 1em; border-radius: 999px;
  background: rgba(12, 14, 22, 0.86); border: 1px solid var(--d-line); box-shadow: 0 2px 0 rgba(0, 0, 0, 0.35); -webkit-font-smoothing: antialiased; }
#made a, #win .wfoot a { color: #D5DAE3; text-decoration: underline; text-decoration-color: rgba(213, 218, 227, 0.45); text-underline-offset: 3px; }
#made a:hover, #win .wfoot a:hover, #made a:focus-visible, #win .wfoot a:focus-visible { color: #fff; text-decoration-color: currentColor; }
.msep { margin: 0 0.55em; color: #6B7385; }
/* "how was this made? · source": small, at the bottom of the stack */
#made { margin-top: calc(var(--u) * 1.4); font: 500 max(12.5px, calc(var(--u) * 2.6)) / 1.2 "IBM Plex Mono", ui-monospace, monospace; color: #B4BBC8; text-align: center; }
body.talk #made { display: none; }
/* the win card: share the real path, or play again */
#win .wbtns { display: flex; gap: calc(var(--u) * 2.4); justify-content: center; flex-wrap: wrap; }
#share { margin-top: calc(var(--u) * 3); font: 700 calc(var(--u) * 3.2) / 1 "Silkscreen"; letter-spacing: 0.06em; color: var(--gold-hi); background: rgba(8, 10, 22, 0.6);
  border: 2px solid var(--gold); padding: calc(var(--u) * 2.2 - 2px) calc(var(--u) * 4); cursor: pointer; }
#win .whow { display: inline-block; margin-top: calc(var(--u) * 2.6); font: 500 max(11px, calc(var(--u) * 2.4)) / 1.2 "IBM Plex Mono", ui-monospace, monospace; }
#special .sp-maker { margin-top: 0.5em; color: #6B7385; font-size: 0.92em; }
#win .wfoot { margin-top: calc(var(--u) * 2.6); font: 500 max(12.5px, calc(var(--u) * 2.6)) / 1.2 "IBM Plex Mono", ui-monospace, monospace; color: #B4BBC8; }
#win .wfoot { font-size: min(max(12.5px, calc(var(--u) * 2.6)), 3.6vw); line-height: 1.5; }   /* one line down to 320 px wide */
#win .wfoot .whow, #win .wfoot .wmaker, #made a { white-space: nowrap; }
#win .wfoot .whow { margin-top: 0; }
#special .sp-maker a { color: var(--d-slate); text-decoration: underline; text-underline-offset: 2px; }

/* ---- his read in one line ("read: bribe 94% · 28 ms · rule"); tap it for all five bars */
#read { cursor: pointer; }
#read .r-bars { display: none; }
#read.open .r-bars { display: grid; }
#read .r-k { text-transform: none; letter-spacing: 0.02em; }
#read .r-head::after { content: "▾"; color: #4B5363; font-size: 0.85em; }
#read.open .r-head::after { content: "▴"; }

/* ---- help when stuck: hints name a kind of move (tap: it becomes the input's placeholder), "write one for me" fills the input.
   Until then only a quiet "stuck? ideas". Nothing here sends a line. */
#sugg .sg.stuck, #sugg .sg.walk { font: 500 max(11.5px, calc(var(--u) * 2.6)) / 1.2 "IBM Plex Mono", ui-monospace, monospace; color: var(--d-slate);
  background: none; border: 0; box-shadow: none; padding: 0.3em 0.6em; text-decoration: underline; text-underline-offset: 2px; font-style: normal; opacity: 1; }
#sugg .sg.hint { font-style: italic; color: var(--night10); border-style: dashed; }
#sugg .sg.hint::before { content: "try: "; font-style: normal; color: var(--d-slate); }
#sugg .sg.write { color: var(--gold-hi); border-color: var(--gold); background: rgba(8, 10, 22, 0.6); }
#sugg:has(.sg.stuck) { justify-content: center; }
