/* Tonytopia — original dark teal + gold theme. No external assets. */
:root{
  --teal-950:#042024; --teal-900:#062a2e; --teal-800:#0a3a3f; --teal-700:#0f4c52;
  --teal-500:#17808a; --teal-300:#5ec2c9; --gold:#f2b63d; --gold-2:#ffd97a;
  --ink:#eaf6f5; --muted:#9fc0bd; --card:#0b3237; --line:#1c5a60;
  --danger:#e5534b; --ok:#62c370; --radius:14px;
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
}
*{box-sizing:border-box; -webkit-tap-highlight-color:transparent;}
html,body{height:100%;}
html{overflow:hidden; overscroll-behavior:none;}
body{
  margin:0; color:var(--ink); background:var(--teal-950);
  font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  overflow:hidden; overscroll-behavior:none;
  /* App-shell scroll lock: the page itself can never scroll (e.g. when the
     soft keyboard opens and the browser tries to pan to the chat input);
     only inner regions (.screen, .inv-grid, modals) may scroll. */
  position:fixed; inset:0; width:100%;
}
button,input,select{font:inherit;}
.hidden{display:none !important;}

/* ---------- screens ---------- */
.screen{display:none; height:100dvh; overflow-y:auto; padding:16px 12px calc(16px + var(--safe-b));}
.screen.active{display:block;}
.screen.game-screen.active{display:block; padding:0; overflow:hidden;}

