/* ─── Story theme: Gorey ─── */
/* First named story theme. Loaded by app/views/layouts/story.html.erb on top of
   the main app stylesheet. Plain CSS that references global font tokens
   (--font-display, --font-decorative, --font-body) declared in the @theme
   block of app/assets/tailwind/application.css. */

:root {
  /* Sky palettes */
  --sky-day-top:       #8cb8d8;
  --sky-day-horizon:   #e8d8b8;
  --sky-dusk-top:      #4a3a6a;
  --sky-dusk-horizon:  #d88a4a;
  --sky-night-top:     #0a0820;
  --sky-night-horizon: #2a1f3a;
  --sky-dawn-top:      #5a4a6a;
  --sky-dawn-horizon:  #e8a88a;

  --sun-core:          #f8d878;
  --sun-halo:          #f8b848;
  --moon-core:         #e8e0c8;
  --moon-halo:         #a8a098;
  --star-fill:         #f8f0d8;

  --candle-wax:        #e8d8b0;
  --candle-wick-lit:   #3a2a18;
  --candle-wick-dark:  #2a1e14;
  --flame-core:        #f8e8a8;
  --flame-outer:       #f89a48;
  --flame-glow:        #ffc878;
  --smoke-color:       rgba(200, 190, 180, 0.6);

  --card-surface:       rgba(242, 228, 200, 0.92);
  --card-surface-night: rgba(232, 220, 192, 0.86);
  --card-ink:           #2a1f14;
  --card-flourish:      #8a5a2a;

  --good-gold:        #a88b42;
  --evil-crimson:     #7a1a1a;
  --outsider-slate:   #5a6a7a;
  --traveller-indigo: #3a2a5a;

  /* Finale theme palettes. Blended into --sky-top/--sky-horizon via
     --finale-weight (0..1), published by sky_controller when the viewport
     midline crosses the .story-finale section. */
  --finale-evil-top:     #1a0408;
  --finale-evil-horizon: #6e1e1e;
  --finale-evil-floor:   #1a0808;
  --finale-good-top:     #5ea3d1;
  --finale-good-horizon: #e4f0ff;
  --finale-good-floor:   #c8dcef;
}

/* The story page should escape the regular max-width container. */
.story-page {
  position: relative;
  width: 100%;
  margin: 0;
}

/* Diorama is a fixed sky/candle layer behind the scrolling text column. */
.diorama {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
  /* Sky color blends three palettes (day, dusk, night) based on how close
     the viewport midline is to each chapter's center. All weights are
     published by sky_controller as a continuous function of scroll, so the
     transition between any two chapters is a smooth arc through dusk. */
  --sky-base-top: color-mix(in oklab,
    color-mix(in oklab, var(--sky-dusk-top), var(--sky-day-top) calc(var(--inner-mix, 0) * 100%)),
    var(--sky-night-top) calc(var(--night-weight, 0) * 100%));
  --sky-base-horizon: color-mix(in oklab,
    color-mix(in oklab, var(--sky-dusk-horizon), var(--sky-day-horizon) calc(var(--inner-mix, 0) * 100%)),
    var(--sky-night-horizon) calc(var(--night-weight, 0) * 100%));
  --sky-finale-top:     var(--sky-base-top);
  --sky-finale-horizon: var(--sky-base-horizon);
  --sky-floor:          #1a1410;
  --sky-top: color-mix(in oklab,
    var(--sky-base-top),
    var(--sky-finale-top) calc(var(--finale-weight, 0) * 100%));
  --sky-horizon: color-mix(in oklab,
    var(--sky-base-horizon),
    var(--sky-finale-horizon) calc(var(--finale-weight, 0) * 100%));
  background: linear-gradient(to bottom, var(--sky-top) 0%, var(--sky-horizon) 60%, var(--sky-floor) 100%);
}

