/* Defaults; each box overrides these CSS variables via app.js (theme). */
:root {
  --wall:#bfa6a8; --wall-ink:#ad9092;
  --wood:#6b4329; --wood-lo:#4a2e18;
  --doily:#f6efe0; --box:#7c4a2c; --box-lid:#90593a; --box-lo:#5e3820;
  --lamp:#ffd49a; --accent:#7c5a3c;
}

* { box-sizing:border-box; }
html,body { margin:0; min-height:100%; }

body {
  min-height:100vh;
  color:#2b2117;
  background-color:var(--wall);
  /* faded damask wallpaper: a quatrefoil floret (center dot + four petals) on a
     72px grid, with quarter-dots at tile corners for the half-drop diamond rhythm,
     over faint vertical stripes */
  --flo-hi: color-mix(in srgb, var(--wall-ink) 85%, var(--wall));
  --flo-lo: color-mix(in srgb, var(--wall-ink) 50%, var(--wall));
  background-image:
    radial-gradient(circle 2.6px at 36px 36px, var(--flo-hi) 97%, transparent),
    radial-gradient(circle 1.6px at 27px 36px, var(--flo-lo) 97%, transparent),
    radial-gradient(circle 1.6px at 45px 36px, var(--flo-lo) 97%, transparent),
    radial-gradient(circle 1.6px at 36px 27px, var(--flo-lo) 97%, transparent),
    radial-gradient(circle 1.6px at 36px 45px, var(--flo-lo) 97%, transparent),
    radial-gradient(circle 1.5px at 0px 0px, var(--flo-lo) 97%, transparent),
    radial-gradient(circle 1.5px at 72px 0px, var(--flo-lo) 97%, transparent),
    radial-gradient(circle 1.5px at 0px 72px, var(--flo-lo) 97%, transparent),
    radial-gradient(circle 1.5px at 72px 72px, var(--flo-lo) 97%, transparent),
    repeating-linear-gradient(90deg, rgba(0,0,0,.028) 0 1px, transparent 1px 36px);
  background-size:72px 72px, 72px 72px, 72px 72px, 72px 72px, 72px 72px,
                  72px 72px, 72px 72px, 72px 72px, 72px 72px, auto;
}

/* warm lamp glow from the upper right + a soft vignette */
#lamp {
  position:fixed; inset:0; pointer-events:none; z-index:0;
  background:
    radial-gradient(60% 55% at 72% 8%, color-mix(in srgb, var(--lamp) 55%, transparent), transparent 70%),
    radial-gradient(120% 100% at 50% 40%, transparent 55%, rgba(20,10,4,.42) 100%);
}

#scene { position:relative; z-index:1; max-width:720px; margin:0 auto; padding:30px 20px 60px; }

/* the between-boxes curtain: the room dims to warm dark, the box swaps while it's
   dark, the lights come back up — the page never reloads, so the music plays on */
#curtain { position:fixed; inset:0; z-index:8; pointer-events:none;
  background:#140d08; opacity:0; transition:opacity .55s ease; }
#curtain.down { opacity:1; }

/* ── the stage: desk, doily, box, the rising object ── */
.stage { position:relative; height:320px; perspective:900px; }

.desk {
  position:absolute; left:-100vw; right:-100vw; bottom:0; height:96px;
  background:linear-gradient(var(--wood), var(--wood-lo));
  box-shadow:inset 0 2px 0 rgba(255,255,255,.08), 0 -1px 14px rgba(0,0,0,.25);
}
.desk::before { /* wood grain */
  content:""; position:absolute; inset:0; opacity:.18;
  background:repeating-linear-gradient(90deg, rgba(0,0,0,.5) 0 1px, transparent 1px 7px);
}

