:root{
  --panel:#123444;--line:#245266;--ink:#e8fbff;--muted:#a9cdd8;--mint:#39e6b0;--teal:#22c3e6;--red:#ff5566;--gold:#ffcf47;
  --font-main:'Jersey 10', system-ui, sans-serif;
  --bg:#071720;--panel-bg:#0e2a38;--panel-bg-soft:#12333f;--panel-border:#1f4b5e;--overlay-bg:#06141c;
  --btn-bg:#153a4a;--btn-border:#2a6070;--btn-text:#dff3f8;
  --row-bg:#0f2c3a;--row-border:#204a5a;
  /* shared pixel-art accent frame (Assets/Sprites/Menu UI/Imported UI/Panels/{color}/
     GridPanelFrame.png) used for .panel/.side-panel/#minimap — one colorway per theme.
     Deliberately the *small* 16x16 frame tile, not the 64x64 PanelInner used in an earlier
     pass: PanelInner's ~15px-thick ring read as a heavy black slab at any usable
     border-width, which is exactly what came back as "too harsh / too thick". This tile's
     ring is a couple of native px, so a thin border-image-width stays a crisp, light
     accent line instead of a chunky one. See .side-panel/#minimap/.panel for the
     border-image application. */
  --frame-img:url('../Assets/Sprites/Menu UI/Imported UI/Panels/Blue/GridPanelFrame.png');
  /* width doubled from an earlier 4px pass (2x the native ~4px ring, a clean multiplier
     that stays crisp) — 4px read as "too thin" once seen next to real content; this is the
     middle ground between that and the original 16px "too thick" PanelInner pass. */
  --frame-slice:4;--frame-w:8px;
}
:root[data-theme="offwhite"]{
  --ink:#2a2620;--muted:#6b6455;--mint:#0e8f63;--gold:#9c6b00;
  --bg:#f4f1ea;--panel-bg:#fbf9f3;--panel-bg-soft:#efeadd;--panel-border:#d8d2c2;--overlay-bg:#f4f1ea;
  --btn-bg:#ffffff;--btn-border:#c9c2ac;--btn-text:#2a2620;
  --row-bg:#efeadd;--row-border:#d8d2c2;
  /* Wood colorway — its inner accent ring (rgb(213,166,136)) is pixel-identical to the
     Gold button family's fill color (verified by direct sampling), so Wood frame + Gold
     buttons share one real accent color rather than two coincidentally-similar tans. */
  --frame-img:url('../Assets/Sprites/Menu UI/Imported UI/Panels/Wood/GridPanelFrame.png');
}
:root[data-theme="darkgrey"]{
  --ink:#e7e7ea;--muted:#9a9aa2;
  --bg:#18181b;--panel-bg:#232326;--panel-bg-soft:#2a2a2e;--panel-border:#3a3a3f;--overlay-bg:#18181b;
  --btn-bg:#2a2a2e;--btn-border:#46464c;--btn-text:#e7e7ea;
  --row-bg:#232326;--row-border:#3a3a3f;
  --frame-img:url('../Assets/Sprites/Menu UI/Imported UI/Panels/Purple/GridPanelFrame.png');
}
*{box-sizing:border-box;margin:0;padding:0}
body{background:var(--bg);color:var(--ink);font-family:var(--font-main);font-size:22px;letter-spacing:1.2px;display:flex;flex-direction:column;align-items:center;min-height:100vh;padding:8px;}
.logo{font-family:'Press Start 2P',monospace;}
.num{font-family:'VT323',monospace;font-size:1.18em;letter-spacing:.5px;}
.stage{position:relative;width:1400px;max-width:100%;}
.game-row{display:flex;gap:10px;align-items:flex-start;justify-content:center;}
/* positioned ancestor for #pharm — sized to hug the canvas exactly (not the wider
   .game-row/.stage, and not the viewport) so the popup's position:absolute anchor tracks
   the actual game window as the page scrolls, instead of a position:fixed viewport anchor
   that stays put on screen while the canvas moves, letting the two drift apart. Unclipped
   (no overflow:hidden) so the popup can still visibly slide up from below the canvas into
   view, same as before. */
