/* ── Shared shell styles for standalone screen pages (head.php + menu.php) ─────────────────────────
   The full-bleed background + safe-area handling here fixes the iPhone "margins" bug for every screen.
   Page-specific look lives in each page's own <style> block, so editing one screen can't affect another. */
*{margin:0;padding:0;box-sizing:border-box}
html,body{width:100%;min-height:100%;color:#e6eef8;
  font-family:'Segoe UI',system-ui,sans-serif;-webkit-text-size-adjust:100%}
/* Opaque base fill on the ROOT only — body must stay TRANSPARENT so the fixed z-index:-1 background
   layers (.page-bg gradient, and a page's own #lib-bg) paint ABOVE it instead of being covered (a
   non-positioned body paints over negative-z children). */
html{-webkit-touch-callout:none;background:#060a10}
body.shell{-webkit-user-select:none;user-select:none;overscroll-behavior:none}
input,textarea,select,[contenteditable]{-webkit-user-select:text;user-select:text}

/* Full-bleed background that reaches under the notch / safe-area on iPhone (no bare margins). */
.page-bg{position:fixed;inset:0;z-index:-1;background:radial-gradient(120% 120% at 50% 0%,#0b1524 0%,#060a10 60%)}

/* ── Global Menu — one nav bar on every screen ── */
.gm{position:sticky;top:0;z-index:50;background:rgba(6,10,16,.72);backdrop-filter:blur(8px);
  border-bottom:1px solid rgba(255,255,255,.08);
  padding-top:env(safe-area-inset-top,0)}
.gm-bar{display:flex;align-items:center;gap:10px;
  padding:10px clamp(12px,3vw,28px);
  padding-left:calc(clamp(12px,3vw,28px) + env(safe-area-inset-left,0));
  padding-right:calc(clamp(12px,3vw,28px) + env(safe-area-inset-right,0))}
.gm-left{display:flex;align-items:center;gap:8px}
.gm-right{display:flex;align-items:center;gap:8px;margin-left:auto}
/* Top-bar buttons reuse the pixel .btn design (defined below), just smaller with tighter pixel steps. */
.gm .btn{--s:3px;--s2:6px;min-height:36px;padding:7px 11px;gap:6px;white-space:nowrap;
  font-size:clamp(.5rem,1.15vw,.62rem);letter-spacing:.3px}
.gm .btn-ico{width:16px;height:16px;top:0}          /* smaller icons for the compact top bar */
.gm-fs-ico{font-size:calc(1em + 5px);line-height:1;display:inline-flex;align-items:center;justify-content:center;height:1em;position:relative;top:-3px}
/* Hamburger: bump specificity (beats .gm .btn) so the glyph isn't shrunk by the small top-bar font. */
.gm .gm-burger{margin-left:auto;width:44px;padding:0;justify-content:center}
.gm-burger-ico{display:flex;align-items:center;justify-content:center;width:100%;height:100%;
  font-size:1.3rem;line-height:1;position:relative;top:-2px}
.gm-bar .gm-burger{display:none}

/* Pixel-shaped SELECTION ring — the SAME clip-path inflated by --rg on every side, so the highlight hugs
   the button's real pixel edge instead of drawing a rectangle. For shadowless pixel buttons (the top bar):
   hidden at rest, shown on hover/focus; the ring pseudo sits behind the fill so only the --rg band peeks. */
.btn.ring::before{content:"";position:absolute;inset:calc(-1 * var(--rg,3px));z-index:-2;
  clip-path:var(--clip);background:var(--ring,#ffffff);opacity:0;transition:opacity .08s}
.btn.ring:hover::before,.btn.ring:focus::before{opacity:1}
.btn.ring:focus-visible{outline:none}
.btn.primary.ring{--ring:#eafff7}

/* 🔔 Notifications bell + dropdown (signed-in users). */
.gm-bell-wrap{position:relative;display:inline-flex}
.gm-bell-ico{font-size:1rem;line-height:1;display:inline-flex;align-items:center;justify-content:center}
.gm-bell.has-unread .gm-bell-ico{animation:gm-bell-wiggle 1.4s ease-in-out}
@keyframes gm-bell-wiggle{0%,100%{transform:rotate(0)}20%{transform:rotate(-12deg)}40%{transform:rotate(10deg)}60%{transform:rotate(-6deg)}80%{transform:rotate(4deg)}}
.gm-bell-badge{position:absolute;top:-5px;right:-5px;min-width:16px;height:16px;padding:0 4px;
  background:#ff5470;color:#fff;font:400 .5rem/16px 'Press Start 2P','Segoe UI',monospace;text-align:center;
  box-shadow:0 0 0 2px #0c1420;clip-path:polygon(0 3px,3px 3px,3px 0,calc(100% - 3px) 0,calc(100% - 3px) 3px,100% 3px,100% calc(100% - 3px),calc(100% - 3px) calc(100% - 3px),calc(100% - 3px) 100%,3px 100%,3px calc(100% - 3px),0 calc(100% - 3px))}
.gm-bell-badge[hidden]{display:none}
.gm-notif{position:absolute;top:calc(100% + 8px);right:0;width:min(340px,86vw);z-index:200;
  background:#0e1723;border:2px solid #2b3d57;box-shadow:0 16px 40px rgba(0,0,0,.55);text-align:left}
.gm-notif[hidden]{display:none}
.gm-notif-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:10px 12px;
  border-bottom:1px solid #1b2636;font:400 .56rem/1.4 'Press Start 2P','Segoe UI',monospace;color:#cfe0ff}
.gm-notif-readall{background:none;border:0;color:#7fd0ff;cursor:pointer;font-size:.72rem;padding:2px 4px}
.gm-notif-readall:hover{color:#aee6ff}
.gm-notif-list{max-height:min(60vh,420px);overflow:auto}
.gm-notif-empty{color:#8fa2b8;font-size:.82rem;padding:16px 12px;margin:0;text-align:center}
.gm-notif-item{display:block;width:100%;text-align:left;background:none;border:0;border-bottom:1px solid #16202e;
  cursor:pointer;padding:11px 12px;color:#dfe9f5}
.gm-notif-item:hover{background:#132234}
/* Unread notifications get a green border + accent so they're spotted instantly. */
.gm-notif-item.unread{background:#101f22;border-left:4px solid #00e5ab;box-shadow:inset 0 0 0 1px rgba(0,229,171,.35)}
.gm-notif-item.unread .gm-notif-title::before{content:"● ";color:#00e5ab}
.gm-notif-title{display:block;font-size:.86rem;font-weight:600;color:#eaf2fb;margin-bottom:3px;line-height:1.4}
.gm-notif-body{display:block;font-size:.82rem;color:#b3c2d4;line-height:1.5}
.gm-notif-time{display:block;font-size:.72rem;color:#6f8299;margin-top:4px}

/* ── Cookie-consent banner + legal (Terms / Cookies) modal ── */
.cookie-bar{position:fixed;left:0;right:0;bottom:0;z-index:150;display:flex;align-items:center;gap:14px;
  flex-wrap:wrap;justify-content:center;padding:12px 16px;background:#0c1826;border-top:2px solid #22344b;
  box-shadow:0 -8px 30px rgba(0,0,0,.45)}
.cookie-bar[hidden]{display:none}
.cookie-msg{margin:0;color:#c7d3e4;font-size:.86rem;line-height:1.5;max-width:760px}
.cookie-link{background:none;border:0;color:#00e5ab;cursor:pointer;font-size:.86rem;text-decoration:underline;
  text-underline-offset:2px;padding:0 2px}
.cookie-link:hover{color:#6ff2cf}
.cookie-ok{--s:3px;--s2:6px;background:#00d18f;color:#03150f;border:0;cursor:pointer;clip-path:var(--clip);
  font:400 .56rem/1 'Press Start 2P','Segoe UI',monospace;letter-spacing:.3px;padding:11px 16px;flex:0 0 auto}
.cookie-ok:hover{filter:brightness(1.12)}
.legal-modal{position:fixed;inset:0;z-index:210;display:flex;align-items:center;justify-content:center;
  padding:20px;background:rgba(4,8,14,.74)}
.legal-modal[hidden]{display:none}
.legal-box{background:#0e1723;border:2px solid #2b3d57;width:min(720px,96vw);max-height:88vh;display:flex;
  flex-direction:column;box-shadow:0 20px 60px rgba(0,0,0,.6)}
.legal-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px 18px;border-bottom:1px solid #1b2636}
.legal-head h2{margin:0;font-family:'Press Start 2P','Segoe UI',monospace;font-size:.82rem;color:#eaf2fb;line-height:1.4}
.legal-close{background:none;border:0;color:#9fb0c4;cursor:pointer;font-size:1.1rem;padding:4px 8px;line-height:1}
.legal-close:hover{color:#fff}
.legal-body{padding:18px 20px;overflow:auto;color:#c7d3e4;line-height:1.65;font-size:.95rem}
.legal-body h2{font-size:1.2rem;color:#eaf2fb;margin:0 0 12px}
.legal-body h3{font-size:1rem;color:#eaf2fb;margin:18px 0 6px}
.legal-body p{margin:0 0 12px}
.legal-body a{color:#00e5ab}
.legal-body ul,.legal-body ol{margin:0 0 12px;padding-left:22px}
.legal-loading{color:#8fa2b8}
@media (max-width:560px){ .cookie-msg{font-size:.82rem} }

/* Persistent legal footer (Terms · Privacy · Cookies) — the buttons reuse the shared legal modal.
   FIXED (out of flow) so it never adds page height / forces a scrollbar; the screens stay sized to the
   viewport. Pointer events pass THROUGH the strip (only the links are clickable) and a soft top-fade keeps
   the links legible over any content behind them. */
.site-foot{position:fixed;left:0;right:0;bottom:0;z-index:40;pointer-events:none;
  display:flex;align-items:center;justify-content:center;gap:8px;flex-wrap:wrap;
  padding:6px 12px calc(16px + env(safe-area-inset-bottom,0));
  background:linear-gradient(to top,rgba(6,10,16,.9),rgba(6,10,16,0));
  color:#6f8098;font-size:.78rem}
.foot-link{pointer-events:auto;background:none;border:0;color:#8ba0b8;cursor:pointer;font-size:.78rem;
  text-decoration:underline;text-underline-offset:2px;padding:0 2px}
.foot-link:hover{color:#00e5ab}
.foot-sep{color:#3d4d63}

/* Shell pages only: the shared floating mute button (from audio.js) gets .btn.ring via shell.js. These
   id-level rules beat audio.js's injected pill styles (rounded/teal-outline) without touching that file,
   so the in-game button stays exactly as-is. */
body #mute-btn{--s:3px;--s2:6px;gap:6px;position:fixed;right:12px;bottom:12px;z-index:101;
  min-height:34px;height:auto;padding:7px 12px;border:0;border-radius:0;background:transparent;color:#dfe9f5;
  font:400 .5rem/1 'Press Start 2P','Segoe UI',monospace;letter-spacing:.3px}
body #mute-btn:hover{background:transparent}
body #mute-btn:focus-visible{outline:none}
body #mute-btn .mi{font-size:.95rem;line-height:1}

/* Narrow screens: collapse the right-side items behind a hamburger sheet. */
@media (max-width:640px){
  .gm-bar .gm-burger{display:inline-flex}
  .gm-right{position:absolute;top:100%;right:8px;left:8px;margin:0;flex-direction:column;align-items:stretch;
    gap:6px;padding:10px;border-radius:12px;background:#0e1723;border:1px solid rgba(255,255,255,.14);
    box-shadow:0 16px 40px rgba(0,0,0,.5);display:none}
  .gm-right.open{display:flex}
  .gm-right .btn{justify-content:flex-start;min-height:44px;width:100%}
}

/* Page content area: stays hidden until the global #app-loading gate lifts (body.ready). */
.shell-main{min-height:calc(100dvh - 61px);display:flex;flex-direction:column;
  padding:clamp(16px,4vw,48px);
  padding-left:calc(clamp(16px,4vw,48px) + env(safe-area-inset-left,0));
  padding-right:calc(clamp(16px,4vw,48px) + env(safe-area-inset-right,0));
  padding-bottom:calc(clamp(16px,4vw,48px) + env(safe-area-inset-bottom,0));
  opacity:0;transition:opacity .3s ease;visibility:hidden}
body.shell.ready .shell-main{opacity:1;visibility:visible}
@media (prefers-reduced-motion:reduce){.shell-main{transition:none}}

/* Wallpaper blurs under cards must not peek around the loading gate. */
body.shell:not(.ready) #lib-bg,
body.shell:not(.ready) #gp-bg{opacity:0 !important;visibility:hidden}

/* Pixel-staircase corner shape shared by buttons AND inputs. --s/--s2 = step sizes; nested vars resolve
   on whatever element applies clip-path:var(--clip), so each control can pick its own step size. */
html{--s:5px;--s2:10px;
  --clip:polygon(
    var(--s2) 0, calc(100% - var(--s2)) 0,
    calc(100% - var(--s2)) var(--s), calc(100% - var(--s)) var(--s), calc(100% - var(--s)) var(--s2), 100% var(--s2),
    100% calc(100% - var(--s2)), calc(100% - var(--s)) calc(100% - var(--s2)), calc(100% - var(--s)) calc(100% - var(--s)), calc(100% - var(--s2)) calc(100% - var(--s)), calc(100% - var(--s2)) 100%,
    var(--s2) 100%, var(--s2) calc(100% - var(--s)), var(--s) calc(100% - var(--s)), var(--s) calc(100% - var(--s2)), 0 calc(100% - var(--s2)),
    0 var(--s2), var(--s) var(--s2), var(--s) var(--s), var(--s2) var(--s)
  )}

/* Shared RETRO button used inside page content — flat pixel-art (no 3D): flat fill, hard pixel-stepped
   corners (clip-path staircase, scales to any width/text). --s = pixel step size.
   The FILL is painted by ::after (not the element background) so an optional ::before shadow can sit
   genuinely BEHIND it — clip-path makes .btn its own stacking context, so a plain z-index:-1 child would
   otherwise paint ABOVE the element's own background. Layer order inside .btn (isolation:isolate):
   shadow ::before (z-2) → fill ::after (z-1) → text/icon (in flow, on top). */
.btn{--bg:#16202e;--tint:transparent;
  position:relative;isolation:isolate;
  display:inline-flex;align-items:center;justify-content:center;gap:10px;cursor:pointer;text-decoration:none;
  font:400 clamp(.62rem,1.5vw,.82rem)/1 'Press Start 2P','Segoe UI',monospace;letter-spacing:.5px;
  padding:18px 26px;min-height:54px;border:0;border-radius:0;
  background:transparent;color:#dfe9f5;image-rendering:pixelated}
/* fill */
.btn::after{content:"";position:absolute;inset:0;z-index:-1;clip-path:var(--clip);
  background-color:var(--bg);background-image:linear-gradient(var(--tint),var(--tint));transition:background-image .1s}
/* Decorative layers (fill + shadow/ring) must never intercept clicks on neighbouring controls. */
.btn::before,.btn::after{pointer-events:none}
/* Hover/active tint the fill via an overlay var (NOT filter — filter would create a stacking context). */
.btn:hover{--tint:rgba(255,255,255,.12)}
.btn:active{--tint:rgba(0,0,0,.16)}
.btn:focus-visible{outline:3px solid #7ef7d4;outline-offset:4px}
.btn.primary{--bg:#00d18f;color:#03150f}

/* ── Button STYLES (mix with any .btn / .btn.primary) — pick per background ──
   1. Simple    →  .btn            (flat, no shadow)
   2. Dark bg   →  .btn.on-dark    (hard WHITE pixel shadow on hover/focus — for dark screens)
   3. Light bg  →  .btn.on-light   (hard BLACK pixel shadow on hover/focus — for light screens)
   4. Color     →  .btn.on-color   (retro colour-palette pixel shadow — icons/color-background.png)
   The shadow is the SELECTION cue: hidden at rest, shown on :hover / :focus (keyboard or mouse). Its
   footprint is reserved with margin so toggling it never shifts layout. Same-shape ::before at z-index:-2
   sits truly behind the fill. --sh = offset (down+right). --shx = trim the shadow's LEFT start inward so
   less white shows on the bottom-left; the right edge is unchanged. */
.btn.on-dark,
.btn.on-light,
.btn.on-color{--sh:6px;--shx:5px;margin:0 var(--sh) var(--sh) 0}
.btn.on-dark::before,
.btn.on-light::before,
.btn.on-color::before{content:"";position:absolute;inset:0 0 0 var(--shx);z-index:-2;
  clip-path:var(--clip);transform:translate(var(--sh),var(--sh));image-rendering:pixelated;
  opacity:0;transition:opacity .08s}
.btn.on-dark:hover::before,.btn.on-dark:focus::before,
.btn.on-light:hover::before,.btn.on-light:focus::before,
.btn.on-color:hover::before,.btn.on-color:focus::before{opacity:1}
.btn.on-dark::before{background:rgba(255,255,255,.9)}
.btn.on-light::before{background:rgba(0,0,0,.5)}
/* clip-path masks the palette image to the pixel shape (cover so the full retro strip fills the shape). */
.btn.on-color::before{background:url(../icons/color-background.png) center/cover no-repeat}
.btn.on-dark:active,
.btn.on-light:active,
.btn.on-color:active{--sh:3px}
/* The pixel shadow is the focus indicator for these buttons — drop the extra outline to keep it clean. */
.btn.on-dark:focus-visible,
.btn.on-light:focus-visible,
.btn.on-color:focus-visible{outline:none}
/* Pixel-art button icon (custom 25x25 webp/png). Flex centering + a hair of optical lift keeps it
   dead-centered on the Press Start 2P cap height. */
.btn-ico{flex:0 0 auto;width:18px;height:18px;display:block;image-rendering:pixelated;
  -webkit-user-select:none;user-select:none;pointer-events:none;position:relative;top:-1px}

/* Pixel-bordered text field: the WRAPPER paints the border colour, the inner <input> paints the fill, and
   BOTH share --clip. Because the border is a separate clipped layer (not a box-shadow/border on the input),
   it follows the pixel-stepped corners instead of staying rectangular. Wrap: <div class="pix-field"><input></div> */
.pix-field{--s:3px;--s2:6px;--pf:#2b3d57;clip-path:var(--clip);background:var(--pf);padding:2px;
  image-rendering:pixelated;transition:background .12s}
.pix-field:focus-within{--pf:#00e5ab}
.pix-field > input,.pix-field > select,.pix-field > textarea{display:block;width:100%;box-sizing:border-box;clip-path:var(--clip);
  background:#0b1220;color:#eaf2fb;border:0;outline:none;image-rendering:pixelated;font:inherit}
.pix-field > textarea{resize:vertical;min-height:64px;line-height:1.5}
.pix-field > input::placeholder,.pix-field > textarea::placeholder{color:#556780}
/* Pixel <select>: kill the native chrome and draw our own tiny caret (native arrow can clip at the steps). */
.pix-field > select{appearance:none;-webkit-appearance:none;cursor:pointer;padding-right:30px;
  background-image:linear-gradient(45deg,transparent 50%,#8fa6c4 50%),linear-gradient(135deg,#8fa6c4 50%,transparent 50%);
  background-position:calc(100% - 16px) 55%,calc(100% - 11px) 55%;background-size:5px 5px,5px 5px;background-repeat:no-repeat,no-repeat}
/* Autofill only needs to keep the FILL dark now (the border is the wrapper, untouched by autofill). */
.pix-field > input:-webkit-autofill{-webkit-text-fill-color:#eaf2fb;caret-color:#eaf2fb;
  -webkit-box-shadow:inset 0 0 0 100px #0b1220;box-shadow:inset 0 0 0 100px #0b1220;transition:background-color 9999s}