.diorama[data-winner="evil"] {
  --sky-finale-top:     var(--finale-evil-top);
  --sky-finale-horizon: var(--finale-evil-horizon);
  --sky-floor: color-mix(in oklab, #1a1410, var(--finale-evil-floor) calc(var(--finale-weight, 0) * 100%));
}
.diorama[data-winner="good"] {
  --sky-finale-top:     var(--finale-good-top);
  --sky-finale-horizon: var(--finale-good-horizon);
  --sky-floor: color-mix(in oklab, #1a1410, var(--finale-good-floor) calc(var(--finale-weight, 0) * 100%));
}

.sky-stars {
  position: absolute;
  inset: 0 0 40vh 0;
  width: 100vw;
  height: 60vh;
  pointer-events: none;
  opacity: var(--star-opacity, 0);
}
.star-field {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  border-radius: 50%;
}

/* Illustrated starbursts layered on top of the dot field. */
.sky-bursts {
  position: absolute;
  inset: 0 0 40vh 0;
  width: 100vw;
  height: 60vh;
  pointer-events: none;
  opacity: var(--star-opacity, 0);
}
.star-burst {
  position: absolute;
  width: var(--size, 2vh);
  height: var(--size, 2vh);
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
  opacity: var(--burst-opacity, 0.7);
  animation: star-twinkle 4s ease-in-out infinite;
  animation-delay: var(--twinkle-delay, 0s);
}
@keyframes star-twinkle {
  0%, 100% { opacity: var(--burst-opacity, 0.7); }
  50%      { opacity: calc(var(--burst-opacity, 0.7) * 0.9); }
}

/* Cloud field. Clouds drift slowly across the sky; visible during day and
   dusk, hidden at night (inverse of stars). */
.sky-clouds {
  position: absolute;
  inset: 0 0 40vh 0;
  width: 100vw;
  height: 60vh;
  pointer-events: none;
  overflow: hidden;
  opacity: calc(1 - var(--reveal-approach, 0));
}
.cloud {
  position: absolute;
  left: 0;
  width: var(--cloud-w, 40vh);
  aspect-ratio: 1344 / 784;
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
  opacity: var(--cloud-opacity, 0.7);
  animation: cloud-drift var(--drift-duration, 240s) linear infinite;
  animation-delay: var(--drift-delay, 0s);
  will-change: transform;
}
@keyframes cloud-drift {
  from { transform: translateX(-60vw); }
  to   { transform: translateX(110vw); }
}

/* Sun and moon each traverse the sky tied to the nearest day/night chapter.
   --sun-t and --moon-t are continuous positions (0 = off left, 0.5 = zenith,
   1 = off right). Opacity peaks at their own chapter's center and fades to
   zero halfway to the neighboring chapter, so handoffs land on empty sky. */
.celestial {
  position: absolute;
  width: 44vh;
  height: 44vh;
  top: 0;
  left: 0;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}
.sun {
  transform: translate(
    calc(var(--sun-t, 0.5) * (100vw + 44vh) - 44vh),
    calc(50vh - sin(var(--sun-t, 0.5) * 3.14159) * 48vh)
  );
  opacity: calc(var(--sun-opacity, 0) * (1 - var(--reveal-approach, 0)));
}
.moon {
  transform: translate(
    calc(var(--moon-t, 0.5) * (100vw + 44vh) - 44vh),
    calc(50vh - sin(var(--moon-t, 0.5) * 3.14159) * 48vh)
  );
  opacity: calc(var(--moon-opacity, 0) * (1 - var(--reveal-approach, 0)));
}
/* Finale celestial. Fades in as the viewport crosses the reveal section.
   Replaces the sun/moon with a theme-specific image (devil face or dove). */
.celestial.finale {
  transform: translate(calc(50vw - 22vh), calc(50vh - 26vh));
  opacity: var(--reveal-progress, 0);
}

/* Atmospheric creatures */
.sky-creatures { position: absolute; inset: 0 0 40vh 0; pointer-events: none; }
.bat { position: absolute; left: 0; width: 5vw; opacity: 0.8; display: none; }
.diorama[data-phase-kind="night"] .bat { display: block; animation: flutter-across var(--flutter-duration, 40s) ease-in-out infinite; animation-delay: var(--flutter-delay, 0s); }

@keyframes flutter-across {
  0%   { transform: translate(112vw, 4vh); }
  50%  { transform: translate(50vw, -2vh); }
  100% { transform: translate(-12vw, 6vh); }
}

/* Candle arc. Bottom band of viewport. */
.candle-arc {
  position: absolute;
  bottom: 4vh;
  left: 50%;
  transform: translateX(-50%);
  width: min(94vw, 1200px);
  height: 32vh;
}
.candle {
  --candle-w: 76px;
  position: absolute;
  bottom: 0;
  width: var(--candle-w);
  aspect-ratio: var(--candle-aspect, 688 / 1151);
  --t: calc((var(--seat-index, 0) + 0.5) / var(--seat-count, 1));
  left: calc(var(--t) * 100% - var(--candle-w) / 2);
  transform: translateY(calc(sin(var(--t) * 3.14159) * -3vh));
  transition: opacity 600ms ease, transform 900ms ease;
}

.candle-body {
  position: absolute;
  inset: 0;
  background-image: var(--candle-body-url);
  background-repeat: no-repeat;
  background-size: contain;
  background-position: bottom center;
  transition: filter 600ms ease;
}

/* Flame sprite. Each frame is 180×320; base is at 50%,96.25%. Anchor the element
   so that base sits on the wick, then cycle the 4 frames via steps(4). */
.candle-flame {
  position: absolute;
  width: 52%;
  aspect-ratio: 180 / 320;
  left: var(--wick-x, 50%);
  top: var(--wick-y, 25%);
  transform: translate(-50%, -96.25%);
  background-image: var(--flame-strip-url);
  background-size: 400% 100%;
  background-repeat: no-repeat;
  background-position-x: 0%;
  filter: drop-shadow(0 0 6px rgba(255, 200, 90, 0.95)) drop-shadow(0 0 14px rgba(255, 120, 60, 0.55));
  animation:
    candle-flicker 0.6s steps(4, jump-none) infinite,
    candle-flame-glow 2.4s ease-in-out infinite alternate;
  animation-delay: var(--flicker-delay, 0ms), calc(var(--flicker-delay, 0ms) * -1.7);
  transition: opacity 600ms ease;
  pointer-events: none;
}
@keyframes candle-flicker {
  from { background-position-x: 0%; }
  to   { background-position-x: 100%; }
}
@keyframes candle-flame-glow {
  0%   { filter: drop-shadow(0 0 5px rgba(255, 210, 110, 0.95)) drop-shadow(0 0 12px rgba(255, 150, 70, 0.55)); }
  50%  { filter: drop-shadow(0 0 7px rgba(255, 170, 80, 1))    drop-shadow(0 0 16px rgba(255, 100, 50, 0.65)); }
  100% { filter: drop-shadow(0 0 6px rgba(255, 130, 70, 0.95)) drop-shadow(0 0 18px rgba(220, 70, 40,  0.6)); }
}

.candle-flame::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 2%;
  width: 42%;
  height: 44%;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at 50% 70%,
    rgba(255, 220, 90, 1) 0%,
    rgba(255, 140, 50, 0.85) 45%,
    rgba(220, 60,  40, 0.35) 75%,
    transparent 92%);
  filter: blur(1.5px);
  mix-blend-mode: plus-lighter;
  pointer-events: none;
  animation: candle-flame-inner-glow 2.4s ease-in-out infinite alternate;
  animation-delay: calc(var(--flicker-delay, 0ms) * -1.7);
}
@keyframes candle-flame-inner-glow {
  0%   { opacity: 0.5;  transform: translateX(-50%) scale(0.95); }
  50%  { opacity: 0.75; transform: translateX(-50%) scale(1.08); }
  100% { opacity: 0.55; transform: translateX(-50%) scale(0.92); }
}

