/* The Stage: the live séance, behind a proscenium. Velvet curtains part on the act;
   the spirit's words own the frame, set in woodtype as they are spoken; a worn Ouija
   board lies on the table below with candles around it that die as the truth nears. */

#room.active {
  display: grid; grid-template-rows: auto minmax(9rem, 1fr) auto auto;
  min-height: 100dvh; padding: 98px clamp(56px, 9vw, 140px) 0;
  text-align: center;
  /* Candlelight pools on the table below; it falls away as the candles go out. */
  background:
    linear-gradient(to top, rgba(245, 187, 77, calc(.1 * var(--light) + .03 * var(--flicker))), transparent 45%),
    var(--stock-deep);
  transition: background 1.2s;
}

/* ---------- Who is on stage, and what they are doing ---------- */
.stage-head { display: grid; justify-items: center; gap: var(--space-2); }
.stage-name { font-size: clamp(1.4rem, 3.4vw, 2.2rem); color: var(--bone-dim); letter-spacing: .08em; }

/* Three states, three structures, never just three captions:
   listening is a rubber stamp, thinking is printer's ornament, speaking is live type. */
.status {
  min-height: 2.4rem; margin: 0; display: inline-flex; align-items: center; gap: .4em;
  font: 800 .95rem/1 var(--face-gothic); letter-spacing: .24em; text-transform: uppercase; color: var(--bone-dim);
}
body[data-mode="listening"] .status {
  color: var(--bone); padding: .5em .9em; border: 2px solid var(--bone); transform: rotate(-2deg);
  animation: stamp .35s var(--ease-out) both;
}
@keyframes stamp { from { opacity: 0; transform: rotate(-2deg) scale(1.25); } }
.status .thinking { display: none; gap: .35em; }
body[data-mode="thinking"] .status .thinking { display: inline-flex; }
body[data-mode="thinking"] .status .label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.thinking .icon { width: 2.4rem; height: 1.2rem; color: var(--oxblood); animation: breathe 1.4s ease-in-out infinite; }
.thinking .icon:nth-child(2) { animation-delay: .2s; } .thinking .icon:nth-child(3) { animation-delay: .4s; }
@keyframes breathe { 50% { opacity: .25; } }

/* ---------- The spirit's words ---------- */
.words { display: grid; align-content: center; justify-items: center; gap: var(--space-3); padding: var(--space-3) 0; }
.spirit {
  margin: 0; max-width: 28ch; color: var(--bone);
  font: 800 min(var(--fit, 3.4rem), 9vw)/1.02 var(--face-gothic); text-transform: uppercase; letter-spacing: .01em;
  min-height: 1.1em;
}
.spirit .w { display: inline-block; white-space: pre; }
.you { margin: 0; max-width: 60ch; font: italic 1.1rem/1.4 var(--face-roman); color: var(--bone-dim); min-height: 1.4em; }
.you:not(:empty)::before { content: 'You: '; font-style: normal; }

/* ---------- The table: the board, the candles, the record ---------- */
.table {
  display: grid; grid-template-columns: minmax(0, 1fr) 10rem; gap: var(--space-4); align-items: end;
  /* The board yields height to the words: it takes what the header, a long line and the button leave. */
  width: min(100%, 860px, calc((100dvh - 628px) * 1.7 + 12rem)); min-width: min(100%, 420px); margin: 0 auto;
}
.tabletop { position: relative; padding: 34px 0 26px; perspective: 1300px; }
.board-tilt { transform: rotateX(26deg); transform-origin: 50% 75%; }

