/* ══════════════════════════════════════════════════════════
   PAC-50 SHELL — the MENU bar and the menu overlay.
   Loaded by every app page. Additive: nothing here overrides
   base.css / screens.css, and it depends on neither.
   ══════════════════════════════════════════════════════════ */

/* ── the bar ───────────────────────────────────────────────
   A flex child prepended to #app, so it sits ABOVE the HUD and
   pushes it down instead of floating over it. Hidden until the
   group is unlocked.                                          */
#shellbar{
  flex:0 0 auto;display:none;align-items:center;justify-content:space-between;
  gap:10px;padding:8px 12px;border-bottom:2px solid #1a1a5e;
  background:linear-gradient(180deg,#0a0a1e 0%,#05050f 100%)}
#shellbar.on{display:flex;animation:shIn .45s ease-out}
@keyframes shIn{
  0%{opacity:0;transform:translateY(-14px)}
  65%{transform:translateY(2px)}
  100%{opacity:1;transform:translateY(0)}}

/* the buttons keep their size; the group name is what gives way,
   because a squeezed button wraps its own label onto two lines */
#shellbtns{flex:0 0 auto;display:flex;align-items:center;gap:8px}
#shellbtn{
  background:#2121de;color:#fff;border:0;font-family:inherit;font-size:9px;
  letter-spacing:2px;padding:10px 14px;cursor:pointer;white-space:nowrap;
  box-shadow:0 4px 0 #0d0d73,0 0 16px rgba(33,33,222,.45);
  transition:transform .05s,box-shadow .05s}
#shellbtn:active{transform:translateY(4px);box-shadow:0 0 0 #0d0d73}

/* ── the one shortcut a page may hang next to MENU ────────
   Yellow, because it is the only thing on the bar that is a
   suggestion rather than a door: PARTY FEED from the camera,
   TAKE ANOTHER from the feed. Same shape as MENU so the two
   read as a pair, not as a button and an afterthought. */
#shelllink{
  background:#ffde00;color:#0a0a1e;text-decoration:none;font-family:inherit;
  font-size:9px;letter-spacing:2px;padding:10px 14px;cursor:pointer;
  white-space:nowrap;
  box-shadow:0 4px 0 #8a7800,0 0 16px rgba(255,222,0,.5);
  transition:transform .05s,box-shadow .05s}
#shelllink:active{transform:translateY(4px);box-shadow:0 0 0 #8a7800}
#shellgroup{
  flex:1 1 auto;font-size:8px;letter-spacing:2px;text-align:right;min-width:0;
  overflow:hidden;white-space:nowrap;text-overflow:ellipsis}

/* ── the overlay ───────────────────────────────────────────
   z-index 89 sits above #app (2) but below #crt (90) and #vig
   (91), so the scanlines and the tube glow still run over the
   menu — and below #ready/#toast, which must stay on top.
   Opaque, or the screen underneath bleeds through the type.    */
#shellmenu{
  position:fixed;inset:0;z-index:89;display:none;overflow-y:auto;
  -webkit-overflow-scrolling:touch;background:#01010a;
  padding:calc(env(safe-area-inset-top) + 26px) 18px calc(env(safe-area-inset-bottom) + 28px)}
#shellmenu.on{display:block}
#shellmenu .wrap{margin:0 auto;width:100%;max-width:460px}
#shellmenu h1{margin-bottom:16px}

.sh-logo{font-size:18px;color:#ffde00;text-align:center;line-height:1.6;
  text-shadow:0 0 22px rgba(255,222,0,.7);margin-bottom:20px;letter-spacing:2px}