.candle[data-variant="1"] { --candle-aspect: 688 / 1151; --wick-x: 46%; --wick-y: 57%; }
.candle[data-variant="2"] { --candle-aspect: 688 / 1308; --wick-x: 48%; --wick-y: 26%; }
.candle[data-variant="3"] { --candle-aspect: 688 / 1380; --wick-x: 50%; --wick-y: 24%; }
.candle[data-variant="4"] { --candle-aspect: 688 / 1138; --wick-x: 50%; --wick-y: 53%; }

.candle-label {
  display: block;
  position: absolute;
  bottom: -1.4rem;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
  font-family: var(--font-display);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  color: #f5e7c3;
  text-shadow:
    0 0 2px rgba(0, 0, 0, 0.95),
    0 0 4px rgba(0, 0, 0, 0.85),
    0 1px 6px rgba(0, 0, 0, 0.7);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: calc(var(--candle-w) * 2);
}

.candle-smoke {
  position: absolute;
  left: var(--wick-x, 50%);
  top: var(--wick-y, 25%);
  width: 36%;
  height: 40%;
  transform: translate(-50%, -100%);
  opacity: 0;
  pointer-events: none;
}

/* State: dormant = candle present, no flame. Wax filter dims it slightly. */
.candle[data-state="dormant"] .candle-flame { opacity: 0; animation: none; }
.candle[data-state="dormant"] .candle-body  { filter: brightness(0.82) saturate(0.85); }