/* An aged wooden talking board: grain, worn edges, a little varnish catching the candles. */
.board {
  position: relative; width: 100%; aspect-ratio: 1.55; border-radius: 22px;
  --wood-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='700' height='450'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.0045 0.26' numOctaves='4' seed='17'/%3E%3CfeColorMatrix values='0 0 0 0 .22 0 0 0 0 .12 0 0 0 0 .05 0 0 0 .85 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  background:
    linear-gradient(115deg, transparent 30%, rgba(255, 236, 200, calc(.08 + var(--light) * .06)) 45%, transparent 60%),
    radial-gradient(ellipse 75% 70% at 50% 48%, transparent 55%, rgba(48, 22, 6, .55) 100%),
    var(--wood-grain),
    linear-gradient(180deg, #c99b5f, #b5844a 55%, #a07039);
  background-size: auto, auto, cover, auto; background-blend-mode: normal, normal, multiply, normal;
  box-shadow: inset 0 0 0 2px rgba(0, 0, 0, .35), inset 0 2px 1px rgba(255, 230, 190, .35), inset 0 -10px 24px rgba(0, 0, 0, .35),
              0 30px 40px -18px rgba(0, 0, 0, .85), 0 6px 0 #6b4520, 0 7px 0 #3d240e;
  filter: brightness(calc(.42 + var(--light) * .58)) saturate(1.05); transition: filter 1.2s;
}
.board-art { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; color: #2b1607; }
.board-art .frame { fill: none; stroke: currentColor; stroke-width: .6; opacity: .75; }
.board-art .frame + .frame { stroke-width: .25; opacity: .55; }
.board-art .art { fill: none; stroke: currentColor; stroke-width: .7; stroke-linecap: round; stroke-linejoin: round; opacity: .85; }
.board-art .art-fill { fill: currentColor; opacity: .85; }

.board .glyph {
  position: absolute; transform: translate(-50%, -50%) rotate(var(--r));
  font: 400 clamp(1rem, 3vw, 2.05rem)/1 var(--face-roman); color: #2b1607; user-select: none;
  text-shadow: 0 1px 0 rgba(255, 228, 180, .35); /* ink pressed into the varnish */
  transition: color .25s, transform .25s var(--ease-out);
}
.board .glyph.word { font: 400 clamp(.85rem, 2.2vw, 1.45rem)/1 var(--face-roman); font-variant: small-caps; letter-spacing: .12em; }
.board .glyph.lit { color: var(--oxblood-deep); transform: translate(-50%, -50%) rotate(var(--r)) scale(1.3); }
/* What the spirit spells stays marked on the board. */
.board .glyph.inked:not(.lit) { color: var(--oxblood); }

/* A heart-shaped wooden planchette with a glass window. */
.planchette {
  position: absolute; left: 50%; top: 60%; width: 12.5%; z-index: 2;
  transform: translate(-50%, -52%) rotate(var(--tilt, 0deg));
  filter: drop-shadow(0 10px 6px rgba(0, 0, 0, .5));
  transition: left .9s var(--ease-out), top .9s var(--ease-out), transform .9s var(--ease-out);
}
.planchette svg { display: block; width: 100%; overflow: visible; }
.planchette.drift { animation: drift 7s ease-in-out infinite; }
@keyframes drift { 50% { translate: 1.5% 1.2%; rotate: 3deg; } }

/* ---------- Candles: wax, wick, a living flame ---------- */
.candles { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.candle {
  position: absolute; width: calc(22px * var(--s, 1)); height: calc(var(--h, 70px) * var(--s, 1));
  transform: translate(-50%, -100%);
}
.candle .wax {
  position: absolute; inset: 0; border-radius: 3px 3px 4px 4px;
  /* Lit from its own flame: brightest just under the rim, falling into shadow at the foot. */
  background:
    linear-gradient(180deg, rgba(255, 214, 140, calc(.35 * var(--lit, 1))), transparent 35%),
    linear-gradient(90deg, #a8987a 0%, #e9dfc6 22%, #fbf5e6 42%, #e3d7bb 64%, #9c8c6d 100%);
  box-shadow: 0 8px 10px -2px rgba(0, 0, 0, .6);
}
.candle .wax::before { /* a drip running from the rim */
  content: ''; position: absolute; top: 2px; left: 18%; width: 5px; height: 38%; border-radius: 0 0 4px 4px;
  background: linear-gradient(90deg, #ece2c9, #fff8ea, #dcd0b2);
}
.candle .wax::after { /* the melted pool at the top */
  content: ''; position: absolute; top: -3px; left: 0; right: 0; height: 7px; border-radius: 50%;
  background: radial-gradient(ellipse at 50% 40%, #fff7e2, #e6d9bb 70%);
}
.candle .wick { position: absolute; left: 50%; top: -9px; width: 2px; height: 9px; margin-left: -1px; background: #1c120a; border-radius: 1px; }
.flame {
  position: absolute; left: 50%; bottom: calc(100% + 6px); width: calc(14px * var(--s, 1)); height: calc(30px * var(--s, 1));
  transform-origin: 50% 90%; translate: -50% 0;
  border-radius: 50% 50% 46% 46% / 62% 62% 38% 38%;
  /* White-hot core, warm body, a blue root where the wick feeds it. */
  background:
    radial-gradient(ellipse 30% 22% at 50% 88%, rgba(110, 140, 255, .75), transparent 100%),
    radial-gradient(ellipse 34% 38% at 50% 70%, #fffdf3 0%, #fff1c4 45%, transparent 100%),
    radial-gradient(ellipse 50% 60% at 50% 62%, #ffcf66 0%, #ff9d2e 55%, rgba(255, 110, 20, 0) 100%);
  transform: scale(calc(1 + var(--voice) * .35 + var(--flicker) * .06));
  /* Flicker via brightness and skew, never opacity: an animated opacity overrides .out and the flame would never go out. */
  animation: flicker 1.3s infinite alternate ease-in-out;
  transition: opacity .35s;
}
.candle:nth-child(2n) .flame { animation-duration: 1.7s; }
.candle:nth-child(3n) .flame { animation-duration: 1.1s; }
@keyframes flicker { 0% { rotate: -3deg; filter: brightness(.92); } 50% { rotate: 2.5deg; filter: brightness(1.06); } 100% { rotate: -1deg; filter: brightness(.88); } }
.candle.unlit .flame, .candle.out .flame { opacity: 0; }
.candle.unlit, .candle.out { --lit: 0; }
.candle.out .smoke {
  position: absolute; left: 50%; bottom: 100%; width: 6px; height: 50px; margin-left: -3px;
  background: linear-gradient(to top, rgba(220, 215, 205, .5), transparent); filter: blur(3px);
  animation: smoke 3s ease-out forwards;
}
@keyframes smoke { to { transform: translateY(-70px) scaleX(3.4); opacity: 0; } }
body[data-mode="thinking"] .flame { animation-duration: .35s; }

/* ---------- The record: what the spirit has spelled, rising ---------- */
.record { align-self: stretch; display: flex; flex-direction: column; justify-content: flex-end; text-align: left; min-height: 0; overflow: hidden; padding-bottom: 26px; }
.record h3 { font: 600 .85rem/1 var(--face-gothic); letter-spacing: .3em; text-transform: uppercase; color: var(--bone-dim); margin-top: var(--space-2); order: 2; }
.record ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column-reverse; gap: .15em; }
.record li { color: var(--bone); line-height: 1; overflow-wrap: anywhere; }
.record li:nth-child(odd) { font: 800 1.7rem/1 var(--face-gothic); text-transform: uppercase; }
.record li:nth-child(even) { font: 400 1.35rem/1.05 var(--face-fat); }
.record li:first-child { color: var(--gas); }

.stage-foot { display: flex; justify-content: flex-end; padding: var(--space-3) 0 max(16px, env(safe-area-inset-bottom)); }
.end { font-size: .9rem; border-width: 1px; padding: .7rem 1rem; }

/* ---------- The proscenium: velvet curtains and a fringed valance ---------- */
.proscenium { position: fixed; inset: 0; z-index: 30; pointer-events: none; overflow: hidden; }
.curtain {
  position: absolute; top: 0; bottom: 0; width: 51vw;
  /* Velvet: two fold rhythms that never quite repeat, deep shadow in each trough. */
  background:
    linear-gradient(180deg, transparent 70%, rgba(10, 0, 2, .55)),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, .5) 0, rgba(0, 0, 0, .06) 22px, rgba(255, 190, 190, .1) 34px, rgba(0, 0, 0, .1) 48px, rgba(0, 0, 0, .5) 68px),
    repeating-linear-gradient(90deg, transparent 0, rgba(0, 0, 0, .22) 41px, transparent 97px),
    linear-gradient(180deg, #8f1622, #6a0c16 60%, #46070e);
  box-shadow: inset 0 0 60px rgba(0, 0, 0, .5);
  transition: transform 1.8s cubic-bezier(.65, 0, .25, 1);
}
.curtain::after { content: ''; position: absolute; inset: 0; background: var(--grain); mix-blend-mode: overlay; opacity: .9; }
.curtain-l { left: 0; transform-origin: left; }
.curtain-r { right: 0; transform-origin: right; }
/* Open: drawn to the wings and gathered, leaving a fold of velvet framing each side. */
body.curtain-open .curtain-l { transform: translateX(-87%) scaleX(.9); }
body.curtain-open .curtain-r { transform: translateX(87%) scaleX(.9); }
.curtain-l { box-shadow: inset -30px 0 40px rgba(0, 0, 0, .45), 14px 0 30px rgba(0, 0, 0, .5); }
.curtain-r { box-shadow: inset 30px 0 40px rgba(0, 0, 0, .45), -14px 0 30px rgba(0, 0, 0, .5); }

.valance {
  position: absolute; top: 0; left: 0; right: 0; height: 58px; z-index: 1;
  background:
    repeating-linear-gradient(90deg, rgba(0, 0, 0, .35) 0, rgba(255, 190, 190, .08) 26px, rgba(0, 0, 0, .35) 52px),
    linear-gradient(180deg, #7a1019, #5a0a12);
  box-shadow: 0 10px 24px rgba(0, 0, 0, .55);
}
.valance::before { /* swags hanging below the pelmet */
  content: ''; position: absolute; left: 0; right: 0; top: 100%; height: 26px;
  background: radial-gradient(ellipse 50% 100% at 50% 0, #5e0b13 97%, transparent 100%) 0 0 / 120px 26px repeat-x;
  filter: drop-shadow(0 6px 6px rgba(0, 0, 0, .45));
}
.valance::after { /* gold fringe along each swag */
  content: ''; position: absolute; left: 0; right: 0; top: calc(100% + 18px); height: 10px;
  background: repeating-linear-gradient(90deg, #c9a14a 0 2px, transparent 2px 5px);
  -webkit-mask: radial-gradient(ellipse 50% 100% at 50% -60%, #000 97%, transparent 100%) 0 0 / 120px 10px repeat-x;
  mask: radial-gradient(ellipse 50% 100% at 50% -60%, #000 97%, transparent 100%) 0 0 / 120px 10px repeat-x;
  opacity: .9;
}

/* ---------- The room shakes ---------- */
body.shake-gentle #room .table { animation: shake .5s 3; }
body.shake-violent main { animation: shake-hard .12s 14; }
@keyframes shake { 25% { transform: translate(-3px, 1px) rotate(-.4deg); } 75% { transform: translate(3px, -1px) rotate(.4deg); } }
@keyframes shake-hard { 25% { transform: translate(-10px, 5px) rotate(-1deg); } 75% { transform: translate(10px, -6px) rotate(1deg); } }

@media (max-width: 720px) {
  #room.active { padding: 76px 22px 0; grid-template-rows: auto minmax(7rem, 1fr) auto auto; }
  .words { padding: var(--space-3) 0; gap: var(--space-2); }
  .table { grid-template-columns: 1fr; width: 100%; gap: var(--space-2); }
  .tabletop { padding: 34px 0 24px; }
  .board-tilt { transform: rotateX(14deg); }
  .board { border-radius: 14px; }
  .planchette { width: 15%; }
  .record { flex-direction: row; align-items: baseline; gap: var(--space-2); padding-bottom: 0; }
  .record h3 { order: 0; margin: 0; }
  .record ol { flex-direction: row-reverse; flex-wrap: wrap; justify-content: flex-end; gap: .4em; }
  .record li:nth-child(odd), .record li:nth-child(even) { font-size: 1.1rem; }
  .candle { --s: .62; }
  .stage-foot { justify-content: center; padding-top: var(--space-2); }
  .end { min-height: 40px; padding: .55rem 1rem; }
  .valance { height: 40px; }
  body.curtain-open .curtain-l { transform: translateX(-94%) scaleX(.9); }
  body.curtain-open .curtain-r { transform: translateX(94%) scaleX(.9); }
}

@media (prefers-reduced-motion: reduce) {
  .flame, .planchette.drift, .thinking .icon, body[data-mode="listening"] .status,
  body.shake-gentle #room .table, body.shake-violent main { animation: none !important; }
  .planchette { transition-duration: .2s; }
  .curtain { transition: none; }
}