.doily {
  position:absolute; left:50%; bottom:54px; transform:translateX(-50%);
  width:330px; height:96px; border-radius:50%;
  background:var(--doily);
  /* crochet rings, elliptical so they follow the doily's shape */
  background-image:repeating-radial-gradient(ellipse at 50% 50%,
     var(--doily) 0 7px, color-mix(in srgb, var(--doily) 86%, #000) 7px 8px);
  box-shadow:0 4px 10px rgba(0,0,0,.25);
}
/* lace frill: a ring of picot tabs peeking out around the rim (a ring-shaped
   background cut into tabs by a repeating conic mask — no mask-composite needed) */
.doily::before {
  /* picot lace edge: round dots marching along the elliptical rim */
  content:""; position:absolute; inset:-5px; border-radius:50%;
  border:4px dotted var(--doily);
}

.box {
  position:absolute; left:50%; bottom:66px; transform:translateX(-50%);
  width:216px; height:140px; transform-style:preserve-3d;
}
.box-interior { position:absolute; left:10px; right:10px; top:30px; height:34px;
  /* felt lining, tinted toward each box's accent */
  background:linear-gradient(
    color-mix(in srgb, var(--accent) 32%, #17090b),
    color-mix(in srgb, var(--accent) 14%, #0d0507));
  border-radius:4px; }
.box.open .box-interior {
  box-shadow:inset 0 4px 9px rgba(0,0,0,.65), inset 0 -1px 0 rgba(255,255,255,.05); }
.box-body { position:absolute; left:0; right:0; bottom:0; height:104px; z-index:3;
  background:linear-gradient(160deg, var(--box), var(--box-lo)); border-radius:7px;
  box-shadow:inset 0 -12px 22px rgba(0,0,0,.35), inset 0 2px 0 rgba(255,255,255,.12), 0 16px 26px rgba(0,0,0,.4); }
.box-body::before { content:""; position:absolute; inset:0; border-radius:7px; opacity:.16;
  background:repeating-linear-gradient(90deg, rgba(0,0,0,.6) 0 1px, transparent 1px 9px); }
.box-body::after { /* brass hinges along the back edge, revealed when the lid opens */
  content:""; position:absolute; top:-3px; left:34px; width:20px; height:7px; border-radius:2px;
  background:linear-gradient(#d8b46a,#8a6a2c);
  box-shadow:128px 0 0 0 #c9a75c; }
.box-lid { position:absolute; left:0; right:0; top:0; height:50px; z-index:4;
  background:linear-gradient(var(--box-lid), var(--box)); border-radius:7px 7px 4px 4px;
  transform-origin:50% 100%; /* hinge at the lid's bottom edge, where it meets the body */
  transition:transform 1s cubic-bezier(.34,.1,.2,1), filter 1s ease;
  box-shadow:0 5px 9px rgba(0,0,0,.3), inset 0 2px 0 rgba(255,255,255,.14); }
/* open: the lid swings up and away from the viewer, standing just past vertical at
   the box's back edge — attached at the hinge, falling into shadow */
.box.open .box-lid { transform:rotateX(102deg); filter:brightness(.55) saturate(.85); }
.box-clasp { position:absolute; left:50%; top:40px; transform:translateX(-50%); z-index:5;
  width:26px; height:20px; border-radius:3px;
  background:linear-gradient(#d8b46a,#9c7833); box-shadow:0 1px 2px rgba(0,0,0,.4);
  transition:opacity .5s; }
.box-clasp::after { /* keyhole */
  content:""; position:absolute; left:50%; top:5px; transform:translateX(-50%);
  width:7px; height:10px;
  background:
    radial-gradient(circle 2.4px at 50% 2.6px, #3a2a10 96%, transparent),
    linear-gradient(#3a2a10,#3a2a10) 50% 100%/2px 5px no-repeat; }
.box.open .box-clasp { opacity:0; }

/* the grandparent table lamp, standing on the desk at the right */
.lampstand {
  position:absolute; right:10px; bottom:88px; width:130px; height:178px;
  pointer-events:none;
  background:
    /* warm halo behind the shade */
    radial-gradient(circle 72px at 50% 40px, color-mix(in srgb, var(--lamp) 32%, transparent), transparent 72%),
    /* base */
    radial-gradient(ellipse 42px 10px at 50% calc(100% - 2px), #4c3417 96%, transparent);
}
.lampstand::after { /* stem */
  content:""; position:absolute; left:50%; bottom:6px; transform:translateX(-50%);
  width:9px; height:118px; border-radius:5px;
  background:linear-gradient(90deg,#8a683c,#59401d 60%,#3c2a12);
}
.lampstand::before { /* shade */
  content:""; position:absolute; left:50%; top:0; transform:translateX(-50%);
  width:112px; height:64px;
  background:linear-gradient(
    color-mix(in srgb, var(--lamp) 72%, #fff),
    color-mix(in srgb, var(--lamp) 45%, #6e4318));
  clip-path:polygon(21% 0, 79% 0, 100% 100%, 0% 100%);
}

/* the object sits IN FRONT of the box (never clipped by the viewport on phones).
   Entering: it fades in while drifting gently DOWN, as if lifted out of the box
   and set before you. Leaving (class removed): a quick blink out. */
.object {
  position:absolute; left:50%; bottom:104px; z-index:6;
  transform:translate(-50%, -18px);
  font-size:90px; line-height:1; opacity:0;
  filter:drop-shadow(0 12px 14px rgba(0,0,0,.4));
  transition:opacity .12s ease; /* removing .show = brief blink out */
}
.object img { height:160px; width:auto; max-width:260px; object-fit:contain; display:block; }
.object.show {
  opacity:1; transform:translate(-50%, 0);
  transition:transform .55s cubic-bezier(.2,.6,.3,1), opacity .5s ease;
}

/* ── the narration panel ── */
.panel {
  max-width:640px; margin:14px auto 0;
  background:color-mix(in srgb, var(--doily) 92%, #fff);
  border:1px solid rgba(0,0,0,.1); border-radius:11px;
  padding:22px 28px; box-shadow:0 14px 36px rgba(0,0,0,.3);
}
.panel-label { font-family:'Special Elite', monospace; font-size:13px; letter-spacing:.4px;
  color:var(--accent); margin-bottom:12px; }
.panel-label::before { content:"❧ "; }
.panel-text { font-family:'EB Garamond', Georgia, serif; font-size:20px; line-height:1.62; color:#2b2117; }
.panel-text p { margin:0 0 13px; }
.panel-text p:last-child { margin-bottom:0; }
.panel-foot { display:flex; align-items:center; justify-content:space-between; margin-top:20px; gap:16px; }
.progress { display:flex; gap:8px; flex-wrap:wrap; }
.dot { width:8px; height:8px; border-radius:50%; background:rgba(0,0,0,.16); transition:background .3s; }
.dot.on { background:var(--accent); }
.advance { font-family:'EB Garamond', serif; font-size:17px; cursor:pointer;
  background:var(--accent); color:var(--doily); border:none; border-radius:22px; padding:9px 26px;
  box-shadow:0 3px 8px rgba(0,0,0,.25); transition:filter .2s, transform .05s; }
.advance:hover { filter:brightness(1.09); }
.advance:active { transform:translateY(1px); }

.mute {
  position:fixed; top:16px; right:18px; z-index:5;
  width:40px; height:40px; border-radius:50%; cursor:pointer;
  border:1px solid rgba(0,0,0,.14);
  background:color-mix(in srgb, var(--doily) 82%, transparent);
  color:var(--accent); font-size:17px; line-height:1;
  box-shadow:0 2px 8px rgba(0,0,0,.22); opacity:.6;
  transition:opacity .2s, filter .2s;
}
.mute:hover { opacity:1; }
.mute.off { color:#9a8d80; }

@media (max-width:560px){
  .panel-text { font-size:18px; }
  .stage { height:280px; }
  .lampstand { display:none; } /* too crowded next to the box on phones */
  .object img { height:136px; max-width:210px; }
  .object { font-size:76px; }
}

@media (prefers-reduced-motion: reduce){
  .box-lid, .object, .advance { transition:none; }
}