/* Extinguished: flame out, smoke rises briefly. */
.candle[data-state="extinguished"] .candle-flame { opacity: 0; animation: none; }

.candle[data-effect-smoke] .candle-smoke {
  animation: smoke-rise 1800ms ease-out forwards;
}
@keyframes smoke-rise {
  0%   { opacity: 0.9; transform: translate(-50%, -100%) scale(1); }
  100% { opacity: 0;   transform: translate(-50%, -180%) scale(1.4); }
}

.candle[data-state="exiled"] {
  opacity: 0;
  transform: translateY(8vh);
}

/* Text column. The scrolling layer above the diorama. */
.story-column {
  position: relative;
  z-index: 2;
  max-width: 640px;
  margin: 0 auto;
  padding: 0 1.5rem;
}

.story-opening {
  min-height: 90vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 8vh 0;
}
.story-eyebrow {
  font-family: var(--font-display);
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--card-ink);
  opacity: 0.7;
}
.story-title {
  font-family: var(--font-decorative);
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  letter-spacing: 0.04em;
  margin-top: 0.6rem;
  color: var(--card-ink);
  text-shadow: 0 2px 6px rgba(0,0,0,0.18);
}
.story-meta {
  font-family: var(--font-display);
  font-size: 0.85rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--card-ink);
  opacity: 0.7;
  margin-top: 0.6rem;
}
.story-opening-line {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 1.25rem;
  margin-top: 2rem;
  color: var(--card-ink);
  background: var(--card-surface);
  padding: 1.5rem 1.75rem;
  border-radius: 4px;
  border: 1px solid rgba(138, 90, 42, 0.3);
}
.story-scroll-cue {
  margin-top: 4vh;
  width: 1px;
  height: 4vh;
  background: linear-gradient(to bottom, transparent, var(--card-flourish));
  opacity: 0.6;
}

.chapter {
  padding: 8vh 0;
  min-height: 100vh;
}
.chapter-title {
  font-family: var(--font-decorative);
  font-size: clamp(2rem, 4.5vw, 3.5rem);
  letter-spacing: 0.1em;
  text-align: center;
  text-transform: uppercase;
  margin: 0 auto 5vh;
  color: var(--card-ink);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.28);
  --title-scale: 1;
  --title-translate-y: 0px;
  --title-opacity: 1;
  translate: 0 var(--title-translate-y);
  scale: var(--title-scale);
  transform-origin: 50% 50%;
  opacity: var(--title-opacity);
  will-change: scale, translate, opacity;
}
.chapter[data-chapter-phase-kind-value="night"] .chapter-title {
  color: #f0dfb5;
  text-shadow: 0 0 18px rgba(0, 0, 0, 0.65);
}
.story-finale .chapter-title {
  color: #f5e7c3;
  text-shadow:
    0 0 2px rgba(0, 0, 0, 0.9),
    0 0 6px rgba(0, 0, 0, 0.8),
    0 2px 14px rgba(0, 0, 0, 0.65);
}
.scene-opening-line {
  font-family: var(--font-display);
  font-size: 1rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: center;
  color: var(--card-ink);
  background: var(--card-surface);
  padding: 1.25rem;
  border-radius: 4px;
  border: 1px solid rgba(138, 90, 42, 0.25);
}

.beat {
  margin: 4vh auto;
  max-width: 580px;
  padding: 1.5rem 1.75rem;
  background: var(--card-surface);
  border: 1px solid rgba(138, 90, 42, 0.25);
  border-radius: 4px;
  color: var(--card-ink);
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 600ms ease, transform 600ms ease;
}
.diorama[data-phase-kind="night"] ~ .story-column .beat,
.story-column .chapter[data-chapter-phase-kind-value="night"] .beat {
  background: var(--card-surface-night);
}

