/* /puzzlebox/box.css — puzzlebox devices + socket states.
   Rides on frame.css vars: --wood-*, --char-*, --ember, --ink, --pb-S, --pb-gap. */

/* ===== Device root (overlays inside the content cavity) ===== */
#pb-device{
  position: absolute;
  inset: 0;
  z-index: 60;
  pointer-events: none;
}
#pb-device > *{ pointer-events: auto; }

/* ===== Socket states ===== */
#pb-left, #pb-right, #pb-top{ position: relative; }

.pb-socket{
  pointer-events: auto;
  display: grid;             /* frame.css never centered glyphs — fix that */
  place-items: center;
}
.pb-socket .base{
  /* larger + uniform; symbol glyphs have small metrics at the old clamp */
  font-size: clamp(13px, calc(var(--pb-S) * 0.5), 21px) !important;
  line-height: 1;
}

/* Armed specials: barely warmer than their neighbors. Level 1, not a signpost. */
.pb-socket.pb-armed{ cursor: pointer; }
.pb-socket.pb-armed .base{ color: rgba(255, 226, 200, 0.88); }

.pb-socket.pb-warm .base{
  text-shadow: 0 1px 0 rgba(0,0,0,0.75), 0 0 9px rgba(255,106,26,0.35);
}

/* Deeper-engraved letters (after the case opens) */
.pb-socket.pb-cap-lit .base{
  color: rgba(255, 238, 214, 0.96);
  text-shadow: 0 1px 0 rgba(0,0,0,0.75),
    0 0 10px rgba(255,106,26,0.45),
    0 0 22px rgba(255,106,26,0.22);
}

/* The number that burns, inside the window */
.pb-socket.pb-burning{ cursor: pointer; }
.pb-socket.pb-burning .base{
  color: #ffe7c9;
  animation: pb-burn 1.6s ease-in-out infinite;
}
@keyframes pb-burn{
  0%, 100% { text-shadow: 0 0 8px rgba(255,106,26,0.5), 0 0 18px rgba(255,106,26,0.25); }
  50%      { text-shadow: 0 0 14px rgba(255,140,60,0.9), 0 0 30px rgba(255,106,26,0.5); }
}

/* Hold-to-commit charge (duration set inline via --pb-charge-ms) */
.pb-socket.pb-charging::after{
  border-color: rgba(255,106,26,0.0);
  animation: pb-charge var(--pb-charge-ms, 3000ms) linear forwards;
}
@keyframes pb-charge{
  0%   { box-shadow: inset 0 0 0 1px rgba(255,255,255,0.03); }
  100% { box-shadow: inset 0 0 0 3px rgba(255,120,40,0.75), 0 0 18px rgba(255,106,26,0.5); }
}

/* ===== The key ritual: sliding cover, recess, key, keyhole ===== */

/* Sockets hidden beneath the door go blank — the door owns those pixels */
.pb-socket.pb-under-cover .base,
.pb-socket.pb-under-cover .overlay{ opacity: 0 !important; }

.pb-cover-host{
  position: absolute;        /* left/top/w/h set by JS to the 2×4 cell block */
  z-index: 5;
  pointer-events: auto;
}

/* The recess beneath: dark cavity, key + engraved sigil. Anchored near the
   TOP, not centered — the panel slides away starting from the top edge, so
   whatever's revealed first should be the key, not empty space. Centering it
   meant the panel had to travel roughly half its distance before uncovering
   anything at all, which is why the key only ever seemed to "pop in" near
   the end instead of appearing as the cover moved off it. */