.game-wrap{position:relative;display:inline-block;flex:0 0 auto;line-height:0;}
canvas{display:block;background:#dfeaee;border:3px solid #b7c7cd;image-rendering:pixelated;border-radius:6px;flex:0 0 auto;}

/* pixel-art frame (see --frame-img at :root) replacing the old flat CSS border — the frame
   sits in the border box (outside padding/content), so the panel's own background-color
   still paints normally underneath/through it; no JS injection needed, unlike the old
   .pb-piece system this pattern replaces (see .panel below). */
.side-panel{width:220px;flex:0 0 220px;background:var(--panel-bg);border-style:solid;border-width:var(--frame-w);border-image-source:var(--frame-img);border-image-slice:var(--frame-slice);border-image-width:var(--frame-w);border-radius:0;padding:12px;display:flex;flex-direction:column;gap:10px;align-self:stretch;position:relative;image-rendering:pixelated;}

/* cleaner label/value row (was: big centered stacked text) — icon-less caption on the left,
   value on the right, thin divider between rows so the list reads as one coherent stat
   sheet rather than a stack of separately-centered blocks. */
.side-panel .item{font-family:var(--font-main);font-size:22px;font-weight:600;color:var(--ink);letter-spacing:.5px;display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:8px;padding:5px 2px;border-bottom:1px solid var(--panel-border);}
.item-h{font-size:.62em;color:var(--muted);letter-spacing:1.2px;text-transform:uppercase;font-weight:700;}
.item-row{display:flex;align-items:center;justify-content:center;gap:5px;}
.coin{image-rendering:pixelated;}
.side-panel .val{color:var(--mint);} .side-panel .best{color:var(--gold);}
#lives{display:flex;align-items:center;gap:3px;}
.heart-icon{width:20px;height:17px;background-size:100% 100%;image-rendering:pixelated;display:inline-block;flex:0 0 auto;}
.heart-icon.full{background-image:url('../Assets/Sprites/In-Game UI/Default Theme/Icons/HeartDetailed_Full.png');}
.heart-icon.empty{background-image:url('../Assets/Sprites/In-Game UI/Default Theme/Icons/HeartDetailed_Empty.png');}
#rightC{color:var(--mint);} #wrongC{color:var(--red);}
#statsPanel #endBtn{margin-top:auto;}
#minimap{width:100%;height:auto;border-style:solid;border-width:var(--frame-w);border-image-source:var(--frame-img);border-image-slice:var(--frame-slice);border-image-width:var(--frame-w);border-radius:0;flex:0 0 auto;image-rendering:pixelated;}
.panel-t.small{font-size:20px;margin-bottom:4px;padding-bottom:6px;justify-content:center;text-align:center;}
/* justify-content:flex-start, not center — a flex container with more content than fits
   and center-alignment overflows equally on both edges, but overflow:auto scrolling can
   only ever reach the "positive" (bottom) side of that; the top overflow becomes
   permanently stuck off-screen with no way to scroll to it. flex-start keeps everything
   anchored to a reachable top edge instead. */
.sticker-info{display:flex;flex-direction:column;justify-content:flex-start;gap:12px;flex:1;overflow-y:auto;min-height:60px;}
.sticker-empty{font-size:19px;color:var(--muted);text-align:center;padding:12px 4px;font-family:var(--font-main);line-height:1.4;}
/* pixel-art sticker frame (Assets/Sprites/Side Panel/Sticker UI.png, split into 5 pieces —
   see the "Sticker Top/Middle/Bottom/Dot Orange/Dot Green.png" crops). Native card width is
   96px with a 2px border; sidebar content is 192px wide (220px panel - 14px padding each
   side), so this renders at a clean 2x — same reasoning as the pop-up's --pharm-scale, but
   kept simple here since there's only one scale tier (the sidebar's width doesn't change
   with viewport height the way the pop-up's did). Text stays normal CSS px throughout
   (not tied to that 2x/native-px system) — the lesson from the pop-up was that forcing
   freeform text through the same tiny native-pixel grid as the art is what kept needing
   "still too small" fixes; only the frame art itself benefits from the pixel-scale rule.
   Top/bottom are fixed-height caps; the middle tiles vertically (background-repeat:repeat-y)
   to fit however much text a given chart needs, instead of one fixed-size image. */
.chart-mini{width:100%;position:relative;}
.chart-mini .sc-top{width:100%;height:20px;background:url('../Assets/Sprites/Side Panel/Sticker Top.png');background-size:100% 100%;image-rendering:pixelated;}
.chart-mini .sc-bottom{width:100%;height:18px;background:url('../Assets/Sprites/Side Panel/Sticker Bottom.png');background-size:100% 100%;image-rendering:pixelated;}
.chart-mini .sc-mid{width:100%;box-sizing:border-box;padding:6px 10px 8px;
  background:url('../Assets/Sprites/Side Panel/Sticker Middle.png');background-repeat:repeat-y;background-size:100% 48px;image-rendering:pixelated;
  font-family:var(--font-main);text-align:center;}
.chart-mini .sc-dot{position:absolute;top:7px;left:7px;width:14px;height:14px;
  background:url('../Assets/Sprites/Side Panel/Sticker Dot Orange.png');background-size:100% 100%;image-rendering:pixelated;}
.chart-mini.done .sc-dot{background-image:url('../Assets/Sprites/Side Panel/Sticker Dot Green.png');}
/* dark, fixed colors rather than the theme's --ink/--teal/--mint/--gold/--muted vars —
   those are tuned for light text on the dark theme's own dark card background, but this
   card's background is the cream/white pixel art now, so light theme text would be nearly
   invisible against it regardless of which color theme the player has picked. */
.chart-mini .cm-room{font-size:17px;font-weight:700;color:#1b6e7d;text-transform:uppercase;letter-spacing:.5px;}
.chart-mini .cm-dx{font-size:20px;color:#2a2620;line-height:1.25;margin:4px 0;}
.chart-mini .cm-comp{font-size:16px;font-weight:700;color:#8a5a00;text-transform:uppercase;letter-spacing:.5px;}
.chart-mini .cm-rx{font-size:17px;color:#1f7a4f;margin-top:4px;}
.chart-mini .cm-rx.pending{color:#7a7264;font-style:italic;}
#endBtn{font-family:var(--font-main);font-size:22px;font-weight:600;cursor:pointer;background:#40202a;color:#ff9aa6;border:2px solid #7a3a44;border-radius:8px;padding:11px 12px;box-shadow:none;transition:.1s;width:100%;}
#endBtn:hover{background:#57202e;color:#ffb9c1;border-color:#a44b59;} #endBtn:active{transform:translateY(1px);}
#handbookBtn{font-family:var(--font-main);font-size:20px;font-weight:600;cursor:pointer;background:#123a2e;color:#6be6b0;border:2px solid #1f6b45;border-radius:8px;padding:11px 10px;box-shadow:none;transition:.1s;width:100%;}
#handbookBtn:hover{background:#184a3a;color:#8ef5c4;border-color:#2a9068;} #handbookBtn:active{transform:translateY(1px);}

/* inset:0 (full viewport, not a centered 1280px column) so the ward canvas never peeks out
   past the sides on a wide window — the old width:1280px;max-width:96vw could be narrower
   than .stage's own 1400px, leaving a sliver of the game visible on wide screens even
   though --overlay-bg was meant to fully hide it. --overlay-bg itself is now fully opaque
   (alpha 1, was .93-.96) for the same reason: a solid colour, not a faint see-through tint.
   z-index:10 — above every in-game overlay element (#pharm 6, .toast 7, #handbook 8) — so a
   menu screen always paints over whatever the ward was last showing, including mid-close-
   transition leftovers, instead of the old z-index:5 which sat BELOW #pharm and could let a
   still-closing pharmacy popup show through a menu opened right after it. */
.overlay{position:fixed;inset:0;display:flex;flex-direction:column;justify-content:center;align-items:center;background:var(--overlay-bg);text-align:center;padding:14px;z-index:10;overflow-y:auto;}
#startScreen,#runConfigScreen{padding:10px;}
.hidden{display:none!important;}
h1{font-size:32px;color:var(--ink);text-shadow:3px 3px 0 #000,0 0 22px rgba(57,230,176,.4);margin-bottom:8px;}
.cross{color:var(--red);}
.sub{color:var(--muted);max-width:660px;margin:8px auto 4px;font-size:19px;}
button{font-family:var(--font-main);font-size:16px;font-weight:600;letter-spacing:1px;cursor:pointer;background:var(--btn-bg);color:var(--btn-text);border:2px solid var(--btn-border);border-radius:9px;box-shadow:0 4px 0 rgba(0,0,0,.35);padding:8px 14px;margin:4px;transition:.08s;}
button:hover{transform:translateY(-2px);border-color:var(--mint);color:var(--mint);}
button:active{transform:translateY(3px);box-shadow:0 1px 0 rgba(0,0,0,.35);}
button.sel{border-color:var(--mint);color:var(--mint);background:rgba(57,230,176,.14);}
button.locked{opacity:.5;cursor:not-allowed;} button.locked:hover{transform:none;border-color:var(--btn-border);color:var(--btn-text);}
button.big{font-size:18px;color:#0d2b1f;background:var(--mint);border-color:#25c491;box-shadow:0 5px 0 #1c9d74;}
button.big:hover{color:#0d2b1f;background:#57f0bf;border-color:#25c491;}

.row{display:flex;flex-wrap:wrap;justify-content:flex-start;} .grp{margin:7px 0;}
.lbl{font-family:var(--font-main);font-size:13px;font-weight:600;color:var(--teal);margin-bottom:3px;letter-spacing:.5px;}
.modnote{color:var(--muted);font-size:13px;margin-top:2px;}
.mult{font-family:var(--font-main);color:var(--gold);font-size:16px;font-weight:600;margin-top:4px;}
.hiline{font-family:var(--font-main);font-size:16px;font-weight:600;color:var(--gold);margin:4px 0 2px;}
/* main menu */
.menu-wrap{width:100%;max-width:1240px;margin:0 auto;text-align:left;}
/* settings screen: Theme+Font stacked in one column next to Controls (the tallest single
   section, 6 rows) in the other, instead of all three stacked in one long column — halves
   the total height so it fits without scrolling even with the wider .menu-wrap this needs. */
.settings-grid{display:flex;gap:12px;align-items:stretch;flex-wrap:wrap;}
.settings-col{flex:1;min-width:280px;display:flex;flex-direction:column;gap:10px;}
/* the specialty-ward row has ~13 buttons — a dedicated smaller size here (rather than
   shrinking every button in the game to match) keeps the run-config card compact. */
#specRow button{font-size:13px;padding:6px 10px;margin:2px;}
.panel{background:var(--panel-bg);border:2px solid var(--panel-border);border-radius:12px;padding:9px 14px;position:relative;}
.panel-t{font-family:var(--font-main);font-size:15px;font-weight:700;color:var(--mint);margin-bottom:6px;padding-bottom:4px;border-bottom:1px solid var(--panel-border);display:flex;justify-content:space-between;align-items:center;}

/* ---- custom main menu (Assets/Sprites/Menu UI/CUSTOM MAIN MENU.png) ----
   Hand-drawn art, not theme-driven — one fixed look for every theme, unlike the rest of the
   UI. The sheet is a 600x800 canvas exported as 7 stacked 600x800 layers (see
   CUSTOM MENU.json); rendered at native 1:1 size (no scale multiplier) since this card's
   own text content (the stats bar) needs to stay a normal, comfortably-readable CSS px size
   rather than shrinking with the art the way the pharmacy popup's does — if it's ever too
   tall for a short viewport, the existing .overlay{overflow-y:auto} already handles that,
   same as every other overlay screen.
   Button art + labels are baked into the image itself, so the interactive elements are
   plain invisible hit-areas positioned over the pre-drawn shapes (same idea as the pharmacy
   popup's .ph-tab/.ph-pill sitting over its own background art) rather than CSS-drawn
   buttons. Layers are stacked as multiple background-images on one element — CSS paints the
   *first* listed image on top, so order here is reverse of the JSON's bottom-up layer list;
   the empty "Title background" layer is omitted entirely, it has nothing in it. */
#mmBox{
  position:relative;width:600px;height:800px;margin:0 auto;image-rendering:pixelated;
  background-repeat:no-repeat;background-size:600px 5600px;
  background-image:
    url('../Assets/Sprites/Menu UI/CUSTOM MAIN MENU.png'),
    url('../Assets/Sprites/Menu UI/CUSTOM MAIN MENU.png'),
    url('../Assets/Sprites/Menu UI/CUSTOM MAIN MENU.png'),
    url('../Assets/Sprites/Menu UI/CUSTOM MAIN MENU.png'),
    url('../Assets/Sprites/Menu UI/CUSTOM MAIN MENU.png'),
    url('../Assets/Sprites/Menu UI/CUSTOM MAIN MENU.png');
  background-position:
    0 -4800px, /* Player Stats Bar */
    0 -4000px, /* Button Labels */
    0 -3200px, /* Buttons */
    0 -2400px, /* Title */
    0 -1600px, /* Title Shadow */
    0 0;       /* Base */
}
/* invisible hit-areas over the pre-drawn button art — exact rects measured by isolating the
   Buttons layer and finding each button's connected color region directly in the source
   PNG (not eyeballed). */
.mm-hit{position:absolute;background:transparent;border:none;border-radius:0;box-shadow:none;padding:0;margin:0;cursor:pointer;outline:none;}
.mm-hit:hover{filter:brightness(1.06);}
.mm-hit:active{filter:brightness(.92);box-shadow:none;}
#mmNewRunBtn{left:173px;top:295px;width:253px;height:92px;}
#mmStoreBtn{left:173px;top:401px;width:253px;height:92px;}
#mmLeaderboardBtn{left:173px;top:507px;width:253px;height:92px;}
#settingsBtn.mm-hit{left:173px;top:614px;width:108px;height:78px;}
#mmAboutBtn{left:318px;top:614px;width:108px;height:78px;}
/* player-stats bar (the empty grey placeholder rect in the art) — real content, normal CSS
   text size, not scaled with the art. */
#mmStatsBar{position:absolute;left:53px;top:111px;width:491px;height:63px;box-sizing:border-box;
  display:flex;align-items:center;justify-content:space-between;padding:0 18px;
  font-family:var(--font-main);}
#mmStatsBar .mm-name{font-size:17px;font-weight:700;color:#3a3428;}
#mmStatsBar .mm-figs{display:flex;gap:16px;align-items:center;font-size:15px;color:#3a3428;}
#mmStatsBar .mm-figs .num{font-size:15px;}
#accountBtn.mm-mini{position:static;font-size:13px;padding:5px 10px;margin:0;background:#fff;color:#3a3428;border:2px solid #b8ac94;border-radius:7px;box-shadow:none;}

/* ---- run config screen (New Run → specialty/mode/mods → Play) ----
   Assets/Sprites/Menu UI/NEW RUN CUSTOM MENU.png — updated version, a 2400x20800 sheet:
   every button (12 specialties, 3 modes, practice toggle, 3 modifiers, BACK, Play) is its
   own fully pre-rendered layer with icon+label baked in, each exported at 2 frames
   (0=unselected, 1=selected). Referencing that giant sheet directly via background-position
   per element (as done for the main menu's much smaller 600x5600 sheet) silently failed to
   paint for most of the ~20 simultaneous buttons here — almost certainly a browser texture/
   surface size limit hit by a 2400x20800 source used at that many background-position
   offsets at once. Fixed by physically cropping every frame this screen needs into its own
   small file (`NR <Name>.png` / `NR <Name> Selected.png`, plus the 4 static full-card
   layers and the 7 multiplier value strips) — same "slice the sheet into real files"
   pattern already used for the sticker card and the checklist pieces, just applied here
   too once the single-giant-sheet approach proved unreliable.
   Static, non-toggling art (Base, Headings, the "MULTI:" box, and the Practice-mode
   label+track+off-knob) is layered on #rcBox itself. Everything else is a separate
   absolutely-positioned element carrying its own frame via --img0/--img1 (per-element
   inline style, see index.html) so it can swap independently on .sel. */
/* left:-12px compensates for the card art itself sitting off-centre in its own 600x800
   canvas — measured directly (Base.getbbox()): the main menu's card spans x 23-578 (centre
   300.5, i.e. already centred), but this card spans x 35-590 (centre 312.5), 12px right of
   centre. Both boxes are centred identically by the .overlay flex/margin:auto, so without
   this the card shape itself reads as shifted right compared to the main menu even though
   the two boxes' outer bounds line up exactly. Every child button's `left` is already
   relative to this box, so nudging the box shifts the art and every button together. */
#rcBox{position:relative;left:-12px;width:600px;height:800px;margin:0 auto;image-rendering:pixelated;
  background-repeat:no-repeat;background-size:600px 800px;
  background-image:
    url('../Assets/Sprites/Menu UI/NR Multi Box.png'),
    url('../Assets/Sprites/Menu UI/NR Practice Static.png'),
    url('../Assets/Sprites/Menu UI/NR Headings.png'),
    url('../Assets/Sprites/Menu UI/NR Base.png');
}
/* shared mechanics for every pre-rendered button: position/size come from an inline style
   per element (each button's rect is unique), --img0/--img1 (also inline, url()s) hold its
   two cropped frames. .sel needs to explicitly reset background-image (not just rely on
   .rc-art's) to actually win against the generic `button.sel{background:rgba(...)}` rule —
   that shorthand rule is (element+class) specificity, same as a single class alone, so
   without this .rc-art.sel's compound (class+class) specificity is what lets it win.
   Buttons with no selected state (BACK, Play, E.D./Fluids) simply never get .sel toggled;
   Normal is permanently `sel` in the markup since it's the only functional mode. */
.rc-art{position:absolute;background-repeat:no-repeat;background-size:100% 100%;
  image-rendering:pixelated;border:none;border-radius:0;box-shadow:none;padding:0;margin:0;cursor:pointer;
  background-color:transparent;background-image:var(--img0);}
.rc-art:hover{filter:brightness(1.08);}
.rc-art:active{filter:brightness(.9);box-shadow:none;}
.rc-art.sel{background-image:var(--img1);}
.rc-art.locked{opacity:.4;cursor:not-allowed;filter:none;}
/* practice-mode knob overlay: transparent at rest (the static background's off/red knob
   shows through), swaps in the on/green knob graphic when toggled — kept as its own small
   overlay (not the whole label+track) because the source art's frame 1 for this layer only
   ever contained the knob itself, not the "PRACTICE MODE:" text next to it. */
#practiceBtn{position:absolute;left:354px;top:468px;width:38px;height:20px;border:none;
  border-radius:0;box-shadow:none;padding:0;margin:0;cursor:pointer;background:transparent;}
#practiceBtn.sel{background-image:url('../Assets/Sprites/Menu UI/NR Practice Knob On.png');
  background-repeat:no-repeat;background-size:100% 100%;image-rendering:pixelated;}
/* multiplier readout: 7 pre-rendered value strings (×1.0–×4.0 in 0.5 steps), one file each
   (NR Mult 1.0.png … NR Mult 4.0.png); js swaps which one #rcMultVal points at via --img
   (see recalcMult() in setup.js) to sit inside the static "MULTI:" box on #rcBox. Scaled
   2x — the native 24x10 art is otherwise too small to read next to everything else here.
   Centered within the box's real bounds (measured directly off NR Multi Box.png: the box
   itself — not counting the "MULTI:" label above it — spans x:203-253 y:660-699, i.e.
   50x40) — the box is taller than the 20px-tall scaled digit graphic, and the previous
   left/top here was eyeballed off an earlier, wrong bbox and ran past the box's right
   edge, which is what was actually being seen as "off-centre". */
#rcMultVal{position:absolute;left:204px;top:670px;width:48px;height:20px;
  background-image:var(--img);background-repeat:no-repeat;background-size:100% 100%;
  image-rendering:pixelated;}
/* #rcModeRow/#modRow are plain (non-positioned) wrappers — every button inside is
   position:absolute so it lands on #rcBox (the nearest positioned ancestor), but that
   means each wrapper's own .modnote child needs its own explicit position too, or it
   renders at the wrapper's collapsed top-left instead of below the button row. */
#rcModeRow .modnote{position:absolute;left:40px;top:494px;width:520px;color:#8a8172;font-size:12px;}
#modRow .modnote{position:absolute;left:40px;top:592px;width:520px;color:#8a8172;font-size:12px;}

/* prescribing card — plain CSS panel (reuses .panel/.panel-t, same look as the settings/
   game-over overlays), sized by its own content instead of scaled to fit a fixed
   native-pixel art frame. That fixed-frame approach (two earlier passes: a single sprite,
   then a 3-slot clipboard sprite) kept forcing fields to shrink to fit a native px budget
   that didn't grow with the content; a normal flex layout has no such ceiling. #pharm
   itself stays permanently mounted; opening/closing is a vertical slide (see .ph-open)
   driven purely by inPharm/emPatient (js/popup.js refreshPopup()) — a second interact
   press at the pharmacy closes it again, same as opening it. */
/* width is a % of #pharm's own containing block (.game-wrap, which hugs the canvas exactly)
   rather than vw (the whole viewport) — vw would size against the page width regardless of
   how much of it the side panels eat, letting the popup end up wider than the canvas itself
   and spill over them. 620px (was 460) per the "make it bigger" ask.
   line-height:normal is the actual fix for text visibly overlapping inside this popup
   (every field label / lock note collapsed to a ~0px-tall box, with only glyphs still
   painting past it) — .game-wrap sets line-height:0 on itself (a real, deliberate fix
   elsewhere: it kills the few px of baseline gap under the inline-block <canvas>), and
   since line-height inherits, every descendant text node in here inherited that 0 unless
   it happened to set its own (#phDx did; .ph-field-label/.ph-lock2/etc. didn't). Resetting
   it once here for the whole popup subtree is more robust than patching every class that
   holds text one at a time — nothing added later in here can reintroduce the bug by
   forgetting to set its own line-height. */
#pharm{position:absolute;left:50%;bottom:10px;top:auto;width:min(94%,620px);line-height:normal;
  transform:translate(-50%,130%);transition:transform .4s cubic-bezier(.2,.8,.2,1);
  pointer-events:none;z-index:6;display:flex;flex-direction:column;align-items:center;gap:8px;}
#pharm.ph-open{transform:translate(-50%,0);pointer-events:auto;}
#pharm.ph-emergency{transition-duration:.3s;}
#phPanel{width:100%;max-height:min(76vh,620px);overflow-y:auto;box-shadow:0 10px 24px rgba(6,30,22,.45);}
#pharm.ph-emergency #phPanel{border-color:#c94a52;}
#phPanel .panel-t{font-size:19px;}
/* everything below is plain block/flex flow with wrapping, not fixed-size or absolutely
   positioned — the field list (js/pharmacy-ui.js renderFields()) always appends the same
   fixed sequence of elements (diagnosis, then one block per field) regardless of which
   difficulty mods are on, just swapping a field's own inner content between a button row
   and a lock note; two stacked block-level elements can never overlap each other no matter
   how tall either one renders. min-width:0 on every flex item + overflow-wrap:break-word on
   every text-bearing element is the actual overlap guard against font metrics specifically —
   flex items default to min-width:auto, which refuses to shrink below its text's natural
   width and is what lets a long unbroken word blow out a flex row in a wider/bolder font;
   these two rules together force any such text to wrap inside its own box instead. */
#phTabs{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:12px;}
.ph-tab2{flex:1 1 0;min-width:64px;display:flex;flex-direction:column;align-items:center;gap:2px;
  background:var(--row-bg);border:2px solid var(--row-border);border-radius:8px;padding:6px 4px;cursor:pointer;
  font-family:var(--font-main);color:var(--muted);}
.ph-tab2 .t-room{font-size:14px;font-weight:700;letter-spacing:.4px;max-width:100%;overflow-wrap:break-word;}
.ph-tab2.done .t-room::after{content:' \2713';color:var(--mint);}
.ph-tab2 .t-time{font-family:'VT323',monospace;font-size:18px;}
.ph-tab2.sel{border-color:var(--teal);color:var(--ink);background:var(--panel-bg-soft);}
#phDx{font-family:var(--font-main);font-size:19px;font-weight:700;color:var(--ink);text-align:center;
  line-height:1.3;margin-bottom:12px;overflow-wrap:break-word;}
.ph-field{margin-bottom:11px;min-width:0;}
.ph-field:last-child{margin-bottom:0;}
.ph-field-label{font-family:var(--font-main);font-size:13px;font-weight:700;color:var(--muted);
  text-transform:uppercase;letter-spacing:.6px;margin-bottom:5px;}
.ph-choices{display:flex;flex-wrap:wrap;gap:6px;}
/* multi-choice buttons for every field (drug included) — no dropdowns anywhere in this
   popup. Sized in normal CSS px (not the tiny native-pixel scale the sprite versions
   needed), so long drug names wrap onto a second line instead of needing to be crushed
   into a fixed-width pill. max-width stops any single pill from claiming the whole row
   width in an unusually wide font, which would otherwise push every option after it onto
   its own line and make the field look broken rather than just wrapped. */
.ph-choice{font-family:var(--font-main);font-weight:700;font-size:15px;color:var(--btn-text);
  background:var(--btn-bg);border:2px solid var(--btn-border);border-radius:8px;cursor:pointer;
  padding:8px 13px;margin:0;box-shadow:none;transition:.08s;max-width:100%;overflow-wrap:break-word;
  text-align:center;line-height:1.25;}
.ph-choice:hover{border-color:var(--teal);}
.ph-choice.sel{background:var(--mint);border-color:var(--mint);color:#06251c;}
.ph-lock2{font-family:var(--font-main);font-size:13px;color:var(--muted);font-style:italic;overflow-wrap:break-word;}
.ph-empty2{font-family:var(--font-main);font-size:17px;color:var(--muted);text-align:center;padding:8px 4px;line-height:1.4;}
.ph-hint{pointer-events:none;color:#e8fbff;font-family:var(--font-main);font-size:16px;text-align:center;
  text-shadow:0 2px 4px rgba(0,0,0,.6);max-width:100%;overflow-wrap:break-word;}

.toast{position:absolute;top:48px;left:50%;transform:translateX(-50%) scale(.94);font-family:var(--font-main);font-size:21px;font-weight:600;padding:14px 24px;border:3px solid #cfe0e6;border-radius:14px;background:#ffffff;color:#12414e;box-shadow:0 8px 22px rgba(8,36,46,.32);z-index:7;opacity:0;transition:.2s;max-width:90%;}
.toast.show{opacity:1;transform:translateX(-50%) scale(1);}
.foot{color:var(--muted);font-size:14px;margin-top:6px;text-align:center;max-width:940px;} .foot b{color:var(--teal);}
.final{font-family:'VT323',monospace;font-size:30px;color:var(--gold);margin:10px 0;letter-spacing:1px;}
.newbest{font-family:var(--font-main);font-size:18px;font-weight:700;color:var(--mint);margin:6px 0;animation:blink .6s steps(1) infinite;} @keyframes blink{50%{opacity:.4}}
#review{width:100%;max-width:660px;margin:12px auto;}
.rev-t{font-family:var(--font-main);font-size:15px;font-weight:600;color:var(--teal);margin-bottom:10px;}
.rev-sub{font-family:var(--font-main);font-size:13px;font-weight:700;color:var(--red);margin:14px 0 6px;text-transform:uppercase;letter-spacing:.5px;text-align:left;}
.rev-sub.ok{color:var(--mint);}
.rev-row{display:flex;justify-content:space-between;gap:10px;text-align:left;background:var(--row-bg);border:2px solid var(--row-border);border-left:4px solid var(--red);border-radius:8px;padding:9px 13px;margin-bottom:7px;}
.rev-row.ok{border-left-color:var(--mint);}
.rev-row .dx{color:var(--ink);flex:1;} .rev-row .ans{color:var(--mint);text-align:right;white-space:nowrap;} .rev-row .why{color:var(--muted);font-size:15px;}
.rev-perfect{color:var(--mint);font-family:var(--font-main);font-size:16px;font-weight:600;margin:12px 0;}

/* settings — controls remap */
.ctrl-grid{display:flex;flex-direction:column;gap:4px;}
.ctrl-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:5px 2px;}
.ctrl-lab{font-family:var(--font-main);font-size:16px;color:var(--ink);}
.ctrl-key{font-family:'VT323',monospace;font-size:19px;min-width:96px;padding:7px 10px;margin:0;}
.ctrl-key.listening{border-color:var(--gold);color:var(--gold);animation:blink .6s steps(1) infinite;}

/* handbook — pixel book */
#handbook{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;z-index:8;background:rgba(6,14,10,.6);}
.hb-book{position:relative;display:flex;width:640px;max-width:92%;min-height:340px;background:#7a5230;border:6px solid #4a3018;border-radius:10px;box-shadow:0 18px 40px rgba(0,0,0,.5);padding:14px;}
.hb-spine{position:absolute;left:50%;top:14px;bottom:14px;width:8px;transform:translateX(-50%);background:#4a3018;box-shadow:0 0 0 2px #3a2412 inset;}
.hb-page{flex:1;background:#f6ecd2;border:2px solid #d8c69c;padding:18px 20px;display:flex;flex-direction:column;position:relative;}
.hb-left{border-radius:6px 0 0 6px;margin-right:2px;}
.hb-right{border-radius:0 6px 6px 0;margin-left:2px;justify-content:space-between;}
.hb-pagenum{font-family:'VT323',monospace;font-size:14px;color:#a4906a;text-align:center;}
.hb-label{font-family:'Press Start 2P',monospace;font-size:10px;color:#8a6a3a;letter-spacing:1px;margin:10px 0 8px;}
.hb-dx{font-family:var(--font-main);font-size:22px;font-weight:700;color:#4a3018;white-space:pre-line;line-height:1.3;flex:1;}
.hb-tag{font-family:var(--font-main);font-size:13px;color:#a15a1e;text-transform:uppercase;letter-spacing:.5px;}
.hb-answer{font-family:var(--font-main);font-size:20px;font-weight:700;color:#1f6b45;white-space:pre-line;line-height:1.35;flex:1;}
.hb-nav{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:10px;}
.hb-nav button{font-family:var(--font-main);font-size:14px;padding:7px 12px;margin:0;background:#f0e2bc;color:#4a3018;border:2px solid #c9ad72;border-radius:8px;box-shadow:0 3px 0 #a98a4c;}
.hb-nav button:hover{transform:translateY(-1px);border-color:#8a6a2a;color:#7a3a12;}
.hb-nav button:disabled{opacity:.4;cursor:not-allowed;transform:none;}
#hbCount{font-family:'VT323',monospace;font-size:18px;color:#7a5a2a;}
.hb-close{position:absolute;top:-14px;right:-14px;width:32px;height:32px;border-radius:50%;background:#e5484d;color:#fff;border:3px solid #fff;font-family:var(--font-main);font-size:16px;cursor:pointer;box-shadow:0 4px 10px rgba(0,0,0,.4);padding:0;margin:0;}
.hb-close:hover{background:#ff6169;transform:none;}