.beat[data-visible="true"] { opacity: 1; transform: translateY(0); }

.beat-prose {
  font-family: var(--font-body);
  font-size: 1.35rem;
  line-height: 1.6;
}
.beat-prose .player-name {
  font-weight: 700;
}

.vote-reveal {
  margin-top: 1rem;
  opacity: 0;
  transform: translateY(6px) scale(0.98);
  transition: opacity 900ms ease 700ms, transform 900ms ease 700ms;
  font-weight: 500;
}
.beat-nomination[data-visible="true"] .vote-reveal {
  opacity: 1;
  transform: translateY(0) scale(1);
}
.vote-reveal-onTheBlock { color: var(--evil-crimson); }
.vote-reveal-tied       { color: var(--card-flourish); }

.beat-storyteller-note {
  border: 2px solid var(--card-flourish);
  background: var(--card-surface);
  padding: 2rem;
}
.storyteller-subject {
  font-family: var(--font-display);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--card-flourish);
  margin-bottom: 0.5rem;
}
.storyteller-quote {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 1.3rem;
  line-height: 1.6;
  margin: 0;
  padding-left: 1rem;
  border-left: 3px solid var(--card-flourish);
}

.beat-execution,
.beat-night-kill,
.beat-exile,
.beat-death-other {
  display: flex;
  align-items: center;
  gap: 1.25rem;
}
.beat-execution .beat-prose,
.beat-night-kill .beat-prose,
.beat-exile .beat-prose,
.beat-death-other .beat-prose {
  flex: 1;
  min-width: 0;
}

.reveal-token {
  flex-shrink: 0;
  position: relative;
  width: 140px;
  padding-bottom: 14px;
  opacity: 0;
  transform: scale(0.92);
  transition: opacity 700ms ease 200ms, transform 700ms ease 200ms;
}
.reveal-token-frame {
  width: 140px;
  height: 140px;
  border-radius: 50%;
  overflow: hidden;
  position: relative;
  background: #f4e9d0;
  box-shadow:
    0 2px 8px rgba(28, 18, 4, 0.18),
    0 10px 24px rgba(28, 18, 4, 0.22),
    inset 0 0 0 1px rgba(138, 90, 42, 0.35);
}
.reveal-token-frame::after {
  content: "";
  position: absolute;
  inset: 5px;
  border-radius: 50%;
  border: 1px solid rgba(138, 90, 42, 0.4);
  pointer-events: none;
}
.reveal-token-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.reveal-token-empty .reveal-token-frame {
  background: rgba(138, 90, 42, 0.08);
}
.reveal-token-label {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  white-space: nowrap;
  padding: 0.4rem 0.85rem;
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #f5e7c3;
  background: #120a02;
  border: 1px solid rgba(245, 231, 195, 0.3);
  border-radius: 2px;
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.45),
    inset 0 0 0 1px rgba(12, 6, 0, 0.9);
  pointer-events: none;
}
.beat[data-visible="true"] .reveal-token {
  opacity: 1;
  transform: scale(1);
}

@media (max-width: 520px) {
  .beat-execution,
  .beat-night-kill,
  .beat-exile,
  .beat-death-other {
    gap: 1rem;
  }
  .reveal-token,
  .reveal-token-frame {
    width: 112px;
  }
  .reveal-token-frame {
    height: 112px;
  }
  .reveal-token-label {
    font-size: 0.65rem;
    padding: 0.3rem 0.65rem;
    letter-spacing: 0.14em;
  }
}
.reveal-alignment {
  font-family: var(--font-display);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  margin-top: 0.4rem;
  opacity: 0.85;
}

