/* The Haunted Top 200. One accent, pumpkin orange, on the sepia and silver of an old projection
   booth. Antique gold is for hairlines only, never for data. */

:root {
  --night: #09080a;
  --panel: rgba(11, 10, 8, 0.86);
  --line: #3e392f;
  --gold: #c8a45c;
  --film: #14110d;
  --tungsten: 255, 226, 176;
  --ink: #efeae1;
  --ink-2: #bdb7ac;
  --ink-3: #989388;
  --ember: #ff8a1f;
  --ember-ink: #1a0d02;
  --blood: #d11a26;
  --bone: #d8d0bd;
  --stone-ink: #14151a;
  --serif: "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
}

* { box-sizing: border-box; }

html, body { height: 100%; margin: 0; }

html { background: var(--night); }

body {
  background: radial-gradient(ellipse 90% 70% at 76% 0%, #2d2922 0%, #161410 46%, var(--night) 100%);
  color: var(--ink);
  font: 14px/1.4 var(--serif);
  overflow-x: hidden;
  overflow-y: auto;
  position: relative;
}

button, select { font: inherit; color: inherit; }

button:focus-visible, select:focus-visible { outline: 2px solid var(--ember); outline-offset: 2px; }

.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.boot, .tomb-message { padding: 32px; font-size: 16px; font-style: italic; color: var(--ink-2); }
.tomb-message h1 { margin: 0 0 12px; }
.boot-error { color: #ffb4a8; font-style: normal; }

/* Backdrop ------------------------------------------------------------------ */

#backdrop { position: fixed; inset: 0; overflow: hidden; pointer-events: none; }

/* A conic slice from the lens, with streaks in it, fading out with distance. */
.beam {
  --ray: var(--tungsten);
  animation: beam-flicker 2.6s steps(5) infinite;
  background: conic-gradient(from 214deg at var(--bx) var(--by),
    transparent 0deg, rgba(var(--ray), 0.03) 5deg, rgba(var(--ray), 0.1) 13deg, rgba(var(--ray), 0.05) 19deg,
    rgba(var(--ray), 0.14) 28deg, rgba(var(--ray), 0.07) 36deg, rgba(var(--ray), 0.12) 45deg,
    rgba(var(--ray), 0.04) 55deg, transparent 68deg);
  inset: 0;
  -webkit-mask-image: radial-gradient(circle var(--reach) at var(--bx) var(--by), #000 0, rgba(0, 0, 0, 0.5) 45%, transparent 100%);
  mask-image: radial-gradient(circle var(--reach) at var(--bx) var(--by), #000 0, rgba(0, 0, 0, 0.5) 45%, transparent 100%);
  position: absolute;
}
@keyframes beam-flicker { 0%, 100% { opacity: 1; } 40% { opacity: 0.93; } 60% { opacity: 0.98; } 80% { opacity: 0.9; } }

.motes { inset: 0; position: absolute; }

.blood-moon .beam { --ray: 214, 42, 44; }

/* The dark edges both reference images share. */
#backdrop .vignette { background: radial-gradient(ellipse at 55% 42%, transparent 52%, rgba(0, 0, 0, 0.6) 100%); inset: 0; position: absolute; }

#backdrop::before,
#backdrop::after {
  content: "";
  position: absolute;
  left: -30%;
  right: -30%;
  bottom: -8%;
  height: 46%;
  background:
    radial-gradient(ellipse 30% 42% at 22% 70%, rgba(214, 206, 188, 0.1), transparent 70%),
    radial-gradient(ellipse 34% 36% at 62% 82%, rgba(214, 206, 188, 0.08), transparent 70%),
    radial-gradient(ellipse 22% 30% at 88% 66%, rgba(214, 206, 188, 0.07), transparent 70%);
  animation: fog-a 46s ease-in-out infinite alternate;
}

#backdrop::after { bottom: -14%; animation: fog-b 62s ease-in-out infinite alternate; opacity: 0.8; }

@keyframes fog-a { to { transform: translateX(14%); } }
@keyframes fog-b { from { transform: translateX(10%); } to { transform: translateX(-12%); } }

/* Layout -------------------------------------------------------------------- */

#root { position: relative; height: 100%; }

.app {
  display: grid;
  height: max(100vh, 660px);
  grid-template-columns: minmax(0, 1fr) 308px;
  grid-template-rows: auto minmax(0, 1fr) auto;
  grid-template-areas: "top top" "stage side" "foot foot";
  gap: 8px 12px;
  overflow: clip; /* a sinking stage must not bring up a scrollbar */
  padding: 12px 14px 8px;
}

.top { grid-area: top; padding-right: 232px; position: relative; z-index: 5; }

/* The title is a quote, so it carries its credit, and it's a button: click it and the phone rings. */
.masthead { align-items: baseline; display: flex; flex-wrap: wrap; gap: 0 14px; }
.title-call {
  background: none;
  border: 0;
  cursor: pointer;
  letter-spacing: inherit;
  padding: 0;
  text-align: left;
  text-shadow: inherit;
  text-transform: inherit;
  transition: color 0.2s, text-shadow 0.2s;
}
.title-call:hover { color: #ff5a4f; text-shadow: 0 0 14px rgba(209, 26, 38, 0.7); }
.title-credit { color: var(--ink-2); font-size: 13px; font-style: italic; }

/* Two rows, one width: the lower row sets it and the view buttons stretch to match. */
.nav { display: inline-grid; margin-top: 8px; max-width: 100%; row-gap: 7px; }
.pills.views { display: grid; gap: 4px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.views .pill { font-size: 13.5px; padding: 8px 10px; }

h1 {
  margin: 0;
  font-size: clamp(19px, 2.6vw, 27px);
  font-weight: 400;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  text-shadow: 0 0 14px rgba(255, 255, 255, 0.22);
}

.headline { margin: 7px 0 2px; color: var(--ink-2); font-style: italic; font-size: 15px; min-height: 21px; }

.controls { align-items: center; display: flex; flex-wrap: wrap; gap: 8px 12px; justify-content: space-between; position: relative; }

/* The filters hide in a cursed book, and open over the stage without moving anything. */
.book-toggle { align-items: center; display: inline-flex; gap: 7px; letter-spacing: 0.08em; }
.book-toggle[aria-expanded="true"] { border-color: var(--gold); color: var(--gold); }
.book-icon { fill: #3b2a1a; stroke: var(--gold); stroke-width: 1; }
.book-icon .book-mark { fill: none; stroke: var(--gold); stroke-width: 0.8; }

.book {
  animation: book-open 0.26s ease-out both;
  background: linear-gradient(100deg, #1c1610, #120e09 48%, #070504 50%, #120e09 52%, #1a140e);
  border: 1px solid rgba(200, 164, 92, 0.6);
  border-radius: 5px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.75);
  left: 0;
  max-width: calc(100vw - 32px);
  padding: 11px 16px 10px;
  position: absolute;
  top: calc(100% + 7px);
  transform-origin: 50% 0;
  width: 470px;
}
.book[hidden] { display: none; }
@keyframes book-open { from { opacity: 0; transform: perspective(800px) rotateX(-34deg); } }
.book-title { color: var(--gold); font-size: 13px; letter-spacing: 0.14em; margin: 0; text-transform: uppercase; }
.book-sub { color: var(--ink-2); font-size: 12.5px; font-style: italic; margin: 0 0 9px; }
.book-fields { display: grid; gap: 9px 14px; grid-template-columns: 1fr 1fr; margin-bottom: 9px; }
.book-fields select { max-width: none; width: 100%; }
.pills { display: flex; gap: 4px; }

.pill {
  background: rgba(24, 21, 17, 0.9);
  border: 1px solid var(--line);
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  letter-spacing: 0.1em;
  padding: 6px 11px;
  text-transform: uppercase;
  transition: background 0.15s, border-color 0.15s;
}

.pill:hover { border-color: var(--ember); }

.pill[aria-pressed="true"] {
  background: var(--ember);
  border-color: var(--ember);
  box-shadow: 0 0 12px rgba(255, 138, 31, 0.5);
  color: var(--ember-ink);
  font-weight: 700;
}

.views .pill[aria-pressed="true"] {
  background: rgba(255, 138, 31, 0.16);
  box-shadow: none;
  color: var(--ember);
  font-weight: 400;
}

.control { display: flex; flex-direction: column; gap: 1px; }
.control span { color: var(--ink-2); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; }

select {
  background: #191612;
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 4px 6px;
}

/* Stage --------------------------------------------------------------------- */

.stage { grid-area: stage; min-height: 0; min-width: 0; position: relative; transition: transform 1.2s ease-in, opacity 1.2s; }
.stage.sunken { opacity: 0.25; transform: translateY(46px) scale(0.97); }
.stage svg { display: block; }

.stage-note { bottom: 4px; color: var(--ink-2); font-size: 11.5px; font-style: italic; left: 42px; margin: 0; pointer-events: none; position: absolute; right: 56px; text-shadow: 0 0 3px #000, 0 0 6px #000; z-index: 2; }

/* Each bank is two fog tiles wide, so sliding it one tile along lands exactly where it began. The
   tile is real turbulence, drawn once and only moved, so the fog costs next to nothing to animate.
   --fog-clock keeps its place when the stage redraws. */
.ground-fog {
  --fog-tile: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1100' height='240'%3E%3Cfilter id='f' x='0' y='0' width='100%25' height='100%25' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.0055 .021' numOctaves='4' seed='11' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .87 0 0 0 0 .87 0 0 0 0 .83 2.1 0 0 0 -.62'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23f)'/%3E%3C/svg%3E");
  bottom: 0;
  left: 0;
  -webkit-mask-image: linear-gradient(to top, #000 26%, rgba(0, 0, 0, 0.72) 48%, rgba(0, 0, 0, 0.26) 74%, transparent 100%);
  mask-image: linear-gradient(to top, #000 26%, rgba(0, 0, 0, 0.72) 48%, rgba(0, 0, 0, 0.26) 74%, transparent 100%);
  overflow: hidden;
  pointer-events: none;
  position: absolute;
  right: 0;
}

.ground-fog::before {
  animation: fog-breathe 11s ease-in-out var(--fog-clock, 0s) infinite alternate;
  background: linear-gradient(to top, rgba(216, 216, 210, 0.62), rgba(216, 216, 210, 0.34) 26%, transparent 66%);
  content: "";
  inset: 0;
  position: absolute;
  transform-origin: 50% 100%;
}

.ground-fog i {
  animation: fog-roll 44s linear var(--fog-clock, 0s) infinite;
  background: var(--fog-tile) 0 100% / 50% 100% repeat-x;
  bottom: 0;
  display: block;
  height: 100%;
  left: 0;
  opacity: 0.8;
  position: absolute;
  width: 200%;
  will-change: transform;
}

.ground-fog i:nth-of-type(2) { animation: fog-roll-back 29s linear var(--fog-clock, 0s) infinite; background-position: -37% 100%; height: 76%; opacity: 0.85; }
.ground-fog i:nth-of-type(3) { animation-duration: 17s; background-position: -71% 100%; height: 52%; opacity: 0.9; }

/* Curls of mist lifting off the ground between the graves. */
.ground-fog b {
  animation: fog-curl 13s ease-out infinite;
  background: radial-gradient(ellipse at 50% 62%, rgba(226, 225, 218, 0.5), rgba(226, 225, 218, 0.18) 48%, transparent 70%);
  bottom: 4%;
  height: 52%;
  opacity: 0;
  position: absolute;
  width: 24%;
}

@keyframes fog-roll { to { transform: translateX(-50%); } }
@keyframes fog-roll-back { from { transform: translateX(-50%); } to { transform: translateX(0); } }
@keyframes fog-breathe { from { opacity: 0.78; transform: scaleY(0.9); } to { opacity: 1; transform: scaleY(1.14); } }
@keyframes fog-curl {
  0% { opacity: 0; transform: translate(-6%, 22%) scale(0.72, 0.6); }
  24% { opacity: 1; }
  100% { opacity: 0; transform: translate(16%, -58%) scale(1.5, 1.4); }
}

/* Laid over the fog, with a dark edge so they read through it and across the moon. */
.yard-labels { left: 0; pointer-events: none; position: absolute; top: 0; }
.yard-labels text { paint-order: stroke; stroke: rgba(8, 7, 5, 0.88); stroke-linejoin: round; stroke-width: 3px; }
.yard-labels .axis text { stroke-width: 2px; } /* 3px clogs so small a figure */
.ground-fog ~ .stage-note { background: rgba(8, 7, 5, 0.62); border-radius: 3px; color: #f4efe3; padding: 1px 7px; right: auto; text-shadow: none; }
.stage-note.left { left: 44px; right: 230px; }

.axis line { stroke: rgba(255, 255, 255, 0.09); stroke-width: 1; }
.axis text { fill: var(--ink-2); font-size: 11px; paint-order: stroke; stroke: rgba(9, 8, 10, 0.7); stroke-width: 2px; }
.axis .axis-title { fill: var(--ink-2); font-size: 12px; font-style: italic; }

.moon-seas { fill: #7d7564; opacity: 0.62; }
.moon-rays { fill: none; opacity: 0.32; stroke: #fff; stroke-width: 1.1; }
.moon-crater { fill: #f4ecd8; opacity: 0.55; }
.moon-cloud { animation: moon-cloud 90s ease-in-out infinite alternate; fill: #100e0b; opacity: 0.38; }
@keyframes moon-cloud { from { transform: translateX(-34px); } to { transform: translateX(46px); } }
.blood-moon .moon-body { filter: sepia(1) saturate(6) hue-rotate(-42deg) brightness(0.68); }
.blood-moon .sky-glow { opacity: 0.4; }

.spooky-tree path { fill: none; stroke: #060504; stroke-linecap: round; }
.spooky-tree .tree-trunk { fill: #060504; stroke: none; }
.spooky-tree .tree-mouth { fill: #1d0f04; stroke: none; }
.tree-eye { animation: tree-eye 7s ease-in-out infinite; fill: #e08a2c; opacity: 0.62; }
@keyframes tree-eye { 0%, 86%, 100% { opacity: 0.62; } 90% { opacity: 0.12; } 94% { opacity: 0.5; } }

.hill-far { fill: #141210; }
.hill-near { fill: #0e0c0a; }
.house-body { fill: #080706; }
.window { fill: #ffb24d; opacity: 0.75; }
.window.dim { opacity: 0.22; }
.window.flicker { animation: window-flicker 6s steps(1) infinite; }
@keyframes window-flicker { 0%, 62%, 66%, 100% { opacity: 0.85; } 64% { opacity: 0.1; } 80% { opacity: 0.25; } }
.tree path { fill: none; stroke: #060504; stroke-linecap: round; }

.fence { fill: none; stroke: #221e19; stroke-width: 2.5; }
.ground { fill: #0b0a08; }
.yard { -webkit-mask-image: linear-gradient(90deg, transparent, #000 2.5%, #000 97.5%, transparent); mask-image: linear-gradient(90deg, transparent, #000 2.5%, #000 97.5%, transparent); }

/* Unspooled film ------------------------------------------------------------ */

.film-ribbon { filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.75)); }
.film-ribbon path { fill: none; stroke-linejoin: round; }
.film-edge { stroke: #0e0c09; }
.film-holes { stroke: #d9cdb1; }
.film-base { stroke: #17120c; }
.film-picture { stroke: #6e4f2c; }
.film-light { stroke: #c79b5e; stroke-opacity: 0.55; }

.stone { cursor: pointer; outline: none; }
.stone-body { animation: stone-rise 0.6s cubic-bezier(0.2, 0.9, 0.3, 1.05) both; transform-box: fill-box; transform-origin: 50% 100%; }

@keyframes stone-rise { from { opacity: 0; transform: scaleY(0.04); } }

.shape { fill: var(--stone); stroke: #0a0b0f; stroke-width: 1; transition: fill 0.18s; }
.shade { pointer-events: none; }
.stone-side { fill: #2c2925; pointer-events: none; stroke: #0a0b0f; stroke-width: 0.8; transition: fill 0.18s; }
.stone-rim { fill: none; pointer-events: none; stroke-width: 1.4; }
.stone-panel { fill: var(--stone); fill-opacity: 0.66; pointer-events: none; stroke-width: 1.3; transition: fill 0.18s; }
.crack { fill: none; pointer-events: none; stroke: rgba(10, 11, 15, 0.62); stroke-linejoin: round; stroke-width: 1.2; }
.crack-lip { fill: none; pointer-events: none; stroke: rgba(255, 255, 255, 0.24); stroke-linejoin: round; stroke-width: 0.9; }
.plinth { fill: #5f5a51; pointer-events: none; stroke: #0a0908; }
.mound { fill: #171410; pointer-events: none; }

.stone-rank { fill: var(--stone-ink); font-weight: 700; pointer-events: none; }
.stone-title { fill: var(--stone-ink); font-weight: 600; pointer-events: none; }
.stone-title.outside { fill: var(--ink-2); font-weight: 400; }
.stone-lip { fill: rgba(255, 255, 255, 0.34); font-weight: 600; pointer-events: none; }
.stone-value { fill: var(--ink); font-style: italic; font-weight: 700; pointer-events: none; }

.stone:hover .shape, .stone:hover .stone-panel { fill: #e7e3da; }
.stone:focus-visible .shape, .slice:focus-visible .slice-shape {
  filter: drop-shadow(0 0 1px #fff) drop-shadow(0 0 2px #fff);
  stroke: #000;
  stroke-width: 2.5;
}
.stone.is-selected .shape, .stone.is-selected .stone-panel { fill: var(--ember); }
.stone.is-selected .stone-side { fill: #7a3f08; }
.stone.is-selected .stone-rank, .stone.is-selected .stone-title:not(.outside) { fill: var(--ember-ink); }
.stone-value.is-selected { fill: var(--ember); }
.stone.cursed:not(.is-selected) .stone-body { animation: stone-rise 0.6s both, tremble 9s 2s infinite; }

@keyframes tremble {
  0%, 94%, 100% { transform: rotate(0); }
  95% { transform: rotate(-1.4deg); }
  96.5% { transform: rotate(1.4deg); }
  98% { transform: rotate(-0.8deg); }
}

.stone-body.head-spin { animation: head-spin 1.4s ease-in-out; transform-box: fill-box; transform-origin: 50% 50%; }
@keyframes head-spin { to { transform: rotate(360deg); } }

.stone-body.thing { animation: thing 0.34s steps(2) 4; }
@keyframes thing {
  from { transform: skewX(-7deg) translateX(-5px); filter: hue-rotate(40deg); }
  to { transform: skewX(7deg) translateX(5px); filter: hue-rotate(-40deg); }
}

/* Pops up through the soil, claws at the air for a moment, then slowly sinks back. */
.hand { animation: hand-visit 5.4s linear both; pointer-events: none; }
@keyframes hand-visit {
  0% { animation-timing-function: cubic-bezier(0.2, 1.4, 0.45, 1); transform: translateY(132px); }
  11% { transform: translateY(0); }
  36% { animation-timing-function: ease-in; transform: translateY(0); }
  100% { transform: translateY(132px); }
}

.hand-fingers { animation: claw 1.7s 0.9s ease-in-out infinite; transform-box: fill-box; transform-origin: 50% 100%; }
@keyframes claw { 50% { transform: scaleY(0.82) rotate(-3deg); } }

.bone { fill: none; stroke: var(--bone); stroke-linecap: round; stroke-linejoin: round; stroke-width: 5; }
.bone-edge { fill: none; stroke: #16140f; stroke-linecap: round; stroke-linejoin: round; stroke-width: 7.4; }
.palm { fill: var(--bone); stroke: #16140f; stroke-width: 1.4; }
.sleeve { fill: #26221b; stroke: #0c0a08; }
.mound-torn { fill: #1d1a15; pointer-events: none; }
.dirt circle { animation: dirt 0.8s ease-out both; fill: #4a4438; pointer-events: none; }
@keyframes dirt { 0% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translate(var(--dx), calc(var(--dy) + 42px)); } }

.empty { align-items: center; display: flex; flex-direction: column; gap: 4px; height: 100%; justify-content: center; text-align: center; }
.empty p { font-size: 18px; font-style: italic; margin: 0; }
.empty .empty-note { color: var(--ink-2); font-size: 14px; margin-bottom: 12px; }

/* Swamp --------------------------------------------------------------------- */

.water { fill: rgba(38, 36, 28, 0.5); }
.medians line { stroke: rgba(239, 234, 225, 0.32); stroke-dasharray: 4 5; }
.quadrants text { fill: var(--ink-3); font-size: 11px; letter-spacing: 0.08em; }

.wisp { cursor: pointer; outline: none; }
.wisp .halo { animation: flicker 5s ease-in-out infinite; fill: rgba(var(--tungsten), 0.05); pointer-events: none; }
.wisp .core { fill: rgba(196, 184, 158, 0.16); stroke: rgba(236, 226, 204, 0.5); stroke-width: 1; transition: fill 0.15s; }
.wisp .hit { fill: transparent; }
.wisp.no-box .core { fill: none; }
.wisp.lit .core { fill: #63e6b4; stroke: #c6ffe9; }
.wisp.lit .halo { fill: rgba(84, 232, 172, 0.26); }
.wisp:hover .core { fill: #fff; }
.wisp:focus-visible .core { filter: drop-shadow(0 0 2px #fff); stroke: #000; stroke-width: 2.5; }
.wisp.is-selected .core { fill: var(--ember); stroke: #ffd2a6; }
.wisp.is-selected .halo { fill: rgba(255, 138, 31, 0.3); }
@keyframes flicker { 50% { opacity: 0.3; } }

.wisp-label { fill: var(--ink-2); font-size: 11.5px; font-style: italic; paint-order: stroke; pointer-events: none; stroke: var(--night); stroke-width: 3px; }
.selected-label { fill: var(--ember); font-size: 12.5px; font-weight: 700; }

.size-key circle { fill: none; stroke: rgba(236, 226, 204, 0.55); }
.size-key circle.hollow { stroke-dasharray: 2 2; }
.wisp.no-box .core { stroke-dasharray: 2 2; }
.swamp-scenery .tree path { stroke: #0a0907; }
.reeds { fill: none; stroke: #2a2619; stroke-linecap: round; stroke-width: 1.6; }
.size-key text { fill: var(--ink-2); font-size: 10.5px; }
.size-key .size-title { fill: var(--ink-3); font-size: 11.5px; font-style: italic; }

/* Wheel --------------------------------------------------------------------- */

.rim { fill: #120f0b; }
.rim-edge { fill: #b9b3a6; }
.sprocket { fill: #cdbf9f; }
.hub { fill: #0e0c09; stroke: #b9b3a6; stroke-width: 3; }
.hub-hole { fill: #b9b3a6; }
.hub-eye { fill: var(--ember); }
.hub-hit { cursor: pointer; fill: transparent; }
.pointer { fill: var(--ember); filter: drop-shadow(0 0 5px rgba(255, 138, 31, 0.6)); }

.slice { cursor: pointer; outline: none; }
.slice-shape { fill: var(--slice); stroke: #0a0806; stroke-width: 2; transition: fill 0.15s; }
.slice:hover .slice-shape { fill: #e7e3da; }
.slice.is-selected .slice-shape { fill: var(--ember); }
.slice-label { font-size: 11px; font-weight: 600; pointer-events: none; }
.slice.is-selected .slice-label { fill: var(--ember-ink); }

.spin-row { align-items: center; bottom: 0; display: flex; gap: 12px; justify-content: center; left: 0; position: absolute; right: 0; }

.spin-button {
  background: var(--ember);
  border: 0;
  border-radius: 4px;
  box-shadow: 0 0 14px rgba(255, 138, 31, 0.5);
  color: var(--ember-ink);
  cursor: pointer;
  flex: none;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 7px 14px;
}

.spin-button:disabled { cursor: default; opacity: 0.74; }
.spin-note { color: var(--ink-3); font-size: 11.5px; font-style: italic; }

/* Sidebar ------------------------------------------------------------------- */

/* The sidebar is a strip of film running down from the projector. Each panel is a frame. */
.side {
  background: var(--film);
  display: flex;
  flex-direction: column;
  gap: 8px;
  grid-area: side;
  margin-top: -6px;
  min-height: 0;
  padding: 8px 20px;
  position: relative;
}

.side::before, .side::after {
  --holes: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='22'%3E%3Crect x='2.5' y='5' width='9' height='12' rx='2' fill='%23cdbf9f'/%3E%3C/svg%3E");
  background: var(--holes) repeat-y;
  bottom: 0;
  content: "";
  position: absolute;
  top: 0;
  width: 14px;
}
.side::before { left: 3px; }
.side::after { right: 3px; }

.film-running .side::before, .film-running .side::after { animation: film-run 0.28s linear infinite; }
@keyframes film-run { to { background-position-y: 22px; } }

/* Wound up until a film is picked. The stage takes the strip's column while it's away. */
.side[hidden] { display: none; }
.app.reel-away { grid-template-areas: "top top" "stage stage" "foot foot"; }

/* The strip feeds down out of the projector: the film moves, and the opening it shows through
   grows behind it, so its foot arrives first. It settles in the gate with a small jolt, and the
   sprocket holes race while it runs. */
.side.reel-feed { animation: reel-feed 0.72s cubic-bezier(0.22, 0.72, 0.3, 1) both; z-index: 1; }
.side.reel-wind { animation: reel-wind 0.6s cubic-bezier(0.62, 0, 0.82, 0.42) both; pointer-events: none; z-index: 1; }
.side.reel-feed::before, .side.reel-feed::after, .side.reel-wind::before, .side.reel-wind::after { animation: film-run 0.09s linear infinite; }
.side.reel-wind::before, .side.reel-wind::after { animation-direction: reverse; }
@keyframes reel-feed {
  0% { clip-path: inset(100% 0 0); transform: translateY(-100%); }
  84% { clip-path: inset(0); transform: translateY(1.1%); }
  92% { clip-path: inset(0); transform: translateY(-0.5%); }
  100% { clip-path: inset(0); transform: none; }
}
@keyframes reel-wind {
  0% { clip-path: inset(0); transform: none; }
  12% { clip-path: inset(0); transform: translateY(0.9%); }
  100% { clip-path: inset(100% 0 0); transform: translateY(-100%); }
}

.reel-close {
  background: none;
  border: 1px solid transparent;
  border-radius: 3px;
  color: var(--ink-2);
  cursor: pointer;
  font-size: 16px;
  height: 22px;
  line-height: 1;
  padding: 0;
  position: absolute;
  right: 24px;
  top: 11px;
  width: 22px;
  z-index: 1;
}
.reel-close:hover { border-color: var(--ember); color: var(--ember); }

.card, .list { background: #0b0907; border: 1px solid rgba(200, 164, 92, 0.42); border-radius: 5px; }

.card { flex: none; padding: 9px 12px 10px; }
.card::before { color: var(--gold); content: "Now showing"; display: block; font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; }
.card h2 { color: var(--ember); font-size: 17px; font-weight: 700; line-height: 1.2; margin: 1px 0 0; padding-right: 12px; }
.card-meta { color: var(--ink-2); font-size: 12.5px; margin: 2px 0 0; }
.card-credit { color: var(--ink-2); font-size: 12.5px; font-style: italic; margin: 0 0 6px; }
.card-place { border-top: 1px solid var(--line); color: var(--ink-3); font-size: 11.5px; margin: 7px 0 0; padding-top: 5px; }

.stats { display: grid; gap: 5px 10px; grid-template-columns: 1fr 1fr; margin: 0; }
.stat dt { color: var(--ink-3); font-size: 11px; letter-spacing: 0.07em; text-transform: uppercase; }
.stat dd { font-size: 17px; font-weight: 700; line-height: 1.15; margin: 0; }
.stat dd.missing { color: var(--ink-3); font-size: 13px; font-style: italic; font-weight: 400; }
.stat dd.wordy { font-size: 13px; font-weight: 600; line-height: 1.25; }
.stat small { color: var(--ink-3); display: block; font-size: 11px; line-height: 1.2; }

.list { display: flex; flex: 1; flex-direction: column; min-height: 170px; }
.list-title { color: var(--ink-2); font-size: 11px; font-weight: 600; letter-spacing: 0.08em; margin: 0; padding: 7px 10px 4px; text-transform: uppercase; }
.rank-list { flex: 1; list-style: none; margin: 0; min-height: 0; overflow-y: auto; padding: 0 3px 4px; scrollbar-color: #3b3d46 transparent; scrollbar-width: thin; }

.row {
  align-items: baseline;
  background: none;
  border: 0;
  border-radius: 3px;
  cursor: pointer;
  display: grid;
  gap: 6px;
  grid-template-columns: 26px minmax(0, 1fr) auto;
  padding: 2px 7px;
  text-align: left;
  width: 100%;
}

.row:hover { background: rgba(255, 255, 255, 0.07); }
.row.is-selected { background: rgba(255, 138, 31, 0.16); color: var(--ember); font-weight: 700; }
.row-place { color: var(--ink-3); font-size: 11.5px; text-align: right; }
.row.is-selected .row-place { color: var(--ember); }
.row-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-value { font-style: italic; }

.footer { color: var(--ink-3); display: flex; font-size: 11.5px; gap: 14px; grid-area: foot; justify-content: space-between; padding: 0 30px 2px 22px; }
.footer span { min-width: 0; }
.link { background: none; border: 0; color: var(--ink-2); cursor: pointer; flex: none; font-size: 11.5px; padding: 0; text-decoration: underline; text-underline-offset: 2px; }
.link:hover { color: var(--ember); }

.tip {
  background: rgba(8, 7, 5, 0.96);
  border: 1px solid var(--ember);
  border-radius: 3px;
  display: none;
  flex-direction: column;
  font-size: 12.5px;
  left: 0;
  max-width: 250px;
  padding: 5px 8px;
  pointer-events: none;
  position: fixed;
  top: 0;
  z-index: 40;
}
.tip.on { display: flex; }

/* About --------------------------------------------------------------------- */

.about { align-items: center; background: rgba(3, 4, 6, 0.74); display: flex; inset: 0; justify-content: center; padding: 16px; position: fixed; z-index: 50; }
.about-panel { background: #0f0d0a; border: 1px solid var(--ember); border-radius: 4px; max-height: 100%; max-width: 620px; overflow-y: auto; padding: 16px 20px; }
.about-panel h2 { font-size: 18px; font-weight: 400; letter-spacing: 0.1em; margin: 0 0 6px; text-transform: uppercase; }
.about-panel h3 { color: var(--ember); font-size: 13px; letter-spacing: 0.08em; margin: 12px 0 4px; text-transform: uppercase; }
.about-panel p { color: var(--ink-2); margin: 0 0 7px; }
.about-panel .credit { color: var(--ink-3); font-size: 12px; }
.secrets { columns: 2; font-size: 12.5px; list-style: none; margin: 0 0 12px; padding: 0; }
.secrets li { break-inside: avoid; color: var(--ink-3); }
.secrets li.found { color: var(--ember); }

/* Creatures ----------------------------------------------------------------- */

#fx { left: 0; min-height: 100%; overflow: hidden; pointer-events: none; position: absolute; right: 0; top: 0; z-index: 30; }
.book-open .top { z-index: 31; } /* an open Book sits above the birds and everything else that creeps */
#fx > * { pointer-events: none; position: absolute; }
/* Full-window effects stay with the window. Creatures stay with the page. */
#fx > .toast, #fx > .flash, #fx > .scrawl, #fx > .static, #fx > .slashes, #fx > .ghost, #fx > .balloon,
#fx > .claw-shadow, #fx > .shape-mask, #fx > .bolt, #fx > .call, #fx > .ghostface { position: fixed; }

.rig { right: 8px; top: 0; }
.rig-glow { fill: rgba(var(--tungsten), 0.08); }
.reel-main { cursor: pointer; pointer-events: auto; }
.reel-turn { animation: reel-turn 34s linear infinite; transform-box: fill-box; transform-origin: 50% 50%; }
.reel-back .reel-turn { animation-duration: 22s; }
.reel-back { opacity: 0.72; }
.film-running .reel-turn { animation-duration: 1.2s; }
.film-running .reel-back .reel-turn { animation-duration: 0.8s; }
.film-rewinding .reel-turn { animation-direction: reverse; }
@keyframes reel-turn { to { transform: rotate(360deg); } }
.reel-spool { fill: #231e17; stroke: #0b0907; }
.reel-metal { stroke: #1d1913; stroke-width: 0.6; transition: fill 1.2s; }
.reel-rim { fill: none; stroke: #f3eee2; stroke-opacity: 0.55; }
.reel-hub { fill: #2a251d; stroke: #d8d0bd; }
.reel-pin { fill: #d8d0bd; }
.rig-film { fill: none; stroke: #17130e; stroke-width: 3; }
.rig-arm { fill: #15120e; }
.rig-body { stroke: #050403; }
.rig-trim { fill: none; stroke: var(--gold); stroke-opacity: 0.6; }
.rig-vents { fill: none; stroke: #0a0806; stroke-width: 2; }
.rig-knob { fill: #15120e; stroke: var(--gold); stroke-opacity: 0.75; }
.rig-barrel { stroke: #050403; }
.rig-lens { fill: #fff3d6; filter: drop-shadow(0 0 7px rgba(var(--tungsten), 0.95)); }
.rig.blood .reel-metal { fill: #a81b20; }
.rig.blood .rig-lens { fill: #ff8d7d; filter: drop-shadow(0 0 7px rgba(214, 42, 44, 0.95)); }
.rig.blood .rig-glow { fill: rgba(209, 26, 38, 0.2); }

.web { cursor: pointer; transform-origin: 0 0; }
.web-hit { fill: transparent; pointer-events: all; }
.threads { fill: none; pointer-events: none; stroke: rgba(226, 228, 236, 0.46); stroke-width: 0.9; }
.web.shake { animation: web-shake 0.5s ease-out; }
.web.occupied { animation: web-sway 3s ease-in-out infinite; }
@keyframes web-shake { 25% { transform: rotate(1.6deg); } 60% { transform: rotate(-1.2deg); } }
@keyframes web-sway { 50% { transform: rotate(0.7deg); } }

.spider { cursor: pointer; left: 0; pointer-events: auto !important; top: 0; transition: opacity 0.3s; }
.spider.gone { opacity: 0; pointer-events: none !important; }
.spider-body, .spider-head { fill: #0c0c10; stroke: #a9a9ad; stroke-width: 0.7; }
.spider-mark { fill: var(--blood); }
.spider-eye { fill: var(--blood); }
.leg { fill: none; stroke: #c8c8cc; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.3; transform-box: view-box; transform-origin: 50% 50%; }
.spider.walking .leg.a { animation: leg-a 0.2s linear infinite alternate; }
.spider.walking .leg.b { animation: leg-b 0.2s linear infinite alternate; }
@keyframes leg-a { from { transform: rotate(-7deg); } to { transform: rotate(7deg); } }
@keyframes leg-b { from { transform: rotate(7deg); } to { transform: rotate(-7deg); } }

.bat { left: 0; top: 0; }
.bat path, .bat ellipse { fill: #0b0b0f; stroke: #5e4a30; stroke-width: 0.5; }
.bat-wing { animation: flap var(--flap, 0.2s) ease-in-out infinite alternate; transform-box: view-box; transform-origin: 50% 50%; }
.bat.bird path, .bat.bird ellipse { fill: #030304; stroke: #3b3b42; }
@keyframes flap { to { transform: scaleY(-0.45); } }

.eyes { cursor: pointer; display: flex; gap: 7px; pointer-events: auto !important; }
.eyes:not(.placed), .book-open .eyes { display: none; }
.eyes i { animation: blink 7s ease-in-out infinite; background: var(--blood); border-radius: 50%; box-shadow: 0 0 7px 2px rgba(209, 26, 38, 0.6); display: block; height: 5px; width: 9px; }
.eyes.shut i { height: 1px; opacity: 0.2; }
@keyframes blink { 0%, 93%, 100% { transform: scaleY(1); } 96% { transform: scaleY(0.08); } }

.raven { cursor: pointer; fill: #050506; pointer-events: auto !important; stroke: #6a6a72; stroke-width: 0.35; }
.raven.flying { pointer-events: none !important; }
.raven-leg { fill: none; stroke: #6a6a72; stroke-width: 0.8; }
.raven-eye { fill: var(--blood); stroke: none; }
.raven-wing { display: none; }
.raven.flying .raven-wing { animation: raven-flap 0.17s ease-in-out infinite alternate; display: block; transform-box: fill-box; transform-origin: 100% 100%; }
.raven.flying .raven-leg { display: none; }
@keyframes raven-flap { to { transform: rotate(-52deg) scaleY(0.72); } }

.pumpkin { cursor: pointer; pointer-events: auto !important; }
.pumpkin-rib { fill: #7e3d0a; stroke: #0c0d11; }
.pumpkin-core { fill: #94480d; stroke: #0c0d11; }
.pumpkin-stem { fill: #4a5a2c; }
.pumpkin-face { fill: #1a0d02; transition: fill 0.4s; }
.pumpkin.lit .pumpkin-face { fill: #ffd76a; filter: drop-shadow(0 0 4px #ff9b2e); }

.bog { overflow: hidden; }
.bog .bog-arm { cursor: pointer; pointer-events: auto; }
.bog .bone { stroke: #8f9378; }
.bog .palm { fill: #8f9378; }
.bog .sleeve { fill: #1d1f16; }

.ghost { left: 0; top: 0; }
.ghost path:first-child { fill: rgba(232, 236, 240, 0.8); }
.ghost-eye { fill: #0b0c10; }

.shape-mask { cursor: pointer; left: 0; pointer-events: auto !important; top: 0; }
.mask-face { fill: #e9e6da; stroke: #5f5c52; }
.mask-hair { fill: #2b2219; }
.mask-hole { fill: #050506; }

.balloon { left: 0; top: 0; }
.balloon-skin { fill: #c9141f; }
.balloon-shine { fill: rgba(255, 255, 255, 0.4); }
.balloon-string { fill: none; stroke: #d7d4cd; stroke-width: 1; }

.slashes path { animation: slash 2.3s ease-out both; fill: none; stroke: #b3121d; stroke-dasharray: 1; stroke-linecap: round; stroke-width: 7; }
@keyframes slash { 0% { stroke-dashoffset: 1; } 15% { stroke-dashoffset: 0; opacity: 1; } 100% { stroke-dashoffset: 0; opacity: 0; } }

.claw-shadow { fill: #020203; left: 0; top: 0; }

.scrawl {
  animation: scrawl 4.2s ease-out both;
  color: #c0141f;
  font-family: "Bradley Hand", "Segoe Print", "Brush Script MT", cursive;
  font-size: clamp(44px, 11vw, 120px);
  font-weight: 700;
  left: 0;
  letter-spacing: 0.08em;
  right: 0;
  text-align: center;
  text-shadow: 0 3px 2px #4e0208, 0 0 28px rgba(209, 26, 38, 0.4);
  top: 30%;
}
.scrawl.flip { animation: scrawl-flip 0.9s ease-in-out both; }
@keyframes scrawl { 0% { opacity: 0; } 10%, 74% { opacity: 1; } 100% { opacity: 0; } }
@keyframes scrawl-flip { from { transform: scaleX(-1); } to { transform: scaleX(1); } }

.static {
  align-items: center;
  animation: static-jitter 0.1s steps(2) infinite;
  background:
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.12) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.4) 0 2px, transparent 2px 5px), #17181c;
  display: flex;
  inset: 0;
  justify-content: center;
  opacity: 0.9;
}
.static span { color: #efeae1; font-size: clamp(32px, 7vw, 74px); letter-spacing: 0.2em; text-shadow: 3px 0 rgba(255, 0, 0, 0.5), -3px 0 rgba(0, 200, 255, 0.5); }
@keyframes static-jitter { to { background-position: 0 3px, 4px 0, 0 0; } }

.flash { animation: flash 0.9s ease-out both; background: #cdd5ee; inset: 0; }
.flash.strike { animation: flash-strike 0.62s ease-out both; }
@keyframes flash-strike { 0% { opacity: 0; } 7% { opacity: 0.26; } 18% { opacity: 0.05; } 28% { opacity: 0.2; } 100% { opacity: 0; } }

.call {
  align-items: center;
  animation: call-in 0.28s ease-out both;
  background: rgba(7, 6, 4, 0.96);
  border: 1px solid var(--ember);
  border-radius: 4px;
  color: var(--ink);
  cursor: pointer;
  display: flex;
  font-size: 15px;
  font-style: italic;
  gap: 11px;
  max-width: min(460px, 92vw);
  padding: 7px 15px 7px 10px;
  pointer-events: auto !important;
  transform: translateX(-50%);
  white-space: nowrap;
  z-index: 3;
}
@keyframes call-in { from { opacity: 0; transform: translate(-50%, -14px); } }
.call.local { border-color: var(--blood); box-shadow: 0 0 20px rgba(209, 26, 38, 0.55); color: #ffb9b0; }
.call-phone { fill: #17130e; flex: none; stroke: var(--ember); stroke-width: 1.2; }
.call.ringing .call-phone { animation: ring 0.16s linear infinite alternate; }
@keyframes ring { from { transform: rotate(-9deg); } to { transform: rotate(9deg); } }
.call-dial { fill: none; }

.house.all-lit .window, .house.all-lit .window.dim, .house.all-lit .window.flicker { animation: none; fill: #ffd98a; filter: drop-shadow(0 0 5px #ffb24d); opacity: 1; }

/* His face comes up out of the dark, stays a moment and goes again. */
.ghostface {
  animation: ghostface-visit 5.2s ease-in-out both;
  left: 0;
  top: 0;
  transform-origin: 50% 50%;
}
@keyframes ghostface-visit { 0% { opacity: 0; } 36% { opacity: 1; } 62% { opacity: 1; } 100% { opacity: 0; } }
.ghost-crease { fill: none; stroke: #4d473e; stroke-linecap: round; stroke-opacity: 0.75; stroke-width: 1.1; }
.ghost-hole { fill: #020203; }
.ghost-mouth { fill: #020203; stroke: #3a0a0c; stroke-width: 1.2; }
.ghost-stare { fill: #e9e2d2; }
.ghost-blood { fill: none; stroke: #8f0d15; stroke-linecap: round; stroke-width: 2.3; }

/* The Nightmare Before Christmas: Zero in the graves. */
.zero-track { pointer-events: none; }
.zero { cursor: pointer; pointer-events: auto; }
.zero-bob { animation: zero-bob 1.8s ease-in-out infinite alternate; transform-box: fill-box; transform-origin: 50% 50%; }
@keyframes zero-bob { from { transform: translateY(-4px) rotate(3deg); } to { transform: translateY(5px) rotate(-4deg); } }
.zero-sheet, .zero-ear { filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.75)); stroke: #17171c; stroke-linejoin: round; stroke-width: 0.9; }
.zero-sheet { fill: #f8f8f4; }
.zero-ear { fill: #c9ccca; }
.zero-eye { fill: #0b0c10; }
.zero-mouth { fill: none; stroke: #0b0c10; stroke-linecap: round; stroke-width: 1; }
.zero-nose { animation: zero-nose 1.1s ease-in-out infinite alternate; fill: var(--ember); filter: drop-shadow(0 0 4px var(--ember)) drop-shadow(0 0 10px rgba(255, 138, 31, 0.85)); }
@keyframes zero-nose { from { opacity: 0.72; } }



.bolt { animation: bolt 0.56s linear both; left: 0; top: 0; }
.bolt path { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.bolt-glow { filter: blur(5px); stroke: rgba(190, 212, 255, 0.75); stroke-width: 11; }
.bolt-core { stroke: #fff; stroke-width: 2.6; }
.bolt-fork { stroke: #dbe6ff; stroke-width: 1.3; }
@keyframes bolt { 0% { opacity: 0; } 5% { opacity: 1; } 20% { opacity: 0.25; } 30% { opacity: 1; } 100% { opacity: 0; } }
@keyframes flash { 0% { opacity: 0; } 8% { opacity: 0.14; } 16% { opacity: 0.02; } 26% { opacity: 0.1; } 100% { opacity: 0; } }

.toast {
  animation: toast 3.2s ease both;
  background: rgba(7, 8, 12, 0.95);
  border: 1px solid var(--ember);
  border-radius: 3px;
  bottom: 34px;
  color: var(--ink);
  font-size: 14px;
  font-style: italic;
  left: 50%;
  max-width: min(460px, 90vw);
  padding: 7px 13px;
  transform: translateX(-50%);
}
@keyframes toast { 0% { opacity: 0; } 6%, 86% { opacity: 1; } 100% { opacity: 0; } }

.blood-moon .eyes i { box-shadow: 0 0 12px 4px rgba(209, 26, 38, 0.85); }
.blood-moon body { background: radial-gradient(ellipse 90% 70% at 70% 0%, #3a1216 0%, #16090c 46%, var(--night) 100%); }

/* Narrow sheets ------------------------------------------------------------- */

@media (max-width: 760px) {
  body { overflow-y: auto; }
  .app, .app.reel-away { grid-template-areas: "top" "stage" "side" "foot"; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 420px auto auto; height: auto; }
  .top { padding-right: 150px; }
  .rig { right: 2px; transform: scale(0.6); transform-origin: 100% 0; }
  .web { height: 110px; width: 110px; }
  .side { margin-top: 0; }
  .list { max-height: 280px; }
  .footer { flex-direction: column; gap: 3px; padding: 0 4px 4px; }
}

@media (max-width: 520px) {
  .top { padding-right: 76px; }
  .masthead { padding-right: 16px; }
  .call { white-space: normal; width: max-content; }
  .views .pill { font-size: 11.5px; padding: 8px 2px; }
  .rig { transform: scale(0.42); }
  .stage-note.left { right: 8px; }
  .spin-note { display: none; }
}

/* Still mode: reduced motion and image exports ------------------------------ */

.paused #backdrop::before, .paused #backdrop::after, .paused .beam, .paused .ground-fog i, .paused .ground-fog b, .paused .ground-fog::before, .paused .tree-eye, .paused .moon-cloud, .paused #fx *, .paused .wisp .halo, .paused .hand-fingers, .paused .window { animation-play-state: paused; }

.still *, .still *::before, .still *::after { animation: none !important; transition: none !important; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