.pb-recess{
  position: absolute; inset: 1px;
  border-radius: 9px;
  display: grid;
  justify-content: center;
  align-content: start;
  padding-top: 14px;
  gap: 8px;
  background:
    radial-gradient(70% 60% at 50% 40%, rgba(255,106,26,0.07), transparent 70%),
    linear-gradient(180deg, #070403, #030202);
  box-shadow:
    inset 0 4px 14px rgba(0,0,0,0.9),
    inset 0 0 0 1px rgba(0,0,0,0.6);
}
.pb-realkey{
  width: 70%;
  max-width: 72px;
  margin: 0 auto;
  color: #c9a86a;
  cursor: grab;
  filter: drop-shadow(0 2px 3px rgba(0,0,0,0.9));
  transition: filter .15s ease, opacity .25s ease;
}
.pb-realkey:hover{ filter: drop-shadow(0 2px 3px rgba(0,0,0,0.9)) drop-shadow(0 0 10px rgba(255,190,100,0.45)); }
.pb-realkey.pb-key-away{ opacity: 0; pointer-events: none; }
.pb-realkey svg{ display: block; width: 100%; height: auto; }

/* Pulled loose from the keyhole (double-click while shut) — a standalone
   grabbable object resting where it fell, not a grid item inside the
   recess anymore, so it needs its own explicit size/position instead of
   the 70%-of-parent sizing above. */
.pb-realkey-loose{
  position: absolute;
  width: 44px;
  margin: 0;
  transform: translate(-50%, 0);
  z-index: 7;
}

/* The floating key while carried (fixed, follows the pointer, tip leads right) */
.pb-keyfloat{
  position: fixed;
  z-index: 9999;
  /* width set inline by plank.js at pickup, matched to .pb-realkey's actual
     rendered size — no fixed fallback here on purpose, so it never jumps. */
  color: #c9a86a;
  pointer-events: none;
  filter: drop-shadow(0 3px 6px rgba(0,0,0,0.8));
}
.pb-keyfloat.pb-key-seeking{
  filter: drop-shadow(0 3px 6px rgba(0,0,0,0.8)) drop-shadow(0 0 12px rgba(255,120,40,0.7));
}
.pb-keyfloat svg{ display: block; width: 100%; height: auto; }

/* The door: 8 tiles indistinguishable from their neighbors (one bears the key).
   Position/z-index/transform are all set inline by plank.js — this is just the
   solid backdrop. Real sockets sit in a grid with a gap between cells, and the
   door's own tiles mirror that same gap (they're sized/positioned to match the
   sockets they're disguising), so without a backdrop of its own, those seams
   were a window straight through to whatever's behind the whole panel. This
   fills the panel's full rectangle underneath the tiles so the seams show more
   of the same wood instead of a hole. */
.pb-door{
  background-image:
    var(--pb-grain),
    radial-gradient(40px 28px at 30% 30%, var(--wood-hi), transparent 55%),
    linear-gradient(180deg, rgba(0,0,0,0.18), rgba(0,0,0,0.42));
  background-blend-mode: overlay, normal, normal;
  background-size: 120px 120px, auto, auto;
  background-color: var(--wood-2);
  border-radius: 4px;
}
.pb-door-tile{
  position: absolute;
  border-radius: 4px; /* match .pb-socket — a carved slab, not a rounded card */
  display: grid;
  place-items: center;
  /* Same grain + wood-tone + carved-in treatment as .pb-socket::before — a
     secret panel that looks visually distinct from its neighbors has already
     failed at being secret. */
  background-image:
    var(--pb-grain),
    radial-gradient(40px 28px at 30% 30%, var(--wood-hi), transparent 55%),
    linear-gradient(180deg, rgba(0,0,0,0.18), rgba(0,0,0,0.42));
  background-blend-mode: overlay, normal, normal;
  background-size: 120px 120px, auto, auto;
  background-color: var(--wood-2);
  border: 1px solid rgba(255,255,255,0.11);
  box-shadow:
    inset 2px 2px 3px rgba(0,0,0,0.65),
    inset -1px -1px 2px rgba(255,214,170,0.05),
    0 1px 0 rgba(255,255,255,0.03);
}
.pb-door-tile:nth-child(3n)   { background-color: var(--wood-1); }
.pb-door-tile:nth-child(3n+1){ background-color: var(--wood-3); }
.pb-door-tile:nth-child(3n+2){ background-color: var(--wood-2); }
.pb-door-glyph{
  font: 800 clamp(11px, calc(var(--pb-S) * 0.38), 16px) / 1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--brass);
  text-shadow:
    0 1px 1px rgba(0,0,0,0.85),
    0 -1px 0 rgba(0,0,0,0.4),
    0 1px 0 rgba(255,224,180,0.12);
}
.pb-door-handle{ cursor: grab; }
.pb-door-handle svg{
  width: 74%; height: auto;
  color: var(--brass);
  opacity: 0.95;
}
/* No hover animation here on purpose — it doesn't stand out from its
   neighbors until grabbed (see the whole "no tells" design of this
   mechanic). This used to nudge 2px on hover via a now-dead
   ".pb-door-live" guard that was never actually applied to .pb-door
   anymore, so the give was firing unconditionally. */