/* Finale */
.story-finale { padding: 14vh 0 18vh; text-align: center; }
.finale-eyebrow {
  font-family: var(--font-display);
  font-size: 0.75rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--card-ink);
  opacity: 0.7;
}
.finale-headline {
  font-family: var(--font-decorative);
  font-size: clamp(2rem, 5vw, 3.5rem);
  letter-spacing: 0.06em;
  margin-top: 0.6rem;
  color: var(--card-ink);
  opacity: var(--reveal-progress, 0);
}
.story-finale[data-winner="evil"] .finale-headline {
  color: #ef5a5a;
  text-shadow:
    0 0 2px rgba(0, 0, 0, 0.95),
    0 0 6px rgba(0, 0, 0, 0.85),
    0 0 22px rgba(60, 0, 0, 0.85),
    0 2px 14px rgba(0, 0, 0, 0.7);
}
.story-finale[data-winner="good"] .finale-headline {
  color: var(--good-gold);
}
.players-heading {
  font-family: var(--font-decorative);
  font-size: clamp(1.6rem, 3.6vw, 2.4rem);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  margin-top: 10vh;
  color: #f5e7c3;
  text-shadow:
    0 0 2px rgba(0, 0, 0, 0.95),
    0 0 8px rgba(0, 0, 0, 0.8),
    0 2px 14px rgba(0, 0, 0, 0.6);
}
.players-credits {
  list-style: none;
  padding: 0;
  margin: 5vh auto 0;
  max-width: 560px;
  color: #f5e7c3;
  text-shadow:
    0 0 2px rgba(0, 0, 0, 0.95),
    0 0 8px rgba(0, 0, 0, 0.75),
    0 2px 12px rgba(0, 0, 0, 0.55);
}
.credit {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 1.6rem 0;
  text-align: left;
}
.credit-role {
  font-family: var(--font-decorative);
  font-size: clamp(1.15rem, 2.2vw, 1.5rem);
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.credit-leader {
  flex: 1;
  min-width: 1.5rem;
  overflow: hidden;
  white-space: nowrap;
  opacity: 0.65;
}
.credit-leader::after {
  content: ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .";
  letter-spacing: 0.35em;
}
.credit-player {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2.2vw, 1.5rem);
  letter-spacing: 0.08em;
  white-space: nowrap;
}
.finale-closing {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 1.1rem;
  margin-top: 4vh;
  color: var(--card-ink);
}
.finale-back { margin-top: 4vh; }

/* Grimoire gallery. Clickable thumbnails in the finale. */
.grimoire-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.25rem;
  max-width: 560px;
  margin: 5vh auto 2vh;
}
.grimoire-thumb {
  position: relative;
  display: block;
  padding: 0.5rem;
  margin: 0;
  background: var(--card-surface);
  border: 1px solid rgba(138, 90, 42, 0.35);
  border-radius: 4px;
  cursor: pointer;
  transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;
  box-shadow: 0 2px 6px rgba(28, 18, 4, 0.18);
}
.grimoire-thumb:hover,
.grimoire-thumb:focus-visible {
  transform: translateY(-2px);
  border-color: rgba(138, 90, 42, 0.7);
  box-shadow: 0 6px 18px rgba(28, 18, 4, 0.28);
  outline: none;
}
.grimoire-thumb-img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 2px;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}
.grimoire-thumb-caption {
  display: block;
  margin-top: 0.6rem;
  font-family: var(--font-display);
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--card-ink);
  opacity: 0.75;
}

/* Full-size grimoire modal with gallery navigation. */
.grimoire-modal[hidden] { display: none; }
.grimoire-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1.5rem 1.5rem 1rem;
  background: rgba(8, 4, 2, 0.9);
  backdrop-filter: blur(4px);
  animation: grimoire-modal-fade 180ms ease-out;
  touch-action: pan-y pinch-zoom;
}
@keyframes grimoire-modal-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.grimoire-modal-figure {
  margin: 0;
  max-width: min(92vw, 1200px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  pointer-events: none;
  flex: 1 1 auto;
  min-height: 0;
  justify-content: center;
}
.grimoire-modal-figure img {
  max-width: min(92vw, 1200px);
  max-height: calc(100vh - 11rem);
  object-fit: contain;
  border-radius: 4px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6);
  pointer-events: auto;
  user-select: none;
  -webkit-user-drag: none;
}
.grimoire-modal-caption {
  font-family: var(--font-display);
  font-size: 0.75rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #f5e7c3;
  opacity: 0.85;
  pointer-events: none;
}
.grimoire-modal-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 2.5rem;
  height: 2.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.75rem;
  line-height: 1;
  padding: 0 0 4px;
  color: #f5e7c3;
  background: rgba(20, 12, 6, 0.75);
  border: 1px solid rgba(245, 231, 195, 0.3);
  border-radius: 50%;
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease;
  z-index: 2;
}
.grimoire-modal-close:hover,
.grimoire-modal-close:focus-visible {
  background: rgba(40, 24, 12, 0.95);
  border-color: rgba(245, 231, 195, 0.6);
  outline: none;
}