.sh-logo span{color:#fff}

/* an app button */
.sapp{
  display:flex;align-items:center;gap:12px;
  width:100%;text-align:left;text-decoration:none;
  border:3px solid #2a2a6e;border-left-width:7px;background:#06061a;
  font-family:inherit;color:#fff;padding:16px 14px;margin-bottom:11px;cursor:pointer;
  box-shadow:0 0 0 3px #000,inset 0 0 20px rgba(33,33,222,.16);
  transition:transform .05s,background .1s}
.sapp:active{transform:translateY(3px);background:#0d0d2c}
.sapp .sbody{flex:1 1 auto;min-width:0}
.sapp .st{font-size:11px;letter-spacing:2px;line-height:1.7;
  display:block;overflow-wrap:break-word}
.sapp .sb{font-size:8px;letter-spacing:2px;color:#6b6b9e;line-height:1.9;
  margin-top:9px;display:block}
.sapp.here{box-shadow:0 0 0 3px #000,0 0 22px rgba(255,255,255,.14),
  inset 0 0 20px rgba(255,255,255,.06);background:#0d0d2c}
.sapp.here .sb::after{content:' · YOU ARE HERE';color:#8a8ac0}
/* Dim, and the same blue as the frame around it, so a locked row
   reads as furniture rather than as a game. It still takes a tap —
   that is how it gets to say why it is shut. */
.sapp.locked{opacity:.38;pointer-events:auto;cursor:pointer;
  border-color:#2a2a6e;border-left-color:#2a2a6e !important;background:#04041a}
.sapp.locked .st{color:#8a8ac0 !important}
.sapp.locked .sb{color:#5a5a8e}

/* ── the badge on the right of a row ──────────────────────
   Two shapes, one colour. The tick is drawn with borders rather
   than typed, because Press Start 2P has no tick in it and the
   fallback font looks like a stray from another website. */
.sflag{flex:0 0 auto;display:flex;align-items:center;justify-content:center}
.sflag.tick{
  width:26px;height:26px;border:2px solid #ffde00;background:rgba(255,222,0,.08);
  box-shadow:0 0 12px rgba(255,222,0,.35),inset 0 0 8px rgba(255,222,0,.12)}
.sflag.tick::after{
  content:'';width:11px;height:6px;margin-top:-4px;
  border-left:3px solid #ffde00;border-bottom:3px solid #ffde00;
  transform:rotate(-45deg)}
.sflag.num{
  font-size:10px;letter-spacing:2px;color:#ffde00;white-space:nowrap;
  text-shadow:0 0 12px rgba(255,222,0,.55)}
/* a locked row is dimmed as a whole, so its badge must not shout */
.sapp.locked .sflag.tick{border-color:#8a8ac0;box-shadow:none;background:none}
.sapp.locked .sflag.tick::after{border-color:#8a8ac0}
.sapp.locked .sflag.num{color:#8a8ac0;text-shadow:none}

/* waiting room */
.sh-wait{border:3px solid #2121de;background:rgba(4,4,20,.72);padding:18px 14px;
  margin-bottom:18px;text-align:center;
  box-shadow:0 0 0 3px #000,0 0 22px rgba(33,33,222,.4),inset 0 0 22px rgba(33,33,222,.18)}
.sh-wait .sw-g{font-size:14px;letter-spacing:2px;margin:12px 0 6px;line-height:1.7}
.sh-wait .sw-dots{font-size:12px;color:#2121de;letter-spacing:4px;margin-top:14px}
.sh-err{font-size:9px;color:#ff3b30;margin-top:14px;letter-spacing:1px;
  min-height:14px;line-height:1.8}
.sh-foot{font-size:8px;letter-spacing:2px;color:#6b6b9e;line-height:1.9;
  text-align:center;margin-top:20px}

/* ── a tile that is waiting on the code at the party ──────
   Locked tiles are switched off and dimmed to nearly nothing.
   This one is the exception: it is the way IN, so it keeps its
   taps, keeps its colour, and breathes so the eye finds it. */
.sapp.scan{opacity:1;pointer-events:auto;cursor:pointer;
  border-left-color:#ff77c8 !important;
  animation:shPulse 2.4s ease-in-out infinite}
.sapp.scan .st{color:#ff77c8 !important}
.sapp.scan .sb{color:#ff77c8}
.sapp.scan .sb::after{content:' \203A';font-size:12px}
@keyframes shPulse{
  0%,100%{box-shadow:0 0 0 3px #000,0 0 10px rgba(255,119,200,.20)}
  50%    {box-shadow:0 0 0 3px #000,0 0 24px rgba(255,119,200,.60)}
}
@media (prefers-reduced-motion: reduce){ .sapp.scan{animation:none} }
/* already scanned: still there to scan again, but no longer the one
   thing on the screen asking to be pressed */
.sapp.scan.done{animation:none;opacity:.85}
/* the scan result's "still to come" heading */
.sh-soon{margin:18px 0 10px;text-align:left}

/* ── the scanner ──────────────────────────────────────── */
#shscan{width:100%;max-width:420px;margin:0 auto;text-align:center}
.shs-box{position:relative;width:100%;aspect-ratio:1/1;overflow:hidden;
  background:#000;border:3px solid #ff77c8;
  box-shadow:0 0 0 3px #000,0 0 30px rgba(255,119,200,.45)}
.shs-box video{width:100%;height:100%;object-fit:cover;display:block}
.shs-frame{position:absolute;inset:14%;pointer-events:none}
.shs-frame i{position:absolute;width:26px;height:26px;border:4px solid #ffde00}
.shs-frame i:nth-child(1){top:0;left:0;border-right:0;border-bottom:0}
.shs-frame i:nth-child(2){top:0;right:0;border-left:0;border-bottom:0}
.shs-frame i:nth-child(3){bottom:0;left:0;border-right:0;border-top:0}
.shs-frame i:nth-child(4){bottom:0;right:0;border-left:0;border-top:0}
.shs-cap{margin:16px 0 14px}
.shs-msg{font-size:9px;letter-spacing:2px;color:#c9c9e8;line-height:2;
  margin-top:10px;min-height:32px}
.shs-msg.bad{color:#ff3b30}

/* ── what a locked row says when you press it ──────────────
   Inside #shellmenu, which is its own stacking context at 89,
   so this sits over the menu and still under the CRT glass. */
#sh-lock{position:fixed;inset:0;z-index:5;display:none;
  align-items:center;justify-content:center;padding:24px;
  background:rgba(1,1,10,.88)}
#sh-lock.on{display:flex;animation:shLockIn .18s ease-out}
@keyframes shLockIn{from{opacity:0}to{opacity:1}}
#sh-lock .sl-box{width:100%;max-width:380px;text-align:center;
  border:3px solid #ff77c8;background:#06061a;padding:22px 16px;
  box-shadow:0 0 0 3px #000,0 0 26px rgba(255,119,200,.45),
             inset 0 0 22px rgba(255,119,200,.12)}
#sh-lock .sl-msg{font-size:10px;letter-spacing:2px;line-height:2.1;
  color:#fff;margin-bottom:20px;overflow-wrap:break-word}

/* ── the 101 card (shell.js) ──────────────────────────────
   Shown once, over whatever the app's first screen happens to be,
   so it is drawn to sit ON something rather than to replace it:
   a hard yellow box on a blacked-out page, and nothing else on
   screen to press. The sticker is the one picture any of these
   cards carries, and it is the first thing to go when the screen
   is too short to hold the words and a button as well. */
#shintro{position:fixed;inset:0;z-index:60;display:none;
  align-items:center;justify-content:center;padding:24px;
  background:rgba(1,1,10,.9)}
#shintro.on{display:flex;animation:shCardIn .2s ease-out}
@keyframes shCardIn{from{opacity:0}to{opacity:1}}
#shintro .si-box,#gameclue .si-box{width:100%;max-width:360px;text-align:center;
  border:3px solid #ffde00;background:#06061a;padding:24px 18px;
  box-shadow:0 0 0 3px #000,0 0 28px rgba(255,222,0,.4),
             inset 0 0 22px rgba(255,222,0,.1)}
#shintro .si-t,#gameclue .si-t{font-size:13px;letter-spacing:3px;line-height:1.9;
  color:#ffde00;text-shadow:0 0 16px rgba(255,222,0,.5);
  margin-bottom:18px;overflow-wrap:break-word}
#shintro .si-b,#gameclue .si-b{font-size:10px;letter-spacing:2px;line-height:2.3;
  color:#ffde00;white-space:pre-line;margin-bottom:22px;
  overflow-wrap:break-word}
#shintro .si-img{display:block;width:190px;max-width:72%;height:auto;
  margin:0 auto 18px;filter:drop-shadow(0 0 16px rgba(255,222,0,.35))}
@media (max-height:600px){ #shintro .si-img{display:none} }

/* The same card, raised by the main game after a named hand-over to
   carry a destination clue — see steps.js showClue(). Same box on
   purpose: by the time a guest meets the companion apps they have
   already learned that a yellow box means read this, then carry on.
   It stacks above #ready (z 94), which is what it replaces. */
#gameclue{position:fixed;inset:0;z-index:95;display:none;
  align-items:center;justify-content:center;padding:24px;
  background:rgba(1,1,10,.94)}
#gameclue.on{display:flex;animation:shCardIn .2s ease-out}