/* ===== The keyhole socket (east rail — the box's mouth all chain long) ===== */
.pb-socket.pb-keyhole .base{
  position: absolute; inset: 0;
  display: grid; place-items: center;
}
.pb-socket.pb-keyhole .pb-svg{
  width: 62%; height: 62%;
  color: var(--brass);
  transition: transform .1s linear, filter .2s ease;
}
.pb-socket.pb-keyhole.pb-key-hover .pb-svg{
  filter: drop-shadow(0 0 10px rgba(255,120,40,0.7));
  transform: scale(1.08);
}
.pb-socket.pb-inserted-live{ cursor: grab; }
.pb-socket.pb-inserted-live .pb-svg{ color: var(--brass); }
.pb-socket.pb-unlocked .pb-svg{
  color: var(--brass);
  filter: drop-shadow(0 0 12px rgba(255,140,60,0.8));
}

/* ===== Mechanical drawer pop (key-turn opening/closing) ===== */
.pb-drawer.pb-pop{
  /* was .62s — "a bit slower" per feedback */
  animation: pb-mech-pop .82s cubic-bezier(.34,1.3,.4,1) both;
}
@keyframes pb-mech-pop{
  0%   { transform: translate(-50%, -112%); opacity: 1; }
  55%  { transform: translate(-50%, 9%);   opacity: 1; }
  75%  { transform: translate(-50%, 2%);   opacity: 1; }
  100% { transform: translate(-50%, 6%);   opacity: 1; }
}
/* Reverse of the above — played by closeDrawer() (key turned back to 0°)
   before the panel is actually torn out of the DOM. */
.pb-drawer.pb-pop-close{
  animation: pb-mech-pop-close .7s cubic-bezier(.5,0,.3,1) both;
}
@keyframes pb-mech-pop-close{
  0%   { transform: translate(-50%, 6%);    opacity: 1; }
  30%  { transform: translate(-50%, 2%);    opacity: 1; }
  100% { transform: translate(-50%, -112%); opacity: 1; }
}
.pb-sigil{
  font: 700 10px/1 ui-monospace, Menlo, Consolas, monospace;
  letter-spacing: 0.14em;
  color: rgba(255,230,200,0.4);
  text-align: center;
  text-shadow: 0 1px 0 rgba(0,0,0,0.8);
  user-select: text;
}

/* ===== Panels (drawer, clock, mastermind, entry) ===== */
.pb-panel{
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -54%) scale(0.98);
  opacity: 0;
  /* Wider + taller than before, and paired with the 2-column reveal grid
     below — the drawer's reveals were stacking into a single column tall
     enough to always need a scrollbar. This gives them room to sit side by
     side instead, so the common case fits without one. */
  max-width: min(94%, 560px);
  max-height: 92%;
  overflow: auto;
  padding: 22px 24px 20px;
  border-radius: 14px;
  background:
    var(--pb-grain),
    radial-gradient(600px 240px at 50% 0%, var(--ember), transparent 60%),
    repeating-linear-gradient(100deg, rgba(255,255,255,0.02) 0 2px, rgba(0,0,0,0) 9px 20px),
    linear-gradient(180deg, var(--wood-2), var(--wood-0));
  background-size: 140px 140px, auto, auto, auto;
  background-blend-mode: overlay, normal, normal, normal;
  border: 1px solid rgba(217,181,108,0.18);
  box-shadow:
    0 30px 80px rgba(0,0,0,0.7),
    inset 0 1px 0 rgba(255,255,255,0.06),
    inset 0 -18px 30px rgba(0,0,0,0.55);
  transition: opacity .22s ease, transform .22s ease;
  color: var(--brass);
  /* Styled scrollbar — a plain white OS-default bar was the one thing left
     that didn't read as wood/brass. Still a safety net for whatever
     doesn't fit, just no longer a jarring one. */
  scrollbar-width: thin;
  scrollbar-color: var(--brass) var(--wood-0);
}
.pb-panel::-webkit-scrollbar{ width: 8px; }
.pb-panel::-webkit-scrollbar-track{ background: var(--wood-0); border-radius: 8px; }
.pb-panel::-webkit-scrollbar-thumb{ background: var(--brass); border-radius: 8px; opacity: 0.6; }
.pb-panel::-webkit-scrollbar-thumb:hover{ background: var(--brass-lit); }
.pb-panel.pb-open{
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}
/* Fixed footprint, not content-driven — it's the same physical drawer
   whether it's holding the tile puzzle (phase 1, small) or the reveals
   (phase 2+, bigger and more of them). A drawer doesn't change size
   depending on what's in it; .pb-panel's max-width/max-height above would
   otherwise let each phase's content shrink-wrap its own box. */