.grimoire-modal-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 3rem;
  height: 3rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.25rem;
  font-family: var(--font-body);
  line-height: 1;
  color: #f5e7c3;
  background: rgba(20, 12, 6, 0.65);
  border: 1px solid rgba(245, 231, 195, 0.25);
  border-radius: 50%;
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease, transform 150ms ease;
  z-index: 2;
  padding: 0 0 6px;
}
.grimoire-modal-nav-prev { left: 1.25rem; }
.grimoire-modal-nav-next { right: 1.25rem; }
.grimoire-modal-nav:hover,
.grimoire-modal-nav:focus-visible {
  background: rgba(40, 24, 12, 0.95);
  border-color: rgba(245, 231, 195, 0.55);
  outline: none;
}
.grimoire-modal-nav:active {
  transform: translateY(-50%) scale(0.96);
}

.grimoire-modal-thumbs {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.75rem;
  padding: 0.25rem 0;
  flex: 0 0 auto;
}
.grimoire-modal-thumb {
  width: 64px;
  height: 64px;
  padding: 0;
  margin: 0;
  background: transparent;
  border: 2px solid rgba(245, 231, 195, 0.25);
  border-radius: 3px;
  overflow: hidden;
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 150ms ease, border-color 150ms ease, transform 150ms ease;
}
.grimoire-modal-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.grimoire-modal-thumb:hover,
.grimoire-modal-thumb:focus-visible {
  opacity: 1;
  border-color: rgba(245, 231, 195, 0.55);
  outline: none;
}
.grimoire-modal-thumb.is-current {
  opacity: 1;
  border-color: var(--good-gold, #d8a441);
  box-shadow: 0 0 0 1px rgba(216, 164, 65, 0.5);
}

@media (max-width: 640px) {
  .grimoire-modal { padding: 1rem 0.5rem 0.5rem; }
  .grimoire-modal-nav { width: 2.25rem; height: 2.25rem; font-size: 1.75rem; padding: 0 0 4px; }
  .grimoire-modal-nav-prev { left: 0.5rem; }
  .grimoire-modal-nav-next { right: 0.5rem; }
  .grimoire-modal-figure img { max-height: calc(100vh - 10rem); }
  .grimoire-modal-thumb { width: 52px; height: 52px; }
}

/* Mobile */
@media (max-width: 640px) {
  .candle-arc { height: 26vh; bottom: 2vh; }
  .candle { --candle-w: 52px; }
  .candle-label { font-size: 0.68rem; }
  .story-column { padding: 0 1rem; }
  .beat { padding: 1.25rem 1rem; }
  .story-title { font-size: 2.5rem; }
}

/* Reduced motion: drop kinetic transitions but keep state changes. */
@media (prefers-reduced-motion: reduce) {
  .diorama .sun, .diorama .moon { transition: none; }
  .candle-flame { animation: none; filter: drop-shadow(0 0 6px rgba(255, 180, 80, 0.95)) drop-shadow(0 0 14px rgba(255, 110, 60, 0.55)); }
  .candle-flame::after { animation: none; opacity: 0.6; transform: translateX(-50%); }
  .diorama .bat { animation: none; display: none; }
  .cloud { animation: none; }
  .star-burst { animation: none; }
  .candle[data-effect-smoke] .candle-smoke { animation: none; opacity: 0; }
  .beat { transition: opacity 200ms ease; transform: none !important; }
  .candle { transition: opacity 200ms ease; }
  .chapter-title { translate: none !important; scale: 1 !important; opacity: 1 !important; transition: none !important; will-change: auto; }
}

/* Page background while on a story page. Reduce nav glare against sky */
.story-page { isolation: isolate; overflow-x: clip; }