/* ---------- home ---------- */
.home-screen{
  background:
    linear-gradient(160deg, rgba(4,32,36,.55) 0%, rgba(4,32,36,.88) 62%, #042024 100%),
    url("assets/keyart.png") center/cover no-repeat,
    radial-gradient(120% 90% at 50% 0%, #14606a 0%, #0a3a3f 48%, #042024 100%);
}
.home-hero{max-width:520px; margin:6vh auto 0; text-align:center; padding:20px 14px;}
.home-icon{width:84px; height:84px; border-radius:20px; border:2px solid var(--gold); object-fit:cover; background:var(--teal-800);}
.logo-text{
  margin:.25em 0 .1em; font-size:clamp(44px,13vw,76px); line-height:1; letter-spacing:.5px;
  color:var(--gold); text-shadow:0 3px 0 #8a5d10, 0 10px 28px rgba(0,0,0,.55);
  font-weight:900;
}
.tagline{color:var(--ink); opacity:.92; margin:6px 0 14px;}
.signed-in{color:var(--gold-2); font-weight:600; min-height:1.2em;}
.balances{color:var(--ink); font-weight:600;}
.balances.compact{font-size:.82rem; text-align:right;}
.conn-status{color:var(--muted); font-size:.85rem; min-height:1.1em;}
.home-buttons{display:grid; gap:10px; margin-top:16px;}
button.btn.big{padding:14px; font-size:1.08rem;}

/* ---------- generic UI ---------- */
.card{
  max-width:520px; margin:4vh auto; background:var(--card); border:1px solid var(--line);
  border-radius:var(--radius); padding:20px 16px; box-shadow:0 14px 40px rgba(0,0,0,.4);
}
.card.wide{max-width:640px;}
.card h2,.modal h2{margin-top:0; color:var(--gold);}
.card h3{color:var(--teal-300); margin-bottom:6px;}
label{display:block; margin:10px 0; color:var(--muted); font-size:.9rem; text-align:left;}
input,select{
  display:block; width:100%; margin-top:4px; padding:11px 12px; border-radius:10px;
  border:1px solid var(--line); background:var(--teal-950); color:var(--ink); outline:none;
}
input:focus,select:focus{border-color:var(--gold);}
.btn{
  border:1px solid var(--line); background:var(--teal-800); color:var(--ink);
  border-radius:10px; padding:10px 14px; cursor:pointer; font-weight:600;
}
.btn:active{transform:translateY(1px);}
.btn.primary{background:var(--teal-500); border-color:var(--teal-300); color:#fff;}
.btn.gold{background:linear-gradient(180deg,var(--gold-2),var(--gold)); border-color:#8a5d10; color:#3a2703;}
.btn.danger{background:#5c2320; border-color:var(--danger);}
.btn.ghost{background:transparent;}
.btn.full{width:100%; margin-top:10px;}
.btn.small{padding:6px 10px; font-size:.82rem; border-radius:8px;}
.btn.icon{width:34px; height:34px; padding:0; font-size:1.1rem;}
.row{display:flex; gap:8px; flex-wrap:wrap; margin-top:10px;}
.row .btn{flex:1;}
.hint{color:var(--muted); font-size:.82rem;}
.question-text{color:var(--gold-2); min-height:1.2em; font-weight:600;}
.check-row{display:flex; gap:8px; align-items:center; color:var(--ink);}
.check-row input{width:auto; margin:0;}
hr{border:none; border-top:1px solid var(--line); margin:18px 0;}
.list{display:grid; gap:6px; margin:8px 0 14px;}
.list-row{
  display:flex; justify-content:space-between; align-items:center; gap:8px;
  background:var(--teal-900); border:1px solid var(--line); border-radius:10px; padding:9px 12px;
  text-align:left; width:100%; color:var(--ink);
}
button.list-row{cursor:pointer;}
.list-row .sub{color:var(--muted); font-size:.82rem;}
.empty-note{color:var(--muted); font-size:.88rem; padding:6px 2px;}

/* ---------- toasts ---------- */
.toast-wrap{position:fixed; top:calc(var(--safe-t) + 8px); left:50%; transform:translateX(-50%); z-index:200; width:min(94vw,480px); display:grid; gap:6px; pointer-events:none;}
.toast{
  background:rgba(6,42,46,.96); border:1px solid var(--gold); color:var(--ink);
  padding:10px 14px; border-radius:10px; text-align:center; font-size:.92rem;
  box-shadow:0 8px 24px rgba(0,0,0,.45); animation:toast-in .18s ease-out;
}
.toast.error{border-color:var(--danger);}
.toast.ok{border-color:var(--ok);}
.toast.muted-flash{opacity:.55;}
@keyframes toast-in{from{opacity:0; transform:translateY(-6px);} to{opacity:1; transform:none;}}

/* ---------- modals ---------- */
.modal-backdrop{
  position:fixed; inset:0; z-index:120; background:rgba(2,16,18,.72);
  display:flex; align-items:flex-start; justify-content:center; padding:14px 10px; overflow-y:auto;
}
.modal{
  width:min(94vw,480px); background:var(--card); border:1px solid var(--line);
  border-radius:var(--radius); padding:16px; margin:auto 0;
}
.modal.large{width:min(96vw,760px);}
.modal-head{display:flex; justify-content:space-between; align-items:center; gap:8px;}
.modal-head h2{margin:0;}
.news-list{list-style:none; margin:10px 0 14px; padding:0; display:flex; flex-direction:column; gap:8px; max-height:46dvh; overflow-y:auto;}
.news-list li{background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.07); border-radius:10px; padding:8px 10px; font-size:14px; line-height:1.45; color:#e8f4f4;}

/* ---------- game ---------- */
.game-screen{position:relative;}
/* The old translucent top bar is gone (Anthony): the menu button
   floats alone at the top-right, and Gems / Tony Lock balances live
   in the Catalog Store only. */
#menuBtn{
  position:absolute; top:calc(var(--safe-t) + 8px); right:8px; z-index:46;
  width:44px; height:44px; border-radius:50%; padding:0;
  display:flex; align-items:center; justify-content:center;
}
.gh-world{display:grid; line-height:1.05; min-width:74px;}
.gh-world .small{font-size:.62rem; color:var(--muted); text-transform:uppercase; letter-spacing:.08em;}
.gh-world strong{color:var(--gold); font-size:1rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:clamp(64px, 17vw, 170px);}
.game-header .balances{flex:1;}
.chat-feed{
  position:absolute; top:calc(var(--safe-t) + 52px); left:0; right:0; z-index:4; pointer-events:none;
  padding:4px 10px; min-height:0;
  display:flex; flex-direction:column; justify-content:flex-end; overflow:hidden;
}
/* ---------- chat overlay (top-anchored, translucent) + FAB ---------- */
.chat-overlay{touch-action:auto; overscroll-behavior:contain;
  position:absolute; left:0; right:0; bottom:0; top:auto; z-index:60;
  /* b31: smaller panel — chatting must leave the game as the big,
     visible part of the screen (the old min(60dvh, 540px) sheet
     swallowed most of a phone). Short landscape screens get a
     taller share below so the feed stays usable there. */
  height:min(44dvh, 440px);
  /* No backdrop-filter: blurring the live game canvas behind the
     chat was a major source of mobile lag. A flatter, more opaque
     panel reads just as well and costs nothing per frame. */
  background:rgba(6,24,28,.95);
  border-top:2px solid var(--gold);
  display:flex; flex-direction:column;
}
@media (max-height: 480px) {
  .chat-overlay{height:min(62dvh, 440px);}
}
.chat-overlay .chat-bar{
  display:flex; gap:8px; width:100%; padding:8px 10px calc(8px + var(--safe-b));
  background:rgba(0,0,0,.28); border-top:1px solid rgba(255,255,255,.13);
}
/* font-size 16px on the chat input: below 16px, mobile browsers
   auto-zoom the whole view when the field takes focus (the
   keyboard-open zoom jump) wherever the viewport meta is ignored. */
.chat-overlay .chat-bar input{flex:1; margin:0; font-size:16px;}
.chat-overlay .chat-bar .btn{white-space:nowrap;}
.chat-overlay .chat-feed{
  position:static; flex:1 1 auto; min-height:0; max-height:none;
  overflow-y:auto; pointer-events:auto; display:block;
  padding:8px 10px; justify-content:flex-start;
}
/* While chatting, the other top overlays step aside entirely. */
body.chat-open .command-strip,
body.chat-open .cmd-strip-btn,
body.chat-open .menu-panel{display:none !important;}
.chat-fab{
  position:absolute; right:10px; top:50%; transform:translateY(-50%); z-index:44;
  width:52px; height:52px; border-radius:50%; cursor:pointer;
  background:rgba(10,58,63,.88); border:1px solid var(--gold); color:#fff; font-size:1.35rem;
  display:flex; align-items:center; justify-content:center; box-shadow:0 8px 20px rgba(0,0,0,.4);
}
.chat-fab:active{transform:translateY(-50%) scale(.95);}
.chat-badge{
  position:absolute; top:-4px; right:-4px; min-width:20px; height:20px; padding:0 5px;
  border-radius:999px; background:var(--danger); color:#fff; font-size:.68rem; font-weight:800;
  display:flex; align-items:center; justify-content:center; border:1px solid rgba(255,255,255,.35);
}
/* ---------- private command log (condensed into one button) ---------- */
/* The old in-flow strip ate a band of play area under the header. Now
   the whole log lives behind a small 📜 button floating at the canvas
   top-left; tapping it opens the entries as an overlay panel that
   floats over the game (zero layout cost) and closes itself when idle.
   The button pulses when a new entry lands while the panel is shut. */
.cmd-strip-btn{
  position:absolute; top:calc(var(--safe-t) + 54px); left:8px; z-index:40;
  width:38px; height:38px; border-radius:50%; cursor:pointer;
  background:rgba(10,58,63,.82); border:1px solid var(--gold); color:#fff;
  font-size:1.05rem; display:flex; align-items:center; justify-content:center;
  box-shadow:0 6px 16px rgba(0,0,0,.35);
}
.cmd-strip-btn:active{transform:scale(.94);}
.cmd-strip-btn.pulse{animation:cmdPulse 1.1s ease-in-out 2;}
@keyframes cmdPulse{0%,100%{box-shadow:0 0 0 0 rgba(242,182,61,0);}50%{box-shadow:0 0 0 7px rgba(242,182,61,.45);}}
.command-strip{
  position:absolute; top:calc(var(--safe-t) + 98px); left:8px; z-index:40;
  width:min(78vw, 400px); max-height:38dvh; overflow-y:auto;
  padding:8px 10px; border-radius:10px;
  background:rgba(6,24,28,.82); -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
  border:1px solid rgba(28,90,96,.7);
  box-shadow:0 10px 24px rgba(0,0,0,.4);
}
.cmd-line{font-size:.78rem; line-height:1.32; color:var(--teal-300); white-space:pre-wrap; word-break:break-word; text-shadow:0 1px 2px #000;}
.cmd-line.own{color:var(--muted); font-style:italic;}
/* ---------- quiet in-canvas notice (break/place feedback, not a pop-up) ---------- */
.game-notice{
  position:absolute; top:calc(var(--safe-t) + 54px); left:50%; transform:translateX(-50%); z-index:4;
  max-width:86%; padding:6px 14px; border-radius:999px; pointer-events:none;
  background:rgba(6,42,46,.85); border:1px solid var(--line); color:var(--ink);
  font-size:.85rem; font-weight:600; text-align:center; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis; opacity:0; transition:opacity .25s ease;
}
.game-notice.show{opacity:1;}
/* ---------- active buff indicator (b38): live timed buffs ---------- */
.buff-hud{
  position:absolute; top:calc(var(--safe-t) + 92px); left:50%; transform:translateX(-50%); z-index:4;
  max-width:86%; padding:4px 12px; border-radius:999px; pointer-events:none;
  background:rgba(46,32,6,.85); border:1px solid var(--gold); color:var(--ink);
  font-size:.78rem; font-weight:600; text-align:center; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis;
}
/* ---------- metal detector indicator (b40) ---------- */
.detector-hud{
  position:absolute; top:calc(var(--safe-t) + 124px); left:50%; transform:translateX(-50%); z-index:4;
  max-width:86%; padding:4px 12px; border-radius:999px; pointer-events:none;
  background:rgba(24,32,52,.88); border:1px solid #7dd3fc; color:var(--ink);
  font-size:.78rem; font-weight:700; text-align:center; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis;
}
/* ---------- race HUD (b41) ---------- */
.race-hud{
  position:absolute; top:calc(var(--safe-t) + 156px); left:50%; transform:translateX(-50%); z-index:4;
  max-width:86%; padding:4px 12px; border-radius:999px; pointer-events:none;
  background:rgba(10,40,22,.88); border:1px solid #22c55e; color:var(--ink);
  font-size:.78rem; font-weight:700; text-align:center; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis;
}
/* ---------- music note strip + art studio easel (b42) ---------- */
.note-strip{
  position:absolute; bottom:calc(var(--safe-b) + 118px); left:50%; transform:translateX(-50%); z-index:5;
  display:flex; align-items:center; gap:5px; padding:6px 10px; border-radius:999px;
  background:rgba(24,20,48,.9); border:1px solid #818cf8;
}
.note-strip-label{font-size:.78rem; font-weight:700; color:var(--ink); white-space:nowrap;}
.note-btn{
  width:34px; height:34px; border-radius:50%; border:1px solid #c7d2fe; cursor:pointer;
  background:#312e81; color:#eef2ff; font-weight:800; font-size:.85rem;
}
.note-btn:active{background:#6366f1;}
.easel-canvas{
  display:block; width:256px; height:256px; max-width:100%; margin:8px auto;
  border:3px solid #92400e; border-radius:6px; image-rendering:pixelated;
  background:#f5eeda; touch-action:none; cursor:crosshair;
}
.easel-palette{display:flex; flex-wrap:wrap; gap:5px; justify-content:center; margin:6px 0;}
.easel-swatch{
  width:26px; height:26px; border-radius:6px; border:2px solid rgba(255,255,255,.35); cursor:pointer; padding:0;
}
.easel-swatch.sel{border-color:#fff; box-shadow:0 0 0 2px #f43f5e;}
.easel-tools{display:flex; gap:6px; justify-content:center; margin:6px 0;}
.easel-tools .btn.sel{outline:2px solid #f43f5e;}
/* ---------- cooking / brewing station recipes (b38) ---------- */
.station-recipe{border:1px solid var(--line); border-radius:10px; padding:10px; margin:8px 0;}
.station-recipe-name{font-weight:700; margin-bottom:2px;}
.station-recipe-ings{font-size:.8rem; color:var(--muted); margin-bottom:8px;}
/* ---------- auto-reconnect pill: persistent while retrying, tappable
   to retry immediately; sits top-centre below the toast zone. Unlike
   .game-notice it never fades on a timer — JS hides it once the
   session is restored (or the player is sent back to log in). */
.reconnect-pill{
  position:fixed; top:calc(52px + env(safe-area-inset-top, 0px)); left:50%; transform:translateX(-50%); z-index:205;
  padding:7px 16px; border-radius:999px; cursor:pointer;
  background:rgba(6,42,46,.92); border:1px solid var(--gold); color:var(--ink);
  font-size:.85rem; font-weight:700; text-align:center; white-space:nowrap;
  box-shadow:0 2px 10px rgba(0,0,0,.45);
  animation:reconnectPulse 1.6s ease-in-out infinite;
}
@keyframes reconnectPulse{0%,100%{opacity:1;}50%{opacity:.55;}}
.chat-line{font-size:.84rem; line-height:1.35; text-shadow:0 1px 2px #000; word-break:break-word; white-space:pre-wrap;}
.chat-line .who{font-weight:700; color:var(--teal-300);}
.chat-line .who.dev{color:#ff3333;}
.chat-line.system{color:var(--gold-2); font-style:italic;}
.chat-line.loot{color:#9fe8b1; font-style:normal;}
.event-banner{background:linear-gradient(135deg, rgba(242,182,61,.20), rgba(64,199,191,.14)); border:1px solid rgba(242,182,61,.45); border-radius:10px; padding:8px 10px; margin-bottom:8px; font-size:13px; color:#ffe9a3;}
.chat-line.announce{color:var(--gold); font-weight:700;}
.chat-line.age-0{opacity:.45;} .chat-line.age-1{opacity:.6;} .chat-line.age-2{opacity:.75;}
.chat-line.age-3{opacity:.88;} .chat-line.age-4{opacity:1;} .chat-line.age-5{opacity:1;}
.canvas-wrap{position:absolute; inset:0; background:#071e26;}
#gameCanvas{position:absolute; inset:0; width:100%; height:100%; display:block; touch-action:none;}
.touch-controls{
  position:absolute; left:0; right:0; bottom:calc(10px + var(--safe-b));
  display:flex; justify-content:space-between; align-items:flex-end; padding:0 clamp(10px, 4.5vw, 40px); z-index:3; pointer-events:none;
}
.tc-group{display:flex; gap:8px;}
.touch-btn{
  pointer-events:auto; width:clamp(54px, 15vmin, 76px); height:clamp(54px, 15vmin, 76px); border-radius:50%;
  border:1px solid var(--teal-300); background:rgba(10,58,63,.72); color:#fff;
  font-size:1.45rem; touch-action:none; user-select:none; -webkit-user-select:none;
}
.touch-btn.held,.touch-btn:active{background:var(--teal-500);}
.touch-btn.punch{border-color:var(--gold);}
/* Directional punch pad (b44, Fang): a bigger punch button with
   four yellow direction triangles at its edges. The triangles are
   decoration (pointer-events:none) — the button itself receives
   every press and punchZoneAt() in game.js works out which zone
   was pressed: centre = the plain punch, edges = aim that way. */
.punch-pad{position:relative; width:clamp(76px, 19vmin, 104px); height:clamp(76px, 19vmin, 104px); pointer-events:none; flex:none;}
.punch-pad #punchBtn{width:100%; height:100%; pointer-events:auto; font-size:1.8rem;}
.punch-tri{position:absolute; width:0; height:0; pointer-events:none; opacity:.95; filter:drop-shadow(0 1px 1px rgba(0,0,0,.55)); z-index:1;}
.punch-tri.tri-up{top:4px; left:50%; transform:translateX(-50%); border-left:9px solid transparent; border-right:9px solid transparent; border-bottom:13px solid #ffd21f;}
.punch-tri.tri-down{bottom:4px; left:50%; transform:translateX(-50%); border-left:9px solid transparent; border-right:9px solid transparent; border-top:13px solid #ffd21f;}
.punch-tri.tri-left{left:4px; top:50%; transform:translateY(-50%); border-top:9px solid transparent; border-bottom:9px solid transparent; border-right:13px solid #ffd21f;}
.punch-tri.tri-right{right:4px; top:50%; transform:translateY(-50%); border-top:9px solid transparent; border-bottom:9px solid transparent; border-left:13px solid #ffd21f;}
/* Mobile touch layout (b23, Anthony): on touch-primary devices the
   on-screen controls sit closer to the middle of the screen (wider
   side inset, so thumbs reach them without stretching to the edges)
   and the buttons grow ~15-17% for bigger tap targets. Desktop
   (fine pointer) keeps the layout above, unchanged. The keyboard-open
   behaviour is unaffected: body.kb-open still hides the controls
   while typing (see the kb-open section below). */
@media (pointer: coarse){
  .touch-controls{padding:0 clamp(30px, 9vw, 76px);}
  .tc-group{gap:10px;}
  .touch-btn{
    width:clamp(62px, 17.5vmin, 88px); height:clamp(62px, 17.5vmin, 88px);
    font-size:1.7rem;
  }
  .punch-pad{width:clamp(88px, 22vmin, 118px); height:clamp(88px, 22vmin, 118px);}
}
/* ---------- unified bottom tray (compact card + pull tab) ---------- */
/* A small floating card that HUGS its slots: width fits the content
   (the 4 spots — Punch / Build / block slots — at their normal size),
   centred at the bottom, never stretched edge-to-edge; on narrow
   phones it caps at 92vw and the slots scroll inside. The pull tab
   rides on top of the box; dragging it down slides the whole tray
   off-screen until only the tab peeks at the bottom edge. */
.hotbar-tray{
  position:absolute; left:50%; bottom:calc(10px + var(--safe-b)); z-index:25;
  transform:translate(-50%, 0); transition:transform .25s ease;
  display:flex; align-items:center; gap:6px;
  width:fit-content; max-width:92vw;
  padding:6px 8px;
  background:#0a3236;
  border:1px solid var(--line); border-radius:14px;
  box-shadow:0 10px 26px rgba(0,0,0,.4);
}
.hotbar-tray.tray-hidden{transform:translate(-50%, calc(100% + 10px + var(--safe-b)));}
.tray-tab{
  position:absolute; top:-31px; left:50%; transform:translateX(-50%); z-index:26;
  width:84px; height:30px; padding:0; cursor:grab; touch-action:none;
  background:rgba(10,58,63,.85); color:var(--gold-2); font-weight:700; font-size:.82rem; line-height:23px;
  border:1px solid var(--gold); border-bottom:none; border-radius:12px 12px 0 0;
  pointer-events:auto; user-select:none; -webkit-user-select:none;
}
.tray-tab:active{cursor:grabbing;}
.layer-chip{
  flex:0 0 auto; padding:5px 9px; border-radius:999px; cursor:pointer;
  background:rgba(10,58,63,.8); border:1px solid var(--teal-300); color:var(--ink);
  font-size:.72rem; font-weight:800; letter-spacing:.04em;
}
.layer-chip.bg-on{background:rgba(88,60,180,.75); border-color:#c4b5fd; color:#fff;}
.hotbar{display:flex; gap:6px; overflow-x:auto; padding-bottom:4px; min-height:56px; justify-content:safe center; flex:1 1 auto; min-width:0;}
.hotbar-empty{color:var(--muted); font-size:.86rem; align-self:center;}
.slot{
  flex:0 0 auto; width:52px; border:1px solid var(--line); border-radius:10px; padding:3px 2px 2px;
  background:var(--teal-950); color:var(--ink); cursor:pointer; display:grid; justify-items:center; gap:1px;
}
.slot canvas{width:30px; height:30px;}
.slot .s-emoji{font-size:1.35rem; line-height:1.15;}
.slot.mode-slot{border-style:dashed;}
.backpack-count{color:var(--gold-2); font-weight:700; font-size:.74rem; white-space:nowrap;}
.store-card{border:1px solid var(--line); border-radius:12px; padding:12px; background:var(--teal-950);}
.store-card h3{margin:0 0 6px; color:var(--gold);}
.store-cost{font-size:1rem; margin:8px 0;}
.slot .s-name{font-size:.56rem; line-height:1.05; text-align:center; max-width:56px; overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;}
.slot .s-count{font-size:.66rem; color:var(--gold-2); font-weight:700;}
.slot.selected{border-color:var(--gold); box-shadow:0 0 0 1px var(--gold);}
.slot.equipped{outline:2px solid var(--teal-500);}
.hotbar-actions{display:flex; gap:6px; flex-wrap:wrap; margin-bottom:8px;}
.hotbar-actions .btn{flex:1;}

.slot.pin-empty{border-style:dashed; opacity:.85;}
.slot.pin-empty .s-emoji{font-size:1.1rem;}

/* ---------- inventory bottom sheet ---------- */
/* Opened from the tray tab (long-press + drag up). Closed = slid fully
   down and not hit-testable; game.js drives the transform during tab
   drags. Chat focus always closes the sheet, so the soft keyboard can
   never trap input behind it. */
.inv-panel{
  position:absolute; left:0; right:0; bottom:0; z-index:30;
  /* Solid panel (Anthony: the translucent sheet let the world bleed
     through and never looked like one seamless UI). */
  background:#062a2e;
  border-top:2px solid var(--gold);
  border-radius:16px 16px 0 0; padding:10px 12px calc(10px + var(--safe-b));
  /* Closed = slid fully down out of sight and not hit-testable; game.js
     drives the transform during tray-tab drags. */
  transform:translateY(100%);
  pointer-events:none;
  transition:transform .25s ease;
  max-height:58dvh; display:flex; flex-direction:column;
  box-shadow:0 -12px 32px rgba(0,0,0,.5);
}
.inv-panel.open{
  transform:none; pointer-events:auto;
}
/* Hotbar pulled up INTO the inventory (Anthony): while the sheet is
   open the tray rides on top of it at the sheet's bottom edge — one
   unit — and the sheet pads its bottom so the last grid row scrolls
   clear of the tray instead of hiding behind it. */
body.inv-open .hotbar-tray{z-index:31;}
body.inv-open .inv-panel{padding-bottom:calc(92px + var(--safe-b));}
body.inv-open .inv-grid{padding-bottom:104px; scrollbar-gutter:stable;}
/* While the backpack is open the floating shop button steps aside
   (b34, Fang): on mobile it sat over the sheet's close (×) button. */
body.inv-open .shop-btn{display:none;}
.inv-panel-head{display:flex; align-items:center; gap:6px; margin-bottom:4px;}
.inv-panel-head strong{font-size:.92rem; white-space:nowrap;}
.inv-panel-head .hint{font-size:.7rem; line-height:1.15;}
.inv-panel-head #invCloseBtn{flex:0 0 auto; margin-left:auto; position:relative; z-index:50;}
.inv-currency{display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin:2px 0 6px;}
.inv-cur-chip{background:rgba(255,255,255,.08); border:1px solid rgba(255,255,255,.16); border-radius:999px; padding:2px 8px; font-weight:700; font-size:12px;}
.inv-cur-chip.gold{color:var(--gold); border-color:rgba(242,182,61,.5);}
.inv-cur-note{font-size:10.5px; opacity:.75; flex:1 1 220px;}
.inv-search{width:100%; box-sizing:border-box; margin:0 0 6px; padding:6px 10px; border-radius:10px; border:1px solid rgba(255,255,255,.22); background:rgba(0,0,0,.35); color:#fff; font-size:13px;}
.inv-search::placeholder{color:rgba(255,255,255,.55);}
.inv-panel-head strong{color:var(--gold);}
.inv-panel-head .hint{flex:1;}
.inv-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(68px,1fr)); gap:5px; overflow-y:auto;}
.inv-cell{
  border:1px solid var(--line); border-radius:10px; padding:6px 4px 5px;
  background:var(--teal-950); color:var(--ink); cursor:pointer;
  display:grid; justify-items:center; gap:1px; touch-action:manipulation;
}
.inv-cell canvas{width:34px; height:34px;}
.inv-cell .i-name{font-size:.6rem; font-weight:700; line-height:1.05; text-align:center;}
.inv-cell .i-count{font-size:.62rem; color:var(--gold-2); font-weight:700;}
.inv-cell .i-value{font-size:.56rem; color:var(--muted);}
.inv-cell.selected{border-color:var(--gold); box-shadow:0 0 0 1px var(--gold);}
.inv-cell.equipped{outline:2px solid var(--teal-500);}
.inv-cell.unowned{opacity:.52; filter:saturate(.55);}
.inv-cell.unowned.afford{opacity:1; filter:none; border-color:rgba(242,182,61,.45);}
.inv-section-head{grid-column:1 / -1; font-size:.78rem; font-weight:700; color:var(--gold-2); padding:8px 2px 0;}
.item-actions{
  position:absolute; right:10px; top:50%; transform:translateY(-50%); z-index:31;
  width:196px; background:var(--card); border:1px solid var(--gold);
  border-radius:var(--radius); padding:12px; display:grid; gap:8px;
  box-shadow:0 14px 40px rgba(0,0,0,.5);
  /* Same no-scroll trap as the ☰ menu (b25): with every action button
     visible the panel is ~542px tall, so on short viewports (landscape
     phones) the centred panel clipped off BOTH ends with no way to
     scroll. Cap it to the viewport and scroll inside. */
  max-height:calc(100dvh - 16px);
  overflow-y:auto; -webkit-overflow-scrolling:touch; overscroll-behavior:contain;
  scrollbar-width:thin;
}
.item-actions .ia-name{font-weight:800; color:var(--gold); font-size:1rem; line-height:1.15;}
.item-actions .ia-sub{color:var(--muted); font-size:.78rem;}
.item-actions .btn.full{margin-top:0;}

/* ---------- terms of service ---------- */
.tos-box{
  max-height:170px; overflow-y:auto; white-space:pre-wrap; text-align:left;
  background:var(--teal-950); border:1px solid var(--line); border-radius:10px;
  padding:10px 12px; font-size:.78rem; line-height:1.45; color:var(--ink); margin:8px 0;
}
.tos-box.tall{max-height:55vh;}

/* ---------- hamburger menu ---------- */
.menu-btn{
  margin-left:auto; width:42px; height:38px; flex:0 0 auto; cursor:pointer;
  background:var(--teal-800); color:var(--gold-2); border:1px solid var(--gold);
  border-radius:9px; font-size:1.25rem; line-height:1;
}
.menu-panel{
  position:absolute; top:calc(var(--safe-t) + 52px); right:8px; z-index:47; width:208px;
  background:var(--card); border:1px solid var(--gold); border-radius:var(--radius);
  padding:6px; display:grid; gap:2px; box-shadow:0 14px 40px rgba(0,0,0,.55);
  /* Scrollable (b25, Anthony): with 13 entries the panel is ~578px tall,
     so on shorter phone viewports its bottom (Settings, Log Out) fell
     off-screen with no way to reach it — the game screen clips overflow
     and the panel itself never scrolled. Cap it to the visible viewport
     below its top offset (52px + 12px breathing room) and scroll inside. */
  max-height:calc(100dvh - var(--safe-t) - 64px);
  overflow-y:auto; -webkit-overflow-scrolling:touch; overscroll-behavior:contain;
  scrollbar-width:thin;
}
.menu-item{
  background:transparent; border:none; color:var(--ink); text-align:left;
  padding:10px 12px; border-radius:8px; cursor:pointer; font-size:.95rem; font-weight:600;
}
.menu-item:hover,.menu-item:active{background:var(--teal-800);}
.menu-item.danger{color:#ff9d8a;}

/* ---------- shop (b24: real-money packs) ---------- */
/* Gold shop button on the HUD, right under the ☰ menu button in the
   top-right corner — one tap from gameplay straight into the shop. */
.shop-btn{
  position:absolute; top:calc(var(--safe-t) + 60px); right:8px; z-index:46;
  width:48px; height:48px; border-radius:50%; cursor:pointer;
  background:linear-gradient(180deg,var(--gold-2),var(--gold));
  border:1px solid #ffe9a8; color:#3a2703; font-size:1.35rem; line-height:1;
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 8px 20px rgba(0,0,0,.45);
}
.shop-btn:active{transform:scale(.94);}
.shop-pack{
  display:flex; align-items:center; gap:10px; margin:8px 0;
  border:1px solid var(--line); border-radius:12px; padding:10px 12px;
  background:var(--teal-950);
}
.shop-pack-info{flex:1; min-width:0;}
.shop-pack-name{font-weight:700; color:var(--ink);}
.shop-pack-blurb{font-size:.82rem; color:var(--muted); margin-top:2px;}
.shop-pack-buy{display:grid; gap:2px; justify-items:end;}
.shop-pack-price{font-weight:800; color:var(--gold-2); white-space:nowrap;}
.design-status{
  display:inline-block; padding:1px 8px; border-radius:999px; font-size:.72rem;
  font-weight:700; border:1px solid var(--line); color:var(--muted);
}
.design-status.pending{color:var(--gold-2); border-color:var(--gold);}
.design-status.created{color:#9fe8b1; border-color:#9fe8b1;}

/* ---------- catalog ---------- */
.catalog-tabs{display:flex; flex-wrap:wrap; gap:6px; margin-bottom:10px;}
.catalog-tab{
  background:var(--teal-800); color:var(--ink); border:1px solid var(--line);
  border-radius:999px; padding:6px 11px; font-size:.8rem; cursor:pointer;
}
.catalog-tab.active{background:var(--gold); border-color:var(--gold); color:#23180a; font-weight:700;}
.catalog-filters{
  display:grid; grid-template-columns:1fr; gap:8px; margin-bottom:8px;
  background:linear-gradient(135deg, rgba(232,184,75,.14), rgba(23,128,138,.16) 55%, rgba(0,0,0,.12));
  border:1px solid rgba(232,184,75,.45); border-radius:14px; padding:10px;
  box-shadow:0 4px 14px rgba(0,0,0,.25), inset 0 1px 0 rgba(255,255,255,.08);
}
@media(min-width:560px){.catalog-filters{grid-template-columns:2fr 1fr 1fr;}}
.filter-field{display:grid; gap:4px;}
.filter-label{font-size:.68rem; font-weight:800; letter-spacing:.06em; text-transform:uppercase; color:var(--gold-2);}
.catalog-filters input,.catalog-filters select{
  width:100%; box-sizing:border-box; appearance:none; -webkit-appearance:none;
  background:rgba(6,26,32,.85) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23e8b84b' stroke-width='2' fill='none' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat right 10px center;
  border:1px solid var(--line); border-radius:10px; color:var(--ink);
  padding:9px 26px 9px 10px; font-size:.88rem; font-weight:600;
}
.catalog-filters input{background-image:none; padding-right:10px;}
.catalog-filters input:focus,.catalog-filters select:focus{
  outline:none; border-color:var(--gold); box-shadow:0 0 0 3px rgba(232,184,75,.25);
}
.catalog-results{display:flex; align-items:center; justify-content:space-between; gap:8px; margin:2px 2px 8px; color:var(--muted); font-size:.8rem; font-weight:600;}
.catalog-footer{display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:10px;}
.catalog-shown{color:var(--muted); font-size:.8rem; font-weight:600;}
.store-note{margin:0 0 10px;}
.catalog-backpack{margin-bottom:12px;}
.catalog-grid{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(104px,1fr)); gap:8px;
  max-height:52dvh; overflow-y:auto; overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch; scrollbar-width:thin; padding:2px;
}
.cat-item{content-visibility:auto; contain-intrinsic-size:auto 158px;}
.cat-item.rarity-legendary{border-color:rgba(249,115,22,.55);}
.cat-item.rarity-mythic{border-color:rgba(244,63,94,.6); box-shadow:0 0 10px rgba(244,63,94,.22);}
.cat-item.rarity-epic{border-color:rgba(168,85,247,.5);}
.cat-buy:disabled{opacity:.45; filter:grayscale(.4); cursor:not-allowed;}
.cat-item{background:var(--teal-900); border:1px solid var(--line); border-radius:10px; padding:8px 6px; text-align:center; display:grid; justify-items:center; gap:2px;}
.cat-item canvas{width:40px; height:40px;}
.cat-item .c-name{font-size:.74rem; font-weight:700; line-height:1.1;}
.cat-item .c-rarity{font-size:.68rem; font-weight:700;}
.cat-item .c-value,.cat-item .c-effect{font-size:10px; color:#ffd76a; line-height:1.25;}
.c-owned{font-size:.68rem; color:var(--muted);}
.cat-item .c-owned{color:var(--gold-2);}

/* ---------- copyright ---------- */
.copyright-note{font-size:.72rem; color:var(--muted); text-align:center; margin:14px 0 2px; opacity:.85;}

/* ---------- on-screen keyboard (body.kb-open, set by game.js) ---------- */
/* While the soft keyboard is open, hide the regions it would cover anyway.
   game.js freezes the game screen + canvas wrap at their pre-keyboard pixel
   sizes and lifts the chat bar above the keyboard, so nothing squishes,
   stretches or jumps while typing. */
body.kb-open .touch-controls{display:none;}
body.kb-open .hotbar-tray{display:none;}
body.kb-open .chat-fab{display:none;}
body.kb-open .shop-btn{display:none;}
body.kb-open .chat-bar{position:relative; z-index:32;}

/* ---------- profiles & friends ---------- */
.dev-badge{
  display:inline-block; vertical-align:2px; margin-left:6px; padding:2px 8px;
  background:linear-gradient(180deg,var(--gold-2),var(--gold)); color:#3a2703;
  border-radius:999px; font-size:.68rem; font-weight:800; letter-spacing:.03em;
}
.profile-name{font-size:1.25rem; font-weight:800; color:var(--ink);}
.profile-meta{color:var(--muted); margin:6px 0; font-size:.92rem;}
.dot{display:inline-block; width:9px; height:9px; border-radius:50%; margin-right:6px; background:#5c6f6d; vertical-align:1px;}
.dot.on{background:var(--ok);}
.dot.off{background:#5c6f6d;}
.friends-h{color:var(--teal-300); margin:14px 0 4px; font-size:.95rem;}
.friends-h:first-child{margin-top:0;}
.friend-actions{display:flex; gap:6px; flex:0 0 auto; align-items:center;}
.friend-req-banner{
  position:fixed; top:10px; left:50%; transform:translateX(-50%); z-index:210;
  width:min(94vw,480px); background:rgba(6,42,46,.97); border:1px solid var(--gold);
  border-radius:12px; padding:10px 12px; box-shadow:0 10px 28px rgba(0,0,0,.5);
  display:grid; gap:8px; animation:toast-in .18s ease-out;
}
.friend-req-banner .frb-text{font-size:.92rem; text-align:center;}
.friend-req-banner .frb-actions{margin-top:0;}
.friend-req-banner .frb-actions .btn{flex:1;}

/* ---------- trade ---------- */
.trade-columns{display:grid; gap:14px;}
@media(min-width:620px){.trade-columns{grid-template-columns:1fr 1fr;}}
.offer-list{background:var(--teal-950); border:1px solid var(--line); border-radius:10px; padding:8px 10px; min-height:56px; font-size:.88rem;}
.offer-list div{display:flex; justify-content:space-between; gap:8px;}
.trade-boxes{display:grid; grid-template-columns:1fr 1fr; gap:8px; margin-bottom:8px;}
.trade-box{
  border:1px solid var(--line); border-radius:10px; background:var(--teal-950);
  min-height:86px; padding:6px 4px; display:grid; justify-items:center; align-content:start; gap:1px;
}
.trade-box canvas{width:40px; height:40px;}
.trade-box .tb-name{font-size:.68rem; line-height:1.1; text-align:center;}
.trade-box .tb-count{font-size:.78rem; color:var(--gold-2); font-weight:700;}
.trade-box.empty{border-style:dashed; align-content:center;}
.trade-box .tb-empty{color:var(--muted); font-size:.8rem;}
.trade-box .tb-btns{display:flex; gap:4px; margin-top:3px;}
.tb-btn{
  min-width:30px; min-height:26px; padding:0 6px; border-radius:7px; cursor:pointer;
  border:1px solid var(--line); background:rgba(10,58,63,.85); color:var(--ink); font-size:.85rem; font-weight:700;
}
.trade-picker{display:flex; gap:6px; overflow-x:auto; padding:4px 0 6px;}
.trade-chip{
  flex:0 0 auto; display:grid; justify-items:center; gap:1px; max-width:86px;
  border:1px solid var(--line); border-radius:10px; padding:4px 6px; cursor:pointer;
  background:var(--teal-950); color:var(--ink); font-size:.62rem; line-height:1.1;
}
.trade-chip canvas{width:30px; height:30px;}
.trade-actions .btn{flex:1;}

/* Seed splicing modal */
.splice-partner{margin:5px 0;}
.splice-partner:disabled{opacity:.45;}

/* Wide screens (tablets / desktop): roomier backpack sheet with bigger
   cells — the full-width phone sizing looked tiny on a tablet. The
   sheet's side padding grows so the grid itself stays readable. */
@media (min-width: 700px) {
  .inv-panel{
    max-height:80dvh;
    padding-left:max(12px, calc((100vw - 900px) / 2));
    padding-right:max(12px, calc((100vw - 900px) / 2));
  }
  .inv-grid{grid-template-columns:repeat(auto-fill, minmax(108px, 1fr)); gap:10px;}
  .inv-cell canvas{width:52px; height:52px;}
  .inv-cell .i-name{font-size:.74rem;}
  .slot{width:60px;}
  .slot canvas{width:36px; height:36px;}
}

/* quests */
.quest-head { margin: 12px 0 6px; font-size: 15px; }
.quest-row { background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.10); border-radius: 10px; padding: 8px 10px; margin: 6px 0; }
.quest-row.done { opacity: .75; border-color: #57d977; }
.quest-top { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.quest-name { font-weight: 600; }
.quest-reward { color: #ffd97a; font-weight: 700; white-space: nowrap; }
.quest-row.done .quest-reward { color: #57d977; }
.qbar { height: 8px; border-radius: 4px; background: rgba(0,0,0,.35); overflow: hidden; margin: 6px 0 4px; }
.qbar-fill { height: 100%; background: linear-gradient(90deg, #57d977, #b6f09a); border-radius: 4px; transition: width .3s ease; }
.quest-prog { font-size: 12px; opacity: .8; text-align: right; }
.inv-show-more{grid-column:1 / -1; margin:10px 2px 4px; padding:11px; border-radius:10px; border:1px solid rgba(242,182,61,.45); background:rgba(242,182,61,.12); color:var(--gold-2); font-weight:700; font-size:.85rem; cursor:pointer;}
.inv-show-more:active{background:rgba(242,182,61,.25);}

/* Tony Lock settings panel */
.lock-line { margin: 6px 0; }
.lock-line.sub, .lock-row .sub { color: #9fb6ba; font-size: 12px; }
.lock-sec { margin: 14px 0 4px; font-weight: 700; color: #9fd8de; font-size: 12px; text-transform: uppercase; letter-spacing: .05em; }
.lock-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 7px 0; border-bottom: 1px solid rgba(255,255,255,.07); }
#lockBody select { background: #0a3236; color: #eaf6f5; border: 1px solid rgba(255,255,255,.25); border-radius: 8px; padding: 6px 8px; font: inherit; }

/* bug reports + signs (b17) */
.field-label { display: block; margin: 10px 0 4px; font-size: 12px; font-weight: 700; color: #9fd8de; text-transform: uppercase; letter-spacing: .05em; }
#reportModal select, #reportModal textarea, #signModal textarea {
  width: 100%; box-sizing: border-box; background: rgba(0,0,0,.35); color: #eaf6f5;
  border: 1px solid rgba(255,255,255,.18); border-radius: 10px; padding: 9px 10px; font: inherit;
}
#reportModal textarea, #signModal textarea { resize: vertical; }
#reportModal select:focus, #reportModal textarea:focus, #signModal textarea:focus { border-color: var(--gold); outline: none; }
#reportSubmitBtn { margin-top: 12px; }
.report-item { background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.10); border-radius: 10px; padding: 8px 10px; margin: 6px 0; }
.report-head { display: flex; justify-content: space-between; gap: 8px; font-weight: 600; }
.report-status { font-size: 12px; white-space: nowrap; }
.report-status.fixed { color: #57d977; }
.report-status.open { color: #ffd97a; }
.report-status.closed { color: #9fb6ba; }
.report-text { margin-top: 4px; white-space: pre-wrap; word-break: break-word; }
.report-note { margin-top: 4px; color: #9fd8de; font-size: 13px; }
.sign-read { background: rgba(250,240,214,.10); border: 1px solid rgba(250,240,214,.35); border-radius: 10px; padding: 10px 12px; font-size: 16px; margin: 6px 0; }

/* World-entry veil: covers the game until the real catalog art is
   ready, so grey fallback blocks are never the first thing seen. */
.world-veil{position:absolute; inset:0; z-index:90; display:flex; align-items:center; justify-content:center; background:radial-gradient(120% 120% at 50% 20%, #0b3d42 0%, #062a2e 55%, #041e21 100%);}
.world-veil.hidden{display:none;}
.world-veil-card{text-align:center; color:#e8f6f3;}
.world-veil-spin{font-size:52px; animation:veilspin 1.6s linear infinite;}
.world-veil-text{margin-top:10px; font-size:16px; letter-spacing:.04em; opacity:.9;}
@keyframes veilspin{from{transform:rotate(0deg);} to{transform:rotate(360deg);}}

.screen.game-screen{position:relative;}