.pb-drawer{
  top: 0;
  width: min(94%, 560px);
  height: 92%;
  transform: translate(-50%, -8%) scale(0.99);
}
.pb-drawer.pb-open{ transform: translate(-50%, 6%) scale(1); top: 0; }

.pb-close{
  position: absolute; right: 8px; top: 6px;
  background: none; border: none; cursor: pointer;
  color: rgba(255,230,200,0.45);
  font: 700 18px/1 system-ui;
}
.pb-close:hover{ color: rgba(255,230,200,0.85); }

/* Reveals sit in a responsive 2-up grid instead of one long stacked column
   — card/case-style boxes are narrow enough to pair up side by side; plain
   engraved text (riddles, vowels, numeral lines) spans the full width
   below for readability. */
.pb-drawer-inner{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 10px 16px;
  justify-items: center;
  align-items: start;
}

/* ===== Engraved text ===== */
.pb-engraved{
  font: 700 13px/1.5 ui-monospace, Menlo, Consolas, monospace;
  letter-spacing: 0.10em;
  color: var(--brass);
  text-shadow: 0 1px 0 rgba(0,0,0,0.85), 0 -1px 0 rgba(255,255,255,0.05), 0 0 8px rgba(255,106,26,0.12);
  white-space: pre-wrap;
  text-align: center;
}
/* Multi-line prose and self-contained boxes always take the full row.
   Vowels and numerals are both short single "X · Y · Z" lines, so they're
   left OUT of this list on purpose — they're narrow enough to pair up in
   the 2-up grid instead of each claiming a full row on their own. */
.pb-riddle, .pb-card, .pb-timeline, .pb-mmline,
.pb-case, .pb-case-open{ grid-column: 1 / -1; }
.pb-vowels{ font-size: 19px; letter-spacing: 0.28em; }
.pb-riddle{ opacity: 0.92; max-width: 100%; }
.pb-numerals{ font-size: 16px; color: var(--brass-lit); }

/* ===== Key card =====
   One line: all the symbol->letter pairs plus "ADVANCE BY" flow left to
   right (wrapping only if the panel is ever too narrow), instead of each
   pair stacked on its own row — that's what was eating the vertical space. */
.pb-card{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 4px 16px;
  padding: 8px 16px;
  border-radius: 10px;
  background:
    var(--pb-grain),
    linear-gradient(180deg, var(--wood-1), var(--wood-0));
  background-size: 100px 100px, auto;
  background-blend-mode: overlay, normal;
  border: 1px solid rgba(217,181,108,0.22);
  box-shadow:
    inset 0 2px 6px rgba(0,0,0,0.6),
    inset 0 -1px 0 rgba(255,255,255,0.04);
}
.pb-card-row{
  display: inline-flex; align-items: center; gap: 5px;
  font: 700 15px/1.3 ui-monospace, Menlo, Consolas, monospace;
  color: var(--brass-lit);
  text-shadow: 0 1px 0 rgba(0,0,0,0.85);
}
.pb-card-row i{ font-style: normal; opacity: 0.45; color: var(--brass); }
.pb-card-adv{
  font: 700 11px/1 ui-monospace, Menlo, Consolas, monospace;
  letter-spacing: 0.16em;
  color: var(--brass);
  padding-left: 10px;
  border-left: 1px solid rgba(217,181,108,0.25);
}

/* ===== Sliding tiles ===== */
.pb-tiles{
  position: relative;
  border-radius: 10px;
  background: linear-gradient(180deg, #0a0605, #050303);
  box-shadow: inset 0 3px 12px rgba(0,0,0,0.9);
  padding: 0;
}
.pb-tile{
  position: absolute;
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 6px;
  overflow: hidden;
  cursor: pointer;
  padding: 0;
  background:
    repeating-linear-gradient(100deg, rgba(255,255,255,0.03) 0 2px, rgba(0,0,0,0) 8px 16px),
    linear-gradient(180deg, var(--wood-3), var(--wood-1));
  box-shadow: 0 3px 8px rgba(0,0,0,0.6), inset 0 1px 0 rgba(255,255,255,0.05);
  transition: left .12s ease, top .12s ease;
}
.pb-tile-face{
  position: absolute; left: 0; top: 0;
  display: block;
  text-align: center;
  font-weight: 900;
  font-family: Georgia, 'Times New Roman', serif;
  color: rgba(255,196,120,0.35);
  text-shadow: 0 0 18px rgba(255,106,26,0.25);
  pointer-events: none;
}

/* ===== Briefcase + lock ===== */
.pb-case{
  padding: 14px 18px;
  border-radius: 12px;
  background:
    var(--pb-grain),
    linear-gradient(180deg, #171009, #0b0704);
  background-size: 100px 100px, auto;
  background-blend-mode: overlay, normal;
  border: 1px solid rgba(217,181,108,0.2);
  box-shadow:
    0 8px 22px rgba(0,0,0,0.55),
    inset 0 1px 0 rgba(255,255,255,0.05);
}
.pb-case-open{ display: grid; gap: 8px; }
.pb-lock{ display: grid; gap: 12px; justify-items: center; }
.pb-lock-wheels{ display: flex; gap: 14px; }
.pb-wheel{ display: grid; justify-items: center; gap: 2px; }
.pb-wheel-btn{
  background: none; border: none; cursor: pointer;
  color: rgba(255,230,200,0.4);
  font-size: 11px; padding: 3px 8px;
}
.pb-wheel-btn:hover{ color: rgba(255,230,200,0.85); }
.pb-wheel-face{
  display: grid;
  justify-items: center;
  width: 44px;
  padding: 4px 0;
  border-radius: 8px;
  background: linear-gradient(180deg, #211508, #0d0803 40%, #211508);
  border: 1px solid rgba(200,160,100,0.25);
  box-shadow: inset 0 2px 8px rgba(0,0,0,0.85);
  font: 800 18px/1.35 ui-monospace, Menlo, Consolas, monospace;
}
.pb-wheel-cur{ color: rgba(255,238,214,0.95); }
.pb-wheel-ghost{ color: rgba(255,238,214,0.18); font-size: 12px; }
.pb-latch, .pb-mm-go, .pb-speak{
  background: linear-gradient(180deg, #2a1a0c, #140b05);
  border: 1px solid rgba(200,160,100,0.3);
  border-radius: 10px;
  cursor: pointer;
  color: rgba(255,214,160,0.85);
  font-size: 18px;
  padding: 8px 22px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.06);
  transition: box-shadow .15s ease, color .15s ease;
}
.pb-latch:hover, .pb-mm-go:hover:not(:disabled), .pb-speak:hover{
  color: rgba(255,238,214,1);
  box-shadow: 0 4px 16px rgba(255,106,26,0.25), inset 0 1px 0 rgba(255,255,255,0.06);
}
.pb-mm-go:disabled{ opacity: 0.35; cursor: default; }

/* ===== Clock ===== */
.pb-clockpanel{ padding: 28px; }
.pb-clock-face{
  position: relative;
  width: 180px; height: 180px;
  border-radius: 50%;
  background:
    radial-gradient(120px 120px at 40% 30%, rgba(255,255,255,0.05), transparent 60%),
    linear-gradient(180deg, #120b06, #060403);
  border: 2px solid rgba(200,160,100,0.3);
  box-shadow: inset 0 4px 18px rgba(0,0,0,0.85), 0 10px 30px rgba(0,0,0,0.6);
}
.pb-hand{
  position: absolute;
  left: 50%; bottom: 50%;
  transform-origin: 50% 100%;
  border-radius: 4px;
  background: rgba(255,226,190,0.85);
}
.pb-hand-h{ width: 4px; height: 46px; margin-left: -2px; }
.pb-hand-m{ width: 3px; height: 66px; margin-left: -1.5px; }
.pb-hand-s{ width: 1px; height: 74px; margin-left: -0.5px; background: rgba(255,120,40,0.9); }
.pb-clock-pin{
  position: absolute; left: 50%; top: 50%;
  width: 8px; height: 8px; margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: #c9a86a;
}

/* ===== Mastermind ===== */
.pb-mm{ display: grid; gap: 12px; justify-items: center; }
.pb-mm-history{
  display: grid; gap: 5px;
  max-height: 200px; overflow-y: auto;
  min-width: 210px;
}
.pb-mm-row{
  display: flex; align-items: center; gap: 6px; justify-content: center;
}
.pb-mm-cell{
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border-radius: 7px;
  background: linear-gradient(180deg, #1b1109, #0c0704);
  border: 1px solid rgba(255,230,200,0.12);
  color: rgba(255,238,214,0.9);
  font-size: 16px;
}
.pb-mm-pegs{
  margin-left: 8px;
  font-size: 12px;
  letter-spacing: 0.2em;
  color: rgba(255,214,160,0.85);
  min-width: 58px;
}
.pb-mm-current{ display: flex; gap: 6px; align-items: center; }
.pb-mm-slot{
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border-radius: 8px;
  cursor: pointer;
  background: linear-gradient(180deg, #241608, #0f0904);
  border: 1px solid rgba(200,160,100,0.25);
  color: rgba(255,238,214,0.9);
  font-size: 18px;
}
.pb-mm-active{ box-shadow: 0 0 0 2px rgba(255,120,40,0.5); }
.pb-mm-tray{ display: flex; gap: 10px; }
.pb-mm-pick{
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: 50%;
  cursor: pointer;
  background: linear-gradient(180deg, #2a1a0c, #140b05);
  border: 1px solid rgba(200,160,100,0.3);
  color: rgba(255,238,214,0.95);
  font-size: 20px;
  box-shadow: 0 4px 10px rgba(0,0,0,0.5);
}
.pb-mm-red{ color: #ff8a6a !important; }

/* ===== Entry ===== */
.pb-entry{ display: grid; gap: 16px; justify-items: center; }
.pb-entry-row{ display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.pb-entry-card{
  display: grid; gap: 4px;
  padding: 8px 6px;
  border-radius: 8px;
  background: linear-gradient(180deg, rgba(255,240,215,0.07), rgba(255,240,215,0.02));
  border: 1px solid rgba(255,230,200,0.14);
}
.pb-entry-sel{
  background: #140b05;
  color: rgba(255,238,214,0.92);
  border: 1px solid rgba(200,160,100,0.3);
  border-radius: 6px;
  font: 700 14px/1.2 ui-monospace, Menlo, Consolas, monospace;
  padding: 4px 6px;
}
.pb-invite{ display: grid; gap: 10px; justify-items: center; padding: 8px 0; }
.pb-invite-code{
  font: 800 24px/1 ui-monospace, Menlo, Consolas, monospace;
  letter-spacing: 0.12em;
  color: #ffdca8;
  text-shadow: 0 0 16px rgba(255,140,60,0.5), 0 0 40px rgba(255,106,26,0.25);
  user-select: text;
}
.pb-invite-line{
  font: 700 12px/1.5 ui-monospace, Menlo, Consolas, monospace;
  letter-spacing: 0.1em;
  color: rgba(255,234,206,0.7);
  text-align: center;
}
