@charset "UTF-8";
/* =============================================================================
   css/halloween.css - ALL HALLOWS, the Halloween 2026 skin (game dates
   Oct 26 - Nov 1). Driven by js/halloween.js; the on/off rules are in
   js/halloween-rules.js.

   EVERY rule here is scoped under html.theme-halloween (or styles an element
   only the skin creates: .hw-*), so with the class off this file changes
   nothing. Loaded by index.html right after css/style.css; remove the file
   and its <link> to take the skin out.

   The palette sits over the app's own dark ground: pumpkin orange, witch
   purple, ghost green, bone. Gold stays the app's gold (bars, primary
   actions, rarity): the skin adds light and color AROUND it, so no meaning
   the app teaches changes (bar colors, stat identity colors, rarity frames
   are untouched).
   Type: names / labels / numbers Cinzel; sentences Crimson Pro 500 16px+;
   nothing new under 13px. Motion: transform + opacity on the big layers;
   the heading candle-flicker steps a few times a second. No reduced-motion
   guard (the app's motion law, design-reference v5.7 / Decision 57.3).
   ============================================================================= */

/* ---------------------------------------------------------------- tokens */
html.theme-halloween {
  --hw-pumpkin: #ff8a1f;
  --hw-pumpkin-hi: #ffb347;
  --hw-pumpkin-deep: #b34a0c;
  --hw-candle: #ffd27a;
  --hw-witch: #9b5de5;
  --hw-witch-hi: #c39bff;
  --hw-witch-deep: #24103a;
  --hw-ghost: #8dffb8;
  --hw-ghost-dim: #6fcf98;
  --hw-bone: #efe6d2;
  --hw-ink: #07030d;
  /* app tokens the skin re-tints (the tab bar's active color, the warm accent) */
  --tab-active: #ffa24a;
  --amber: #ff8a1f;
  /* the small drawn jack-o'-lantern, reused by the toast, the tab bar and the LEVEL moment */
  --hw-jack-svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 22'%3E%3Cpath d='M11.5 4c-.4-1.8.4-3.2 2-3.5l.6.9c-1 .4-1.3 1.2-1.1 2.6z' fill='%235a6a26'/%3E%3Cellipse cx='12' cy='13' rx='11' ry='8.6' fill='%23f07a12'/%3E%3Cpath d='M12 4.4c-2.4 0-3.6 3.8-3.6 8.6s1.2 8.6 3.6 8.6 3.6-3.8 3.6-8.6-1.2-8.6-3.6-8.6z' fill='none' stroke='%23a24a0a' stroke-width='.8'/%3E%3Cpath d='M6 10.5l2.8-2.6 2.2 3zM18 10.5l-2.8-2.6-2.2 3zM5 14.6c2 2.8 5 4 7 4s5-1.2 7-4l-1.6.4-.8 1.4-1.2-1-1.2 1.2-1.2-1.2-1.2 1.4-1.2-1.4-1.2 1.2-1.2-1.2-1 1z' fill='%23ffd25a'/%3E%3C/svg%3E");
  /* a cobweb in a top-left corner (mirrored for top-right) */
  --hw-web-img: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 60' fill='none' stroke='%23efe6d2' stroke-width='.75' stroke-linecap='round'%3E%3Cpath d='M0 0L60 6M0 0L52 30M0 0L30 52M0 0L6 60'/%3E%3Cpath d='M13.9 1.4Q11.5 3.6 12.1 7Q9 8.5 7 12.1Q3.6 11.5 1.4 13.9'/%3E%3Cpath d='M27.9 2.8Q22 6.5 24.2 14Q18 17 14 24.2Q6.5 22 2.8 27.9'/%3E%3Cpath d='M43.8 4.4Q34 10 38.1 22Q28 27 22 38.1Q10 34 4.4 43.8'/%3E%3Cpath d='M38.1 22L38.1 33' stroke-width='.5'/%3E%3C/svg%3E");
  /* three still bats (the bat path from js/halloween.js), for the Legacy hall's rafters */
  --hw-bats-img: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 44'%3E%3Cg fill='%2308030d'%3E%3Cpath transform='translate(6 18) scale(.62)' d='M32 9c2-4 3-6 3-8 1 3 2 5 3 6 3-1 6 0 8 3 4-4 10-7 18-7-4 3-6 7-6 12-3-2-6-2-9 0-2-2-5-2-7 0-2 2-4 5-6 8-2-3-4-6-6-8-2-2-5-2-7 0-3-2-6-2-9 0 0-5-2-9-6-12 8 0 14 3 18 7 2-3 5-4 8-3 1-1 2-3 3-6 0 2 1 4 3 8z'/%3E%3Cpath transform='translate(62 2) scale(.46) rotate(-8 32 15)' d='M32 9c2-4 3-6 3-8 1 3 2 5 3 6 3-1 6 0 8 3 4-4 10-7 18-7-4 3-6 7-6 12-3-2-6-2-9 0-2-2-5-2-7 0-2 2-4 5-6 8-2-3-4-6-6-8-2-2-5-2-7 0-3-2-6-2-9 0 0-5-2-9-6-12 8 0 14 3 18 7 2-3 5-4 8-3 1-1 2-3 3-6 0 2 1 4 3 8z'/%3E%3Cpath transform='translate(118 22) scale(.52) rotate(10 32 15)' d='M32 9c2-4 3-6 3-8 1 3 2 5 3 6 3-1 6 0 8 3 4-4 10-7 18-7-4 3-6 7-6 12-3-2-6-2-9 0-2-2-5-2-7 0-2 2-4 5-6 8-2-3-4-6-6-8-2-2-5-2-7 0-3-2-6-2-9 0 0-5-2-9-6-12 8 0 14 3 18 7 2-3 5-4 8-3 1-1 2-3 3-6 0 2 1 4 3 8z'/%3E%3C/g%3E%3C/svg%3E");
}

/* The painted jack (assets/halloween/jack.png) replaces the drawn one in every
   CSS use once it has loaded on this device (halloween.js adds .hw-art-jack). */
/* (the up-to-11 pass) --hw-jack-img paints the small CSS jacks; --hw-jack-mask is the shape of the
   <img> jacks, for the shading overlay masked to them. Both start as the drawn one. */
html.theme-halloween { --hw-jack-img: var(--hw-jack-svg); --hw-jack-mask: var(--hw-jack-svg); }
html.theme-halloween.hw-art-jack { --hw-jack-img: url("../assets/halloween/jack.png"); --hw-jack-mask: url("../assets/halloween/jack.png"); }
/* round 3: the small CSS jacks take the painted icon jack (v3_jack_icon_B, 64px), the clearest at 13-24px */
html.theme-halloween.hw-art-jacksmall { --hw-jack-img: url("../assets/halloween/jack_small.png"); }
.hw-jack--art { object-fit: contain; }

/* ---------------------------------------------------------------- the night sky */
/* The app background, re-lit: witch-purple overhead, a ghost-green pool, an
   ember horizon low down. Same layered-radial build as style.css's body. */
html.theme-halloween body {
  background:
    radial-gradient(ellipse 160% 50% at 50% 0%, rgba(62, 20, 96, 0.9) 0%, transparent 55%),
    radial-gradient(ellipse 70% 35% at 12% 38%, rgba(44, 14, 74, 0.55) 0%, transparent 60%),
    radial-gradient(ellipse 70% 32% at 88% 58%, rgba(16, 64, 46, 0.32) 0%, transparent 62%),
    radial-gradient(ellipse 100% 40% at 50% 50%, rgba(10, 6, 22, 0.6) 0%, transparent 70%),
    radial-gradient(ellipse 130% 42% at 50% 100%, rgba(150, 58, 10, 0.42) 0%, transparent 62%),
    linear-gradient(180deg, #07030d 0%, #0a0514 35%, #090611 65%, #0d0708 100%);
}

/* The ambient layers (built by halloween.js). Behind the app: */
.hw-ambient { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.hw-moon {
  position: absolute; top: -18px; right: 64px; width: 74px; height: 74px; border-radius: 50%; opacity: 0.9;
  background:
    radial-gradient(circle at 62% 30%, rgba(160, 120, 70, 0.35) 0 5px, transparent 6px),
    radial-gradient(circle at 34% 62%, rgba(160, 120, 70, 0.3) 0 7px, transparent 8px),
    radial-gradient(circle at 70% 70%, rgba(160, 120, 70, 0.22) 0 4px, transparent 5px),
    radial-gradient(circle at 38% 34%, #fff7de 0%, #f6e2b0 45%, #d2a862 100%);
  box-shadow: 0 0 34px 8px rgba(255, 214, 150, 0.28), 0 0 120px 46px rgba(255, 150, 60, 0.14);
}
/* Inside the app the cards cover the sky, so the moon becomes only its warm
   halo behind the header's frosted glass (the disc shows on the profile and PIN screens). */
html.theme-halloween body:has(#screen-app.active) .hw-moon {
  top: -120px; right: -60px; width: 260px; height: 220px; opacity: 1; box-shadow: none;
  background: radial-gradient(ellipse at center, rgba(255, 214, 150, 0.2) 0%, rgba(255, 150, 60, 0.08) 42%, transparent 70%);
}
/* Two fog banks drifting at different speeds: wide strips of soft ellipses,
   panned with transform only (each strip is two screens wide and repeats). */
.hw-fog { position: absolute; left: 0; width: 200%; will-change: transform; }
.hw-fog--a {
  top: 18%; height: 46%;
  background:
    radial-gradient(ellipse 18% 30% at 12% 50%, rgba(170, 150, 210, 0.10), transparent 70%),
    radial-gradient(ellipse 22% 26% at 36% 40%, rgba(140, 220, 180, 0.06), transparent 70%),
    radial-gradient(ellipse 16% 34% at 62% 60%, rgba(170, 150, 210, 0.09), transparent 70%),
    radial-gradient(ellipse 22% 28% at 86% 45%, rgba(170, 150, 210, 0.08), transparent 70%);
  background-size: 50% 100%; background-repeat: repeat-x;
  animation: hw-drift 95s linear infinite;
}
.hw-fog--b {
  top: 46%; height: 40%;
  background:
    radial-gradient(ellipse 20% 32% at 20% 50%, rgba(160, 140, 200, 0.09), transparent 70%),
    radial-gradient(ellipse 24% 30% at 70% 40%, rgba(130, 210, 170, 0.06), transparent 70%);
  background-size: 50% 100%; background-repeat: repeat-x;
  animation: hw-drift 140s linear infinite reverse;
}
/* The low fog (#29): a bank lying along the bottom of every screen. */
.hw-fog-floor { position: absolute; left: 0; right: 0; bottom: 0; height: 38%;
  background: linear-gradient(0deg, rgba(120, 96, 160, 0.26) 0%, rgba(100, 80, 140, 0.12) 40%, transparent 100%); }
.hw-fog-floor i { position: absolute; left: 0; bottom: 0; width: 200%; height: 100%; will-change: transform;
  background:
    radial-gradient(ellipse 14% 40% at 10% 85%, rgba(190, 175, 225, 0.16), transparent 70%),
    radial-gradient(ellipse 18% 45% at 32% 95%, rgba(150, 230, 190, 0.10), transparent 70%),
    radial-gradient(ellipse 15% 38% at 58% 90%, rgba(190, 175, 225, 0.14), transparent 70%),
    radial-gradient(ellipse 18% 42% at 82% 92%, rgba(190, 175, 225, 0.12), transparent 70%);
  background-size: 50% 100%; background-repeat: repeat-x;
  animation: hw-drift 70s linear infinite; }
@keyframes hw-drift { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-50%, 0, 0); } }

/* In front of the app (z 3: above the screens, below every popup, sheet,
   toast and moment): a thin mist over the tab bar, the bats, the peek. */
.hw-front { position: fixed; inset: 0; z-index: 3; pointer-events: none; overflow: hidden; }
.hw-front * { pointer-events: none; }
/* The Log Workout / Meal / Steps sheets live inside #screen-app (z 1), under this
   layer: while one is open the mist, bats and peek step aside (the Fable review). */
html.theme-halloween body:has(.modal-overlay.modal--open, .wk-layer.open) .hw-front { visibility: hidden; }
.hw-mist { position: absolute; left: 0; right: 0; bottom: calc(var(--nav-height) - 10px); height: 64px; overflow: hidden; }
.hw-mist i { position: absolute; left: 0; bottom: 0; width: 200%; height: 100%; will-change: transform;
  background:
    radial-gradient(ellipse 16% 50% at 15% 100%, rgba(200, 185, 235, 0.13), transparent 70%),
    radial-gradient(ellipse 20% 46% at 45% 100%, rgba(160, 235, 200, 0.08), transparent 70%),
    radial-gradient(ellipse 16% 52% at 78% 100%, rgba(200, 185, 235, 0.12), transparent 70%);
  background-size: 50% 100%; background-repeat: repeat-x;
  animation: hw-drift 55s linear infinite reverse; }

/* Bats: a flight (translate across) > a bob (up and down) > the svg (wings flap). */
.hw-bat-flight { position: absolute; left: 0; width: var(--s, 28px); height: calc(var(--s, 28px) * 0.47);
  animation: hw-fly-ltr var(--dur, 8s) linear var(--delay, 0s) both; will-change: transform; }
.hw-bat-flight.hw-rtl { animation-name: hw-fly-rtl; }
.hw-bat-bob { width: 100%; height: 100%; animation: hw-bob 1.3s ease-in-out infinite alternate; }
.hw-bat { display: block; width: 100%; height: 100%; overflow: visible;
  fill: #0a0410; filter: drop-shadow(0 0 3px rgba(255, 138, 31, 0.75)) drop-shadow(0 0 1px rgba(255, 210, 160, 0.6)); }
.hw-bat-w { transform-origin: 50% 40%; animation: hw-flap 0.17s ease-in-out infinite alternate; }
.hw-rtl .hw-bat { transform: scaleX(-1); }
/* the painted raven (flyRaven): square box, mirrored when it flies right to left */
.hw-raven-flight { height: var(--s, 58px); }
.hw-raven { display: block; width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(0 0 3px rgba(255, 150, 60, 0.45)); }
.hw-rtl .hw-raven { transform: scaleX(-1); }
@keyframes hw-fly-ltr { from { transform: translate3d(-15vw, 0, 0); } to { transform: translate3d(112vw, -10vh, 0); } }
@keyframes hw-fly-rtl { from { transform: translate3d(112vw, 0, 0); } to { transform: translate3d(-15vw, -10vh, 0); } }
@keyframes hw-bob { from { transform: translateY(0); } to { transform: translateY(var(--bob, 14px)); } }
@keyframes hw-flap { from { transform: scaleY(1); } to { transform: scaleY(0.35); } }

/* The peeking pumpkin (#111): rises from just above the tab bar, looks, ducks. */
.hw-peek-clip { position: absolute; bottom: var(--nav-height); width: 62px; height: 46px; overflow: hidden; }
.hw-peek-clip.hw-peek--l { left: 26px; }
.hw-peek-clip.hw-peek--r { right: 26px; }
.hw-peek { width: 62px; height: 58px; transform: translateY(100%); transition: transform 0.75s cubic-bezier(0.3, 1.35, 0.5, 1); }
.hw-peek--l .hw-peek { transform: translateY(100%) rotate(10deg); }
.hw-peek--r .hw-peek { transform: translateY(100%) rotate(-10deg); }
.hw-peek-clip.is-up .hw-peek { transform: translateY(16%) rotate(0deg); }
.hw-peek .hw-jack { width: 100%; height: 100%; display: block; filter: drop-shadow(0 0 10px rgba(255, 138, 31, 0.55)); }
/* the painted sprite (a head cut at the chin): a wider box; it rises until its eyes clear the bar */
.hw-peek-clip.hw-peek--sprite { width: 84px; height: 56px; }
.hw-peek--sprite .hw-peek { width: 84px; height: 67px; }
.hw-peek-clip.hw-peek--sprite.is-up .hw-peek { transform: translateY(6%) rotate(0deg); }
.hw-peek-img { display: block; width: 100%; height: 100%; object-fit: contain; object-position: center top; filter: drop-shadow(0 0 8px rgba(255, 138, 31, 0.5)); }
.hw-peek .hw-jack-face { animation: hw-candle-op 2.2s steps(1, end) infinite; }

/* ---------------------------------------------------------------- the frame */
/* The header and the tab bar: an ember edge instead of the plain gold line. */
html.theme-halloween .app-header { border-bottom-color: rgba(255, 138, 31, 0.32); box-shadow: 0 1px 14px rgba(255, 110, 20, 0.14); }
html.theme-halloween .header-logo { filter: drop-shadow(0 0 8px rgba(255, 128, 30, 0.45)); }
html.theme-halloween .bottom-nav { border-top-color: rgba(155, 93, 229, 0.28); }
html.theme-halloween .nav-btn.active::before {
  background: linear-gradient(90deg, transparent, var(--hw-pumpkin), transparent);
  box-shadow: 0 0 10px rgba(255, 138, 31, 0.85), 0 3px 16px rgba(255, 138, 31, 0.4);
}
/* The drawn tab icons, re-tinted (the painted set, when listed, replaces them). */
html.theme-halloween .nav-btn .nav-icon {
  filter: brightness(0) saturate(100%) invert(46%) sepia(12%) saturate(900%) hue-rotate(225deg) brightness(92%) contrast(86%);
}
html.theme-halloween .nav-btn.active .nav-icon {
  filter: brightness(0) saturate(100%) invert(64%) sepia(83%) saturate(1900%) hue-rotate(345deg) brightness(101%) contrast(101%) drop-shadow(0 0 6px rgba(255, 138, 31, 0.75));
}
html.theme-halloween .nav-btn.hw-painted-tab .nav-icon { filter: brightness(1.12); opacity: 0.86; }   /* round 3: the painted set is dark, so less dimmed than the drawn icons */
html.theme-halloween .nav-btn.hw-painted-tab.active .nav-icon { filter: drop-shadow(0 0 6px rgba(255, 138, 31, 0.75)); opacity: 1; }
html.theme-halloween .nav-btn.active span { text-shadow: 0 0 10px rgba(255, 138, 31, 0.55); }
/* a tiny lantern hangs by the active tab's icon */
html.theme-halloween .nav-btn.active::after {
  content: ""; position: absolute; top: 7px; left: calc(50% + 12px); width: 13px; height: 12px;
  background: var(--hw-jack-img) center / contain no-repeat; pointer-events: none;
  filter: drop-shadow(0 0 4px rgba(255, 138, 31, 0.8));
}
/* the Realm tab's ember dot sits top-right; the lantern moves left there */
html.theme-halloween .nav-btn.active[data-tab="realm"]::after { left: calc(50% - 25px); }

/* ---------------------------------------------------------------- candle-lit headings */
/* The big gold headings burn like candles: an orange halo that gutters in a
   few discrete steps (steps() = a few repaints a second, not every frame). */
html.theme-halloween :is(.qs-section-label, .rd-arrival-title, .gr-sog-title, .gr-char-name, .gr-comp-name,
  .qs-companion-name, .hl-title, .lg-section-header, .rm-title, .gr-equip-title, .lg-hall-name,
  .profile-prompt, .pin-player-name, .player-name, .gr-popup-title, .qs-hud-level, .rd-strip-label,
  .rm-notice-title, .lg-popup-title) {
  animation: hw-candle 3.4s steps(1, end) infinite;
}
/* These three have entrance animations in style.css (awk-rise / awk-title-bloom /
   lh-up, timings copied from there): the flicker chains on AFTER the entrance,
   so the boss nameplate and the Legacy title still rise in (the Fable review). */
html.theme-halloween .mn-eyebrow { animation: awk-rise 0.7s ease-out 0.4s backwards, hw-candle 3.4s steps(1, end) 1.1s infinite; }
html.theme-halloween .mn-title { animation: awk-title-bloom 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.8s backwards, hw-candle 3.4s steps(1, end) 1.7s infinite; }
html.theme-halloween .mn-title--threat { animation-delay: 0.6s, 1.5s; }   /* style.css: the boss nameplate starts 0.2s sooner */
html.theme-halloween .lh-title { animation: lh-up 1s 0.2s both, hw-candle 3.4s steps(1, end) 1.2s infinite; }
html.theme-halloween :is(.qs-section-label, .gr-equip-title, .lg-section-header, .hl-title, .qs-hud-level):nth-of-type(2n) { animation-delay: -1.3s; }
@keyframes hw-candle {
  0%   { text-shadow: 0 0 8px rgba(255, 138, 31, 0.55), 0 0 18px rgba(255, 100, 20, 0.25); }
  14%  { text-shadow: 0 0 6px rgba(255, 138, 31, 0.40), 0 0 13px rgba(255, 100, 20, 0.16); }
  22%  { text-shadow: 0 0 10px rgba(255, 150, 40, 0.70), 0 0 22px rgba(255, 100, 20, 0.32); }
  41%  { text-shadow: 0 0 7px rgba(255, 138, 31, 0.50), 0 0 16px rgba(255, 100, 20, 0.22); }
  57%  { text-shadow: 0 0 9px rgba(255, 160, 50, 0.62), 0 0 20px rgba(255, 100, 20, 0.30); }
  71%  { text-shadow: 0 0 5px rgba(255, 138, 31, 0.34), 0 0 11px rgba(255, 100, 20, 0.14); }
  83%  { text-shadow: 0 0 9px rgba(255, 150, 40, 0.66), 0 0 21px rgba(255, 100, 20, 0.30); }
  100% { text-shadow: 0 0 8px rgba(255, 138, 31, 0.55), 0 0 18px rgba(255, 100, 20, 0.25); }
}
@keyframes hw-candle-op { 0% { opacity: 1; } 18% { opacity: 0.78; } 30% { opacity: 1; } 55% { opacity: 0.88; } 70% { opacity: 0.7; } 82% { opacity: 1; } }

/* ---------------------------------------------------------------- cards */
/* The required tier sections keep the gold label (gold = act here) but their
   left edge turns ember, and the active glow is lantern light. */
html.theme-halloween .qs-section--required .qs-section-header { box-shadow: inset 3px 0 0 0 #d9701a; }
html.theme-halloween .qs-section--active .qs-section-header { box-shadow: inset 3px 0 0 0 var(--hw-pumpkin), 0 0 18px rgba(255, 120, 20, 0.18); }
html.theme-halloween .qs-section--optional .qs-section-header { box-shadow: inset 3px 0 0 0 rgba(155, 93, 229, 0.6); }

/* Cobweb corners, on cards whose corner pseudo-element is free (checked in
   the sealed screen run: ::after unused, the card already positioned). The
   web is drawn in bone at low opacity; it never takes a tap. */
html.theme-halloween :is(.rd-arrival-card, .gr-sog-card, .gr-comp-card, .gr-character-cluster)::after {
  content: ""; display: block; position: absolute; top: 0; left: 0; width: 46px; height: 46px; z-index: 3;
  background: var(--hw-web-img) top left / contain no-repeat; opacity: 0.42; pointer-events: none;
}
/* top-right on the cards whose left corner holds a label */
html.theme-halloween .gr-character-cluster::after { left: auto; right: 0; transform: scaleX(-1); }
/* the Site of Grace title sits close to its corner: a smaller web, clear of the words */
html.theme-halloween .gr-sog-card::after { width: 26px; height: 26px; }
/* The companion card: a purple ghost-light edge; the progress card: an ember one.
   (No boss card is recolored here: only the Reaper's own card, by [data-hw-face], below.) */
html.theme-halloween .qs-companion-card { border-color: rgba(155, 93, 229, 0.38); }
html.theme-halloween .qs-progress-hud { border-color: rgba(255, 138, 31, 0.28); }

/* The Site of Grace keeps its warm sanctuary; a ghost-green breath joins the flame. */
html.theme-halloween .gr-sog-card { box-shadow: 0 0 22px rgba(141, 255, 184, 0.08), 0 4px 20px rgba(0, 0, 0, 0.6); }

/* ---------------------------------------------------------------- the profile and PIN screens */
html.theme-halloween .logo-tree { filter: drop-shadow(0 0 26px rgba(255, 120, 30, 0.45)) drop-shadow(0 0 60px rgba(155, 93, 229, 0.25)); }
html.theme-halloween .player-card { border-color: rgba(255, 138, 31, 0.5); box-shadow: 0 4px 24px rgba(0, 0, 0, 0.5), 0 0 20px rgba(255, 120, 20, 0.35); }
html.theme-halloween .player-card-vignette { background: linear-gradient(180deg, rgba(36, 16, 58, 0.15) 20%, transparent 40%, rgba(10, 4, 12, 0.88) 100%); }
html.theme-halloween .profile-footer-divider { background: linear-gradient(90deg, transparent, rgba(255, 138, 31, 0.5), transparent); }
html.theme-halloween .profile-prompt::before { background: var(--hw-pumpkin-deep); }
html.theme-halloween .pin-portrait { border-color: rgba(255, 138, 31, 0.6); box-shadow: 0 0 20px rgba(255, 120, 20, 0.3); }
html.theme-halloween .pin-dot.filled { background: var(--hw-pumpkin); border-color: var(--hw-pumpkin); box-shadow: 0 0 8px rgba(255, 138, 31, 0.6); }

/* ---------------------------------------------------------------- the Rune toast (#33) */
/* The rune diamond becomes a little jack-o'-lantern; the ember flick and a big
   earn's embers become a pumpkin seed and candy corn. Same timing, same words. */
html.theme-halloween .rt-toast { border-color: rgba(255, 138, 31, 0.6); background: linear-gradient(180deg, #1a1018 0%, #0c070f 100%); }
html.theme-halloween .rt-toast.rt-big { border-color: rgba(255, 170, 70, 0.85); }
html.theme-halloween .rt-toast .rt-rune { width: 15px; height: 14px; transform: none; background: var(--hw-jack-img) center / contain no-repeat; filter: drop-shadow(0 0 3px rgba(255, 138, 31, 0.7)); }
html.theme-halloween .rt-toast.rt-ash .rt-rune { filter: grayscale(1) brightness(0.8); box-shadow: none; }
html.theme-halloween .rt-toast .rt-flick { width: 4px; height: 6px; margin-top: -3px; border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
  background: linear-gradient(180deg, #fff5dc, #e9d8a8); box-shadow: 0 0 4px rgba(255, 220, 160, 0.6); }
html.theme-halloween .rt-toast .rt-embers i { width: 5px; height: 7px; border-radius: 0; box-shadow: none;
  clip-path: polygon(50% 100%, 0 0, 100% 0);
  background: linear-gradient(180deg, #fffbe8 0 30%, #ff9a1f 30% 68%, #ffd23f 68% 100%); }
/* the burst thrown from the toast (built by halloween.js; WAAPI moves each bit) */
.hw-burst { position: fixed; z-index: 5601; width: 0; height: 0; pointer-events: none; }
.hw-burst i { position: absolute; left: 0; top: 0; opacity: 0; will-change: transform, opacity; }
.hw-burst .hw-seed { width: 5px; height: 8px; margin: -4px 0 0 -2.5px; border-radius: 50% 50% 50% 50% / 62% 62% 38% 38%;
  background: linear-gradient(180deg, #fffaf0 0%, #eadbb0 100%); box-shadow: 0 0 3px rgba(255, 230, 180, 0.5); }
.hw-burst .hw-corn { width: 7px; height: 9px; margin: -4.5px 0 0 -3.5px; clip-path: polygon(50% 100%, 0 0, 100% 0);
  background: linear-gradient(180deg, #fffbe8 0 30%, #ff9a1f 30% 68%, #ffd23f 68% 100%); }

/* ---------------------------------------------------------------- the LEVEL moment */
/* Lantern light under the portrait, an ember ring, a jack-o'-lantern at its foot. */
html.theme-halloween .mn-overlay.mn-levelup {
  background: radial-gradient(ellipse 85% 55% at 50% 30%, #2a1424 0%, #120914 55%, #050307 100%);
}
html.theme-halloween .glv-mo-ring circle { stroke: var(--hw-pumpkin-hi); filter: drop-shadow(0 0 4px rgba(255, 138, 31, 0.7)); }
html.theme-halloween .glv-mo-port::after {
  content: ""; position: absolute; right: -16px; bottom: -12px; width: 44px; height: 40px;
  background: var(--hw-jack-img) center / contain no-repeat;
  filter: drop-shadow(0 0 8px rgba(255, 138, 31, 0.8));
  animation: hw-candle-op 2.2s steps(1, end) infinite, glv-pop 1s cubic-bezier(0.2, 0.8, 0.2, 1) 0.6s backwards;
}
html.theme-halloween .glv-band::before, html.theme-halloween .glv-band::after { background: linear-gradient(90deg, transparent, rgba(255, 138, 31, 0.75), transparent); }
/* the other moments' flare picks up the same lantern warmth */
html.theme-halloween .mn-overlay:not(.mn-levelup) { background: radial-gradient(ellipse at 50% 42%, #1e1020 0%, #0c0710 48%, #050307 100%); }

/* ---------------------------------------------------------------- the pumpkin boss's face (#18) */
/* Only on the Quests boss card whose portrait is the Halloween boss
   (halloween.js sets data-hw-face from the HP bar: lit / cracked / guttering / smashed). */
html.theme-halloween .qs-boss-strip[data-hw-face]:not(.qs-boss-strip--rage) { border-color: rgba(255, 138, 31, 0.55); box-shadow: 0 0 26px rgba(255, 110, 20, 0.35), 0 8px 32px rgba(0, 0, 0, 0.8); }
.hw-face { position: absolute; inset: 0; pointer-events: none; }
.hw-face-glow { position: absolute; inset: 0; mix-blend-mode: screen;
  background: radial-gradient(ellipse 30% 44% at 50% 58%, rgba(255, 170, 60, 0.5), rgba(255, 110, 20, 0.16) 55%, transparent 75%);
  animation: hw-candle-op 2.4s steps(1, end) infinite; }
/* each fissure drawn twice: a dark split, and the candle's light leaking out of it */
.hw-face-cracks { position: absolute; inset: 0; width: 100%; height: 100%; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.hw-crk-d { stroke: rgba(12, 4, 0, 0.92); stroke-width: 7; }
.hw-crk-g { stroke: #ffc46a; stroke-width: 2.2; filter: drop-shadow(0 0 4px rgba(255, 140, 30, 0.95)); }
.hw-face-cracks .hw-shard { fill: rgba(6, 2, 0, 0.9); }
.hw-crk-g .hw-shard { fill: none; stroke: none; }
.hw-face-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center top; }
[data-hw-face="cracked"] .hw-face-glow { opacity: 0.75; }
[data-hw-face="guttering"] .hw-face-glow { animation: hw-gutter 1.6s steps(1, end) infinite; }
[data-hw-face="guttering"] .qs-boss-portrait-wrap > img { filter: saturate(0.75) brightness(0.82); }
[data-hw-face="smashed"] .hw-face-glow { display: none; }
[data-hw-face="smashed"] .qs-boss-portrait-wrap > img { filter: grayscale(0.7) brightness(0.55) contrast(1.1); }
[data-hw-face="guttering"] .hw-crk-g { stroke: #ffa443; animation: hw-gutter 1.6s steps(1, end) infinite; }
[data-hw-face="smashed"] .hw-crk-d { stroke-width: 9; }
[data-hw-face="smashed"] .hw-crk-g { stroke: rgba(150, 130, 110, 0.55); stroke-width: 1.6; filter: none; }
@keyframes hw-gutter { 0% { opacity: 0.55; } 12% { opacity: 0.15; } 20% { opacity: 0.5; } 46% { opacity: 0.08; } 52% { opacity: 0.45; } 80% { opacity: 0.25; } }

/* ---------------------------------------------------------------- All Hallows + Hollow's Eve (#95) */
/* The once-per-device moment (halloween.js showMoment). z 7500: under the
   app's moments (7600) so one can never be buried by this one. */
.hw-arrival {
  position: fixed; inset: 0; z-index: 7500; overflow: hidden; color-scheme: dark;
  display: flex; align-items: center; justify-content: center; text-align: center;
  background: linear-gradient(180deg, #120624 0%, #1c0a2a 38%, #0d0612 72%, #050306 100%);
  animation: hw-fade-in 0.6s ease-out both; cursor: pointer;
  user-select: none; -webkit-user-select: none;
}
.hw-arrival.is-closing { opacity: 0; transition: opacity 0.55s ease; pointer-events: none; }
.hw-arrival *, .hw-arrival *::before, .hw-arrival *::after { box-sizing: border-box; }
.hw-arr-sky { position: absolute; inset: 0; pointer-events: none; }
.hw-arr-moon { position: absolute; top: 7%; right: 9%; width: 120px; height: 120px; border-radius: 50%;
  background:
    radial-gradient(circle at 64% 30%, rgba(160, 120, 70, 0.32) 0 9px, transparent 10px),
    radial-gradient(circle at 32% 62%, rgba(160, 120, 70, 0.28) 0 13px, transparent 14px),
    radial-gradient(circle at 72% 72%, rgba(160, 120, 70, 0.2) 0 7px, transparent 8px),
    radial-gradient(circle at 38% 34%, #fff8e2 0%, #f7e0a6 45%, #d39a4e 100%);
  box-shadow: 0 0 60px 14px rgba(255, 210, 140, 0.32), 0 0 200px 80px rgba(255, 140, 50, 0.18);
  animation: hw-rise 1.6s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
.hw-arr-stars { position: absolute; inset: 0 0 40% 0; opacity: 0.8;
  background:
    radial-gradient(1.2px 1.2px at 12% 18%, #fff 50%, transparent 51%), radial-gradient(1px 1px at 28% 8%, #fff 50%, transparent 51%),
    radial-gradient(1.4px 1.4px at 46% 22%, #fff 50%, transparent 51%), radial-gradient(1px 1px at 62% 12%, #fff 50%, transparent 51%),
    radial-gradient(1.2px 1.2px at 8% 40%, #fff 50%, transparent 51%), radial-gradient(1px 1px at 36% 36%, #fff 50%, transparent 51%),
    radial-gradient(1.3px 1.3px at 58% 44%, #fff 50%, transparent 51%), radial-gradient(1px 1px at 20% 52%, #fff 50%, transparent 51%),
    radial-gradient(1px 1px at 52% 4%, #fff 50%, transparent 51%), radial-gradient(1.2px 1.2px at 4% 8%, #fff 50%, transparent 51%);
  animation: hw-twinkle 3.2s steps(1, end) infinite; }
.hw-arr-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0.55; pointer-events: none; }
/* the horizon: two dark hills and a dead tree line, in pure gradients */
.hw-arr-hills { position: absolute; left: -10%; right: -10%; bottom: 0; height: 30%; pointer-events: none;
  background:
    radial-gradient(ellipse 60% 55% at 22% 100%, #050208 0 99%, transparent 100%),
    radial-gradient(ellipse 55% 48% at 80% 100%, #07030b 0 99%, transparent 100%),
    linear-gradient(0deg, rgba(255, 110, 20, 0.0) 0%, rgba(255, 110, 20, 0.12) 60%, transparent 100%); }
.hw-arr-fog { position: absolute; left: 0; right: 0; bottom: 0; height: 42%; pointer-events: none; overflow: hidden; }
.hw-arr-fog i { position: absolute; left: 0; bottom: 0; width: 200%; height: 100%;
  background:
    radial-gradient(ellipse 14% 40% at 12% 90%, rgba(200, 185, 235, 0.22), transparent 70%),
    radial-gradient(ellipse 18% 44% at 34% 96%, rgba(150, 235, 195, 0.12), transparent 70%),
    radial-gradient(ellipse 16% 40% at 60% 92%, rgba(200, 185, 235, 0.2), transparent 70%),
    radial-gradient(ellipse 18% 44% at 84% 96%, rgba(200, 185, 235, 0.16), transparent 70%);
  background-size: 50% 100%; background-repeat: repeat-x; animation: hw-drift 40s linear infinite; will-change: transform; }
.hw-arr-fog i + i { opacity: 0.7; animation-duration: 62s; animation-direction: reverse; bottom: 8%; }
/* three bats wheel across the moon */
.hw-arr-bats { position: absolute; top: 10%; right: 6%; width: 160px; height: 140px; pointer-events: none; }
.hw-arr-bats .hw-bat { position: absolute; width: 34px; height: 16px; fill: #07020c; filter: drop-shadow(0 0 2px rgba(255, 170, 80, 0.55)); }
.hw-arr-bats .hw-bat:nth-child(1) { animation: hw-wheel 6s linear infinite; }
.hw-arr-bats .hw-bat:nth-child(2) { animation: hw-wheel 7.5s linear -2.4s infinite; width: 26px; height: 12px; }
.hw-arr-bats .hw-bat:nth-child(3) { animation: hw-wheel 9s linear -5s infinite reverse; width: 22px; height: 10px; }
.hw-arr-bats .hw-bat-w { animation-duration: 0.2s; }
@keyframes hw-wheel {
  0% { transform: translate(10px, 60px) scaleX(1); } 25% { transform: translate(80px, 10px) scaleX(1); }
  50% { transform: translate(140px, 70px) scaleX(-1); } 75% { transform: translate(60px, 120px) scaleX(-1); }
  100% { transform: translate(10px, 60px) scaleX(1); }
}
/* the painted graveyard valley along the bottom (the drawn hills stay behind it) */
.hw-arr-banner { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 34%; object-fit: cover; object-position: 50% 60%; pointer-events: none;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 34%); mask-image: linear-gradient(180deg, transparent 0%, #000 34%);
  animation: hw-fade-in 1.4s ease 0.2s both; }
.hw-arr-banner + .hw-arr-hills { display: none; }
/* a painted backdrop brings its own sky: the drawn moon steps aside */
.hw-arrival:has(.hw-arr-art) .hw-arr-moon { display: none; }
/* the column */
.hw-arr-in { position: relative; z-index: 2; width: 100%; max-width: 420px; padding: 24px 28px calc(28px + env(safe-area-inset-bottom, 0px)); display: flex; flex-direction: column; align-items: center; }
.hw-arr-jack { position: relative; width: 150px; height: 140px; animation: hw-rise 1.1s cubic-bezier(0.2, 0.8, 0.2, 1) 0.25s both; }
.hw-arr-jack .hw-jack { position: relative; z-index: 1; width: 100%; height: 100%; display: block; filter: drop-shadow(0 8px 22px rgba(0, 0, 0, 0.8)); }
.hw-arr-jack .hw-jack-face { animation: hw-candle-op 2s steps(1, end) infinite; }
.hw-arr-halo { position: absolute; left: 50%; top: 56%; width: 300px; height: 300px; margin: -150px 0 0 -150px; border-radius: 50%; z-index: 0;
  background: radial-gradient(circle, rgba(255, 150, 40, 0.38) 0%, rgba(255, 110, 20, 0.14) 38%, transparent 66%);
  animation: hw-candle-op 2.6s steps(1, end) infinite; }
.hw-arr-k { margin-top: 18px; font: 700 13px/1.3 'Cinzel', serif; letter-spacing: 0.32em; text-transform: uppercase; color: var(--hw-ghost, #8dffb8);
  text-shadow: 0 0 12px rgba(141, 255, 184, 0.45); animation: hw-up 0.8s ease 0.7s both; }
.hw-arr-t { margin-top: 8px; font: 900 42px/1.05 'Cinzel', serif; letter-spacing: 0.06em; text-transform: uppercase; color: #ffb347;
  text-shadow: 0 0 18px rgba(255, 138, 31, 0.65), 0 0 46px rgba(255, 90, 10, 0.35), 0 2px 0 #4a1a02;
  animation: hw-up 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) 0.85s both, hw-candle 3.4s steps(1, end) 2s infinite; }
.hw-arr-rule { margin: 16px 0 14px; width: 200px; height: 1px; position: relative; animation: hw-up 0.8s ease 1s both;
  background: linear-gradient(90deg, transparent, rgba(255, 138, 31, 0.8), transparent); }
.hw-arr-rule i { position: absolute; left: 50%; top: -6px; width: 13px; height: 12px; margin-left: -6.5px; background: var(--hw-jack-img, none) center / contain no-repeat; }
.hw-arr-lines { display: flex; flex-direction: column; gap: 6px; }
.hw-arr-p { margin: 0; font: 500 18px/1.38 'Crimson Pro', Georgia, serif; color: #ece3cf; max-width: 330px; animation: hw-up 0.9s ease 1.15s both; }
.hw-arr-d { margin-top: 14px; font: 700 13px/1.3 'Cinzel', serif; letter-spacing: 0.22em; text-transform: uppercase; color: #c39bff; animation: hw-up 0.8s ease 1.3s both; }
.hw-arr-btn { margin-top: 26px; min-width: 230px; min-height: 48px; padding: 12px 22px; border-radius: 8px; cursor: pointer;
  font: 700 14px/1 'Cinzel', serif; letter-spacing: 0.18em; text-transform: uppercase; color: #ffd27a;
  background: linear-gradient(160deg, #22121a, #120a10); border: 2px solid rgba(255, 138, 31, 0.75);
  box-shadow: 0 0 20px rgba(255, 120, 20, 0.35), inset 0 1px 0 rgba(255, 220, 160, 0.08);
  animation: hw-up 0.8s ease 1.5s both; -webkit-tap-highlight-color: transparent; }
.hw-arr-btn:active { transform: scale(0.97); }
/* With the reel listed the main button plays it first (Nick, Oct 25): a play mark,
   a little tighter so "Watch & Enter the Night" sits on one line at 360px, and a
   quiet sound line under it */
.hw-arr-btn.hw-arr-btn--reel { display: inline-flex; align-items: center; justify-content: center; gap: 10px; max-width: 100%;
  font-size: 13px; letter-spacing: 0.1em; line-height: 1.2; }
.hw-arr-btn--reel i { flex-shrink: 0; width: 0; height: 0; border-style: solid; border-width: 6px 0 6px 10px; border-color: transparent transparent transparent #ffd27a; }
.hw-arr-sound { margin: 12px 0 0; font: italic 500 16px/1.3 'Crimson Pro', Georgia, serif; color: rgba(236, 227, 207, 0.72); animation: hw-up 0.8s ease 1.65s both; }
/* Hollow's Eve: the moon goes blood-orange, the eyebrow ghost-green stays */
.hw-arrival--eve { background: linear-gradient(180deg, #1a0510 0%, #2a0a1a 40%, #0f050a 74%, #050306 100%); }
.hw-arrival--eve .hw-arr-moon { background:
    radial-gradient(circle at 64% 30%, rgba(120, 40, 10, 0.35) 0 9px, transparent 10px),
    radial-gradient(circle at 32% 62%, rgba(120, 40, 10, 0.3) 0 13px, transparent 14px),
    radial-gradient(circle at 38% 34%, #ffd9a0 0%, #ff9a40 50%, #b8420c 100%);
  box-shadow: 0 0 70px 18px rgba(255, 120, 40, 0.4), 0 0 220px 90px rgba(200, 50, 20, 0.22); }
@keyframes hw-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes hw-up { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes hw-rise { from { opacity: 0; transform: translateY(26px) scale(0.92); } to { opacity: 1; transform: none; } }
@keyframes hw-twinkle { 0% { opacity: 0.8; } 33% { opacity: 0.55; } 50% { opacity: 0.9; } 77% { opacity: 0.65; } }
/* a short phone: tighten the column */
@media (max-height: 700px) {
  .hw-arr-jack { width: 112px; height: 104px; }
  .hw-arr-t { font-size: 36px; }
  .hw-arr-btn { margin-top: 18px; }
}

/* =============================================================================
   THE EVERYDAY SCREENS (the go-bigger pass, Oct 25). Quests, Grace, Legacy and
   the Realm read as Hollow Week, not "the app, tinted purple". Same laws as
   above: every rule scoped, decor never takes a tap, motion is transform +
   opacity stepped a few times a second, sentences keep Crimson Pro 500 16px,
   names / labels / numbers keep Cinzel, nothing new under 13px. Utility
   chrome (the Ledger, settings, the keypad, sheets) is left alone. Meaning
   colors stay: HP / Vigor red, the Trials' teal, rarity frames, the raid's red.
   ============================================================================= */

/* ---------------------------------------------------------------- the Hollow Week banner (top of Quests) */
/* Built by halloween.js dressQuestsBanner: the graveyard valley, a moon, two
   bats, the countdown to Hollow's Eve (game date), a lit jack-o'-lantern. */
.hw-qbanner {
  position: relative; flex-shrink: 0; height: 108px; border-radius: 12px; overflow: hidden; isolation: isolate;
  pointer-events: none; user-select: none; -webkit-user-select: none;
  background: linear-gradient(180deg, #1a0b2a 0%, #0b0612 100%);
  border: 1px solid rgba(255, 138, 31, 0.5);
  box-shadow: 0 0 22px rgba(255, 110, 20, 0.22), 0 6px 22px rgba(0, 0, 0, 0.55);
}
.hw-qbanner * { pointer-events: none; }
.hw-qb-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 58%; z-index: 0; display: block; }
.hw-qb-hills { position: absolute; left: -10%; right: -10%; bottom: 0; height: 60%; z-index: 0;
  background: radial-gradient(ellipse 60% 70% at 25% 100%, #06030a 0 99%, transparent 100%), radial-gradient(ellipse 55% 60% at 80% 100%, #08040d 0 99%, transparent 100%); }
/* the words' side darkens so they read; the jack's side stays painted */
.hw-qb-shade { position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(90deg, rgba(8, 3, 14, 0.9) 0%, rgba(8, 3, 14, 0.66) 50%, rgba(8, 3, 14, 0.06) 82%),
    linear-gradient(0deg, rgba(8, 3, 14, 0.5) 0%, transparent 45%); }
.hw-qb-moon { position: absolute; z-index: 1; top: 9px; right: 92px; width: 24px; height: 24px; border-radius: 50%;
  background: radial-gradient(circle at 38% 34%, #fff8e2 0%, #f6e0a8 50%, #d2a258 100%);
  box-shadow: 0 0 14px 4px rgba(255, 220, 160, 0.35), 0 0 44px 14px rgba(255, 160, 60, 0.14); }
.hw-qbanner--eve .hw-qb-moon { background: radial-gradient(circle at 38% 34%, #ffd9a0 0%, #ff9a40 50%, #b8420c 100%);
  box-shadow: 0 0 18px 5px rgba(255, 120, 40, 0.5), 0 0 50px 16px rgba(200, 50, 20, 0.25); }
.hw-qbanner--eve { border-color: rgba(255, 90, 30, 0.75); }
.hw-qb-bats { position: absolute; z-index: 2; top: 6px; right: 122px; width: 56px; height: 30px; }
.hw-qb-bats .hw-bat { position: absolute; width: 22px; height: 10px; filter: drop-shadow(0 0 2px rgba(255, 170, 80, 0.6)); }
.hw-qb-bats .hw-bat:nth-child(1) { left: 0; top: 14px; animation: hw-qb-bob 2.6s ease-in-out infinite alternate; }
.hw-qb-bats .hw-bat:nth-child(2) { left: 32px; top: 2px; width: 16px; height: 8px; animation: hw-qb-bob 3.1s ease-in-out -1.2s infinite alternate; }
@keyframes hw-qb-bob { from { transform: translateY(0); } to { transform: translateY(-6px); } }
.hw-qb-txt { position: absolute; z-index: 3; left: 14px; right: 84px; top: 50%; transform: translateY(-50%); display: flex; flex-direction: column; gap: 5px; }
.hw-qb-k { font: 700 13px/1.25 'Cinzel', serif; letter-spacing: 0.06em; color: var(--hw-ghost); text-shadow: 0 0 10px rgba(141, 255, 184, 0.4), 0 1px 2px #000; }
.hw-qb-t { font: 700 18px/1.15 'Cinzel', serif; letter-spacing: 0.02em; color: var(--hw-pumpkin-hi); animation: hw-candle 3.4s steps(1, end) infinite; }
.hw-qb-jack { position: absolute; z-index: 3; right: 12px; bottom: 10px; width: 68px; height: 64px; }
.hw-qb-jack .hw-jack { position: relative; z-index: 1; width: 100%; height: 100%; display: block; filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.8)); }
.hw-qb-jack .hw-jack-face { animation: hw-candle-op 2.2s steps(1, end) infinite; }
.hw-qb-halo { position: absolute; left: 50%; top: 55%; width: 132px; height: 132px; margin: -66px 0 0 -66px; border-radius: 50%; z-index: 0;
  background: radial-gradient(circle, rgba(255, 150, 40, 0.45) 0%, rgba(255, 110, 20, 0.16) 40%, transparent 68%);
  animation: hw-candle-op 2.6s steps(1, end) infinite; }

/* ---------------------------------------------------------------- the cards: aubergine, ember-rimmed */
/* The navy cards turn to a witch-purple black with an ember rim; the main
   Quests cards' rim gutters like a candle (an inset glow on ::after whose
   opacity steps; inset, so the cards' own overflow never clips it). */
html.theme-halloween .qs-section { background: rgba(26, 10, 34, 0.94); border-color: rgba(255, 138, 31, 0.24); }
html.theme-halloween .qs-progress-hud { background: linear-gradient(160deg, rgba(36, 16, 44, 0.96) 0%, rgba(14, 8, 18, 0.96) 100%); }
html.theme-halloween .qs-progress-hud::before { background: linear-gradient(90deg, transparent, rgba(255, 150, 50, 0.6), transparent); }
html.theme-halloween :is(.qs-section, .qs-progress-hud)::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: 1; pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(255, 138, 31, 0.2), inset 0 0 22px rgba(255, 110, 20, 0.15);
  animation: hw-rim 5.4s steps(1, end) infinite;
}
html.theme-halloween #qs-tier-2::after, html.theme-halloween #qs-weekly::after { animation-delay: -2.2s; }
html.theme-halloween .qs-progress-hud::after { animation-delay: -3.6s; }
@keyframes hw-rim { 0% { opacity: 0.85; } 17% { opacity: 0.6; } 29% { opacity: 1; } 46% { opacity: 0.7; } 63% { opacity: 0.95; } 78% { opacity: 0.55; } 90% { opacity: 0.9; } }
/* the section headers: candle light from the left edge, where the ember line burns */
html.theme-halloween .qs-section-header {
  background: radial-gradient(ellipse 58% 160% at 0% 50%, rgba(255, 120, 20, 0.2), transparent 70%), linear-gradient(160deg, #26142f, #140b1a);
}
html.theme-halloween .qs-task-row { border-top-color: rgba(255, 170, 90, 0.05); }
/* the three log buttons */
html.theme-halloween .qs-log-btn {
  background: linear-gradient(160deg, #26142e, #0f0914); border-color: rgba(255, 138, 31, 0.34);
  box-shadow: 0 0 16px rgba(255, 110, 20, 0.2), inset 0 1px 0 rgba(255, 200, 140, 0.12), inset 0 -1px 0 rgba(0, 0, 0, 0.6);
}
html.theme-halloween .qs-log-btn::after { background: linear-gradient(90deg, transparent, rgba(255, 138, 31, 0.45), transparent); }
html.theme-halloween .qs-ndc-review { background: rgba(155, 93, 229, 0.08); border-color: rgba(155, 93, 229, 0.38); }
/* Grace, Legacy and the Realm's big panels */
html.theme-halloween .gr-sog-card { background: linear-gradient(160deg, #1e0f22 0%, #120c18 55%, #0a0710 100%); }
/* three jack-o'-lanterns keep vigil at the foot of the grace's flame (halloween.js dressGraceCard) */
.hw-grace-jacks { position: absolute; right: 0; bottom: 0; width: 140px; height: 60px; z-index: 2; pointer-events: none; }
.hw-grace-jacks * { pointer-events: none; }
.hw-grace-jack { position: absolute; bottom: 10px; }
.hw-grace-jack .hw-jack { position: relative; z-index: 1; width: 100%; height: 100%; display: block; filter: drop-shadow(0 3px 5px rgba(0, 0, 0, 0.8)); }
.hw-grace-jack .hw-jack-face { animation: hw-candle-op 2.3s steps(1, end) infinite; }
.hw-grace-jack i { position: absolute; left: 50%; top: 55%; width: 220%; height: 220%; transform: translate(-50%, -50%); border-radius: 50%; z-index: 0;
  background: radial-gradient(circle, rgba(255, 150, 40, 0.42) 0%, rgba(255, 110, 20, 0.12) 42%, transparent 70%); animation: hw-candle-op 2.6s steps(1, end) infinite; }
.hw-grace-jack--1 { right: 94px; width: 22px; height: 21px; }
.hw-grace-jack--2 { right: 50px; width: 34px; height: 32px; }
.hw-grace-jack--2 i { animation-delay: -1.1s; }
.hw-grace-jack--3 { right: 16px; width: 26px; height: 24px; }
html.theme-halloween .gr-char-card { background: linear-gradient(158deg, rgba(36, 16, 42, 0.97) 0%, rgba(12, 7, 16, 0.97) 100%); }
html.theme-halloween .gr-equip-card { background: linear-gradient(160deg, #22132a 0%, #0e0913 100%); border-color: rgba(255, 138, 31, 0.24); box-shadow: 0 0 18px rgba(255, 110, 20, 0.08); }
html.theme-halloween .gr-companion-tappable { background: rgba(24, 12, 30, 0.95); }
/* SOLID UNDER WORDS (the Fable review's fix): the painted backdrop (.hw-backdrop, a fixed layer
   under the whole app) must show around and between cards, never under text. These cards are
   near-clear in the base app (it sits on plain black there), so in the skin they get their own
   dark ground: the Legacy weekly/raid card (base rgba(255,255,255,.04): the hall's painted candles
   showed through its phase labels) and the Grace companion card's lower half (no ground at all). */
html.theme-halloween .lg-boss-card { background: linear-gradient(160deg, rgba(24, 13, 30, 0.95) 0%, rgba(11, 7, 15, 0.96) 100%); }
html.theme-halloween .gr-comp-card { background: linear-gradient(160deg, rgba(30, 16, 36, 0.95) 0%, rgba(14, 9, 19, 0.96) 100%); }
html.theme-halloween :is(.gr-rest-btn, .gr-flask-row) { background: linear-gradient(160deg, #22122a, #120b16); }
html.theme-halloween .hl { background: #130c19; border-color: rgba(255, 138, 31, 0.24); }
html.theme-halloween .hl-raid { background: #0f0a14; border-color: rgba(155, 93, 229, 0.22); }
html.theme-halloween .rm-state { background: linear-gradient(160deg, #20142a 0%, #140d1a 100%); border-color: rgba(255, 138, 31, 0.26); box-shadow: 0 0 18px rgba(255, 110, 20, 0.1); }
html.theme-halloween .rm-chron-body { background: linear-gradient(158deg, #23172c 0%, #150e1b 100%); border-color: rgba(255, 138, 31, 0.14); }
html.theme-halloween .rd-arrival-card { background: linear-gradient(180deg, #1c0f24 0%, #0d0812 100%); border-color: rgba(255, 138, 31, 0.6); box-shadow: 0 0 20px rgba(255, 110, 20, 0.22); }

/* ---------------------------------------------------------------- the Rune bars: a burning wick */
/* Ember to candle-gold (the head stays gold, so the bar still reads as Runes),
   and on Quests a candle flame rides the leading edge (the app's hidden
   .qs-rune-bar-edge, shown only here). The Grace bar's track clips, so its
   tip glows instead. */
html.theme-halloween :is(.qs-rune-bar-fill, .gr-rune-bar-fill) {
  background: linear-gradient(90deg, #4a1804 0%, #9a3a08 30%, #e8720f 68%, #ffc456 100%);
  box-shadow: 0 0 8px rgba(255, 120, 20, 0.45);
}
html.theme-halloween :is(.qs-rune-bar-track, .gr-rune-bar-track) { background: rgba(155, 93, 229, 0.16); }
html.theme-halloween .qs-rune-bar-edge {
  display: block; position: absolute; right: -6px; bottom: 1px; width: 12px; height: 19px; pointer-events: none;
  border-radius: 50% 50% 45% 45% / 64% 64% 36% 36%;
  background: radial-gradient(ellipse 46% 52% at 50% 72%, #fffbe8 0%, #ffe08a 34%, rgba(255, 150, 40, 0.92) 62%, rgba(255, 110, 20, 0) 100%);
  filter: drop-shadow(0 0 4px rgba(255, 160, 50, 0.9));
  transform-origin: 50% 100%; animation: hw-flame 1.3s steps(1, end) infinite;
}
@keyframes hw-flame {
  0% { transform: scale(1, 1); opacity: 1; } 22% { transform: scale(0.88, 1.14); opacity: 0.92; }
  41% { transform: scale(1.06, 0.9); opacity: 1; } 63% { transform: scale(0.94, 1.08); opacity: 0.85; } 82% { transform: scale(1.02, 0.96); opacity: 1; }
}
html.theme-halloween .gr-rune-bar-fill { position: relative; }
html.theme-halloween .gr-rune-bar-fill::after {
  content: ""; position: absolute; right: 0; top: 0; bottom: 0; width: 14px; border-radius: 6px; pointer-events: none;
  background: radial-gradient(ellipse 60% 120% at 80% 50%, #fffbe8 0%, rgba(255, 210, 120, 0.7) 40%, transparent 75%);
  animation: hw-candle-op 1.6s steps(1, end) infinite;
}

/* ---------------------------------------------------------------- the Grace tier strip: four jack-o'-lanterns */
/* The divider under each tier name becomes a jack, lit by its tier: Forsaken
   cold and dark, Flickering guttering, Burning lit, Blazing ablaze. The
   player's own tier (the active column) sits a little bigger. */
html.theme-halloween .qs-grace-col-divider {
  width: 22px; height: 20px; flex-shrink: 0; background: var(--hw-jack-img) center / contain no-repeat;
  filter: grayscale(1) brightness(0.32); opacity: 0.85;
}
html.theme-halloween .qs-grace-col:nth-child(2) .qs-grace-col-divider { filter: grayscale(0.5) brightness(0.62); opacity: 1; animation: hw-gutter-jack 1.8s steps(1, end) infinite; }
html.theme-halloween .qs-grace-col:nth-child(3) .qs-grace-col-divider { filter: brightness(0.9) drop-shadow(0 0 3px rgba(255, 138, 31, 0.6)); opacity: 1; }
html.theme-halloween .qs-grace-col:nth-child(4) .qs-grace-col-divider { filter: brightness(1.12) saturate(1.2) drop-shadow(0 0 7px rgba(255, 160, 40, 0.95)); opacity: 1; animation: hw-candle-op 2s steps(1, end) infinite; }
html.theme-halloween .qs-grace-col--active .qs-grace-col-divider { transform: scale(1.2); }
html.theme-halloween .qs-grace-col--active { background: linear-gradient(160deg, rgba(255, 138, 31, 0.16), rgba(155, 93, 229, 0.08)); box-shadow: inset 0 0 14px rgba(255, 138, 31, 0.2); }
html.theme-halloween .qs-grace-col--active::before { background: linear-gradient(90deg, transparent, rgba(255, 150, 50, 0.75), transparent); }
@keyframes hw-gutter-jack { 0% { opacity: 1; } 14% { opacity: 0.55; } 22% { opacity: 0.95; } 48% { opacity: 0.4; } 56% { opacity: 0.9; } 80% { opacity: 0.65; } }

/* ---------------------------------------------------------------- a done task lights a tiny pumpkin */
/* The empty ring is an ember hairline; done, the gold orb becomes a lit
   jack-o'-lantern (20px drawn in the ring's 16px slot, so no row moves) that
   pops on with a transform-only bounce. */
html.theme-halloween .qs-checkbox { border-color: rgba(255, 138, 31, 0.42); background: radial-gradient(circle, rgba(255, 120, 20, 0.1), transparent 70%); }
html.theme-halloween .qs-checkbox--done {
  width: 20px; height: 20px; margin: -2px; border: 0; border-radius: 0; box-shadow: none;
  background: var(--hw-jack-img) center / contain no-repeat;
  filter: drop-shadow(0 0 4px rgba(255, 138, 31, 0.85));
  animation: hw-check-light 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.3);
}
@keyframes hw-check-light { 0% { transform: scale(0.5) rotate(-12deg); } 60% { transform: scale(1.3) rotate(4deg); } 100% { transform: none; } }

/* ---------------------------------------------------------------- the Merchant's card: a night road, hanging lanterns */
html.theme-halloween .rd-arrcard-strip--day::after { display: none; }   /* the sun bloom: it is night now */
html.theme-halloween .rd-arrcard-strip::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(circle at 36% 28%, #fff6dc 0 9px, rgba(255, 226, 170, 0.35) 10px, rgba(255, 200, 120, 0.1) 26px, transparent 46px),
    linear-gradient(180deg, rgba(26, 8, 48, 0.72) 0%, rgba(30, 10, 40, 0.5) 55%, rgba(12, 4, 18, 0.4) 100%);
}
/* three jack-o'-lanterns on cords over the painting (halloween.js dressMerchantCard) */
.hw-lanterns { position: absolute; top: 0; left: 0; right: 0; height: 92px; z-index: 1; pointer-events: none; overflow: hidden; }
.hw-lanterns * { pointer-events: none; }
.hw-lantern { position: absolute; top: 0; width: 26px; display: flex; flex-direction: column; align-items: center; transform-origin: 50% 0; animation: hw-swing 3.4s ease-in-out infinite alternate; }
.hw-lantern--1 { left: 20%; animation-delay: -0.8s; }
.hw-lantern--2 { left: 54%; animation-duration: 4.1s; animation-delay: -2.2s; }
.hw-lantern--3 { left: 71%; animation-duration: 3s; }
.hw-lantern-cord { display: block; width: 1px; height: 30px; background: linear-gradient(180deg, rgba(40, 30, 20, 0.9), rgba(120, 90, 60, 0.9)); }
.hw-lantern--2 .hw-lantern-cord { height: 16px; }
.hw-lantern--3 .hw-lantern-cord { height: 42px; }
.hw-lantern-jack { position: relative; width: 26px; height: 24px; }
.hw-lantern-jack .hw-jack { position: relative; z-index: 1; width: 100%; height: 100%; display: block; }
.hw-lantern-jack .hw-jack-face { animation: hw-candle-op 2.1s steps(1, end) infinite; }
.hw-lantern-glow { position: absolute; left: 50%; top: 55%; width: 64px; height: 64px; margin: -32px 0 0 -32px; border-radius: 50%; z-index: 0;
  background: radial-gradient(circle, rgba(255, 160, 50, 0.5) 0%, rgba(255, 110, 20, 0.16) 42%, transparent 70%);
  animation: hw-candle-op 2.4s steps(1, end) infinite; }
.hw-lantern--2 .hw-lantern-glow { animation-delay: -1s; }
@keyframes hw-swing { from { transform: rotate(-7deg); } to { transform: rotate(7deg); } }

/* ---------------------------------------------------------------- the Legacy hall: moonlight, rafters of bats, two lit jacks */
/* ::before (over the painting, under the hall's vignette) washes it in moonlit
   purple with an ember glow on the floor; ::after (under the words) hangs the
   bats in the rafters and sets a lit jack either side of the title. */
html.theme-halloween .lh-hall::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(ellipse 70% 40% at 50% 100%, rgba(255, 120, 20, 0.3), transparent 70%),
    linear-gradient(180deg, rgba(76, 26, 128, 0.45) 0%, rgba(44, 14, 78, 0.2) 45%, rgba(20, 6, 30, 0) 72%);
}
html.theme-halloween .lh-hall::after {
  content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background:
    var(--hw-jack-img) left 14px bottom 112px / 38px 36px no-repeat,
    var(--hw-jack-img) right 14px bottom 112px / 38px 36px no-repeat,
    var(--hw-bats-img) 50% 22px / 160px 44px no-repeat;
  filter: drop-shadow(0 0 7px rgba(255, 138, 31, 0.6));
  animation: hw-candle-op 3.2s steps(1, end) infinite;
}

/* ---------------------------------------------------------------- the Realm's header: Hollow's Eve under the moon */
/* The header becomes a moonlit painting (assets/halloween/hollows_eve.jpg,
   the moon and the lantern-lit arch), darkened under the words; the
   countdown chip (halloween.js dressRealmHeader) sits under the subtitle. */
html.theme-halloween .rm-header {
  border-radius: 14px; padding: 26px 2px 18px; margin-bottom: 12px;
  border: 1px solid rgba(255, 138, 31, 0.38);
  background:
    linear-gradient(180deg, rgba(8, 3, 14, 0.25) 0%, rgba(8, 3, 14, 0.5) 50%, rgba(8, 3, 14, 0.9) 100%),
    url("../assets/halloween/hollows_eve.jpg") 50% 36% / cover no-repeat;
  box-shadow: 0 0 24px rgba(255, 110, 20, 0.2), 0 8px 24px rgba(0, 0, 0, 0.55);
}
html.theme-halloween .rm-header .rm-title { filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.95)); }
html.theme-halloween .rm-header .rm-subtitle { text-shadow: 0 1px 3px #000, 0 0 12px rgba(0, 0, 0, 0.9); color: #ece3cf; }
.hw-eve-chip {
  position: relative; z-index: 2; display: inline-flex; align-items: center; gap: 8px; margin-top: 12px; padding: 6px 14px 6px 10px;
  border-radius: 999px; pointer-events: none;
  background: rgba(14, 6, 20, 0.84); border: 1px solid rgba(255, 138, 31, 0.6); box-shadow: 0 0 14px rgba(255, 110, 20, 0.3);
  font: 700 13px/1.2 'Cinzel', serif; letter-spacing: 0.05em; color: var(--hw-pumpkin-hi);
}
.hw-eve-chip-jack { width: 18px; height: 17px; flex-shrink: 0; background: var(--hw-jack-img) center / contain no-repeat;
  filter: drop-shadow(0 0 4px rgba(255, 138, 31, 0.8)); animation: hw-candle-op 2.2s steps(1, end) infinite; }

/* ---------------------------------------------------------------- empty shelves: cobwebs */
html.theme-halloween .lg-boss-empty { position: relative; background: rgba(24, 11, 32, 0.92); border-color: rgba(155, 93, 229, 0.3); }
html.theme-halloween .lg-boss-empty::before, html.theme-halloween .lg-boss-empty::after {
  content: ""; position: absolute; top: 0; left: 0; width: 52px; height: 52px; pointer-events: none;
  background: var(--hw-web-img) top left / contain no-repeat; opacity: 0.5;
}
html.theme-halloween .lg-boss-empty::after { left: auto; right: 0; transform: scaleX(-1); }

/* =============================================================================
   UP TO 11 (Oct 25): painted in, creepy things everywhere, the surprises.
   Same laws: every rule scoped (html.theme-halloween or a .hw-* element),
   decor never takes a tap (the peeking pumpkin's own box is the one
   exception, while it is up), motion is transform + opacity, sentences are
   Crimson Pro 500 16px+, labels Cinzel, nothing new under 13px. Utility chrome
   (the Ledger, settings, the keypad, the Log sheets) is left calm: the front
   layer hides over the sheets and nothing spawns while one is open.
   ============================================================================= */

/* ---------------------------------------------------------------- painted in, not pasted on */
/* The jack-o'-lanterns stop looking like stickers: graded toward the night
   (less saturated, a little warm-dark), shaded by the same light as the scene
   (moonlight from the top-left, shadow underneath, an overlay masked to the
   pumpkin's own shape), standing in a contact shadow, their glow added with
   screen blending so it LIGHTS what is behind them instead of painting a disc. */
html.theme-halloween { --hw-grade: saturate(0.84) sepia(0.14) brightness(0.92) contrast(1.06); }
html.theme-halloween :is(.hw-qb-jack, .hw-grace-jack, .hw-lantern-jack, .hw-arr-jack) .hw-jack { filter: var(--hw-grade) drop-shadow(0 0 1.5px rgba(255, 170, 80, 0.55)) drop-shadow(0 3px 6px rgba(0, 0, 0, 0.75)); }
/* the big ones: their own light bleeds over the inked outline, the way a lit pumpkin glows in a painting */
html.theme-halloween :is(.hw-arr-jack, .hw-qb-jack) .hw-jack { filter: var(--hw-grade) drop-shadow(0 0 2px rgba(255, 170, 80, 0.6)) drop-shadow(0 0 16px rgba(255, 120, 30, 0.42)) drop-shadow(0 8px 14px rgba(0, 0, 0, 0.7)); }
.hw-qb-jack::after, .hw-grace-jack::after, .hw-lantern-jack::after, .hw-arr-jack::after {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(155deg, rgba(150, 130, 235, 0.34) 0%, transparent 36%, transparent 52%, rgba(10, 2, 16, 0.62) 100%);
  -webkit-mask: var(--hw-jack-mask) center / contain no-repeat; mask: var(--hw-jack-mask) center / contain no-repeat;
}
.hw-qb-jack::before, .hw-grace-jack::before, .hw-arr-jack::before {
  content: ""; position: absolute; z-index: 0; left: 6%; right: 6%; bottom: -8%; height: 22%; pointer-events: none;
  background: radial-gradient(ellipse 50% 50% at 50% 50%, rgba(0, 0, 0, 0.7), transparent 72%);
}
.hw-qb-halo, .hw-grace-jack > i, .hw-lantern-glow, .hw-arr-halo { mix-blend-mode: screen; }
/* a low mist drifts IN FRONT of the jacks' feet, so they stand in the scene */
.hw-qbanner::after, .hw-grace-jacks::after {
  content: ""; position: absolute; left: -10%; right: -10%; bottom: 0; height: 30px; z-index: 4; pointer-events: none;
  background:
    radial-gradient(ellipse 22% 60% at 20% 100%, rgba(200, 185, 235, 0.2), transparent 70%),
    radial-gradient(ellipse 26% 70% at 62% 100%, rgba(170, 230, 205, 0.14), transparent 72%),
    radial-gradient(ellipse 20% 60% at 92% 100%, rgba(200, 185, 235, 0.18), transparent 70%);
  animation: hw-mist-sway 9s ease-in-out infinite alternate;
}
@keyframes hw-mist-sway { from { transform: translate3d(-4%, 0, 0); } to { transform: translate3d(4%, 0, 0); } }
.hw-qbanner .hw-qb-jack { bottom: 4px; }
/* the peeking sprite and the tiny CSS jacks take the same grade */
html.theme-halloween .hw-peek-img { filter: var(--hw-grade) drop-shadow(0 0 8px rgba(255, 138, 31, 0.5)); }
html.theme-halloween .qs-checkbox--done { filter: var(--hw-grade) drop-shadow(0 0 4px rgba(255, 138, 31, 0.85)); }
/* the tab lantern hangs on a cord now, and sways */
html.theme-halloween .nav-btn.active::after {
  top: 1px; height: 19px; transform-origin: 50% 0;
  background: var(--hw-jack-img) center bottom / 13px 12px no-repeat, linear-gradient(rgba(170, 130, 80, 0.85), rgba(170, 130, 80, 0.85)) center top / 1px 7px no-repeat;
  filter: var(--hw-grade) drop-shadow(0 0 4px rgba(255, 138, 31, 0.8));
  animation: hw-swing 2.8s ease-in-out infinite alternate;
}
/* the Realm chip's jack and the Legacy hall's two jacks: graded too */
html.theme-halloween .hw-eve-chip-jack { filter: var(--hw-grade) drop-shadow(0 0 4px rgba(255, 138, 31, 0.8)); }
html.theme-halloween .lh-hall::after { filter: var(--hw-grade) drop-shadow(0 0 7px rgba(255, 138, 31, 0.6)); }

/* The painted pieces (round 3), each switched on only once its file loads
   (halloween.js adds html.hw-art-<hook>): the cobweb, and a painted night
   behind each tab, darkened and faded toward the bottom so cards stay readable. */
html.theme-halloween.hw-art-cobweb { --hw-web-img: url("../assets/halloween/cobweb.png"); }
/* the painted pumpkin already carries its own light: a lighter moonlight overlay on it */
html.theme-halloween.hw-art-jack :is(.hw-qb-jack, .hw-grace-jack, .hw-lantern-jack, .hw-arr-jack)::after { opacity: 0.6; }
/* the Grace tier strip: one painted jack per tier, cold to ablaze (tier_1..4, round 3), so no filter fakes it */
html.theme-halloween.hw-art-tiers .qs-grace-col-divider { width: 24px; height: 24px; filter: none; opacity: 1; }
html.theme-halloween.hw-art-tiers .qs-grace-col:nth-child(1) .qs-grace-col-divider { background-image: url("../assets/halloween/tier_1.png"); opacity: 0.85; }
html.theme-halloween.hw-art-tiers .qs-grace-col:nth-child(2) .qs-grace-col-divider { background-image: url("../assets/halloween/tier_2.png"); }
html.theme-halloween.hw-art-tiers .qs-grace-col:nth-child(3) .qs-grace-col-divider { background-image: url("../assets/halloween/tier_3.png"); filter: drop-shadow(0 0 3px rgba(255, 138, 31, 0.55)); }
html.theme-halloween.hw-art-tiers .qs-grace-col:nth-child(4) .qs-grace-col-divider { background-image: url("../assets/halloween/tier_4.png"); filter: drop-shadow(0 0 6px rgba(255, 160, 40, 0.9)); }
/* the Legacy hall rafters: the painted bats */
html.theme-halloween.hw-art-bats .lh-hall::after {
  background:
    var(--hw-jack-img) left 14px bottom 112px / 38px 36px no-repeat,
    var(--hw-jack-img) right 14px bottom 112px / 38px 36px no-repeat,
    url("../assets/halloween/bats.png") 50% 12px / 150px auto no-repeat;
}
/* the Site of Grace: one painted cluster of three jacks at the flame's foot (dressGraceCard) */
.hw-grace-cluster { position: absolute; right: 6px; bottom: 6px; width: 104px; height: 84px; }
.hw-grace-cluster img { position: relative; z-index: 1; display: block; width: 100%; height: 100%; object-fit: contain;
  filter: var(--hw-grade) drop-shadow(0 4px 6px rgba(0, 0, 0, 0.75)); }
.hw-grace-cluster > i { position: absolute; z-index: 0; left: 50%; top: 58%; width: 180px; height: 140px; margin: -70px 0 0 -90px; border-radius: 50%; mix-blend-mode: screen;
  background: radial-gradient(ellipse, rgba(255, 150, 40, 0.42) 0%, rgba(255, 110, 20, 0.12) 45%, transparent 70%); animation: hw-candle-op 2.6s steps(1, end) infinite; }
.hw-grace-jacks:has(.hw-grace-cluster) { width: 130px; height: 100px; }
.hw-backdrop { position: absolute; inset: 0; opacity: 0; background: 50% 0 / cover no-repeat; }
html.theme-halloween.hw-art-backdrops .hw-backdrop {
  opacity: 0.55; transition: opacity 0.8s ease;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.5) 38%, rgba(0, 0, 0, 0.5) 66%, #000 100%); mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.5) 38%, rgba(0, 0, 0, 0.5) 66%, #000 100%);
}
/* THE BACKDROP PICKS: one line per tab. To try another variant (A-D in
   misc/halloween-2026/art/final/v3_bg_<tab>_<X>.jpg), copy it to assets/halloween/bg/
   at 720 wide and change that tab's line. Only the shown tab's image is ever
   fetched (a background-image loads when its rule first matches): lazy for free. */
html.theme-halloween {
  --hw-bg-quests: url("../assets/halloween/bg/quests_B.jpg");
  --hw-bg-grace: url("../assets/halloween/bg/grace_C.jpg");
  --hw-bg-legacy: url("../assets/halloween/bg/legacy_C.jpg");
  --hw-bg-realm: url("../assets/halloween/bg/realm_A.jpg");
}
html.theme-halloween.hw-art-backdrops body:has(#tab-quests.active) .hw-backdrop { background-image: var(--hw-bg-quests); }
html.theme-halloween.hw-art-backdrops body:has(#tab-grace.active) .hw-backdrop { background-image: var(--hw-bg-grace); }
html.theme-halloween.hw-art-backdrops body:has(#tab-legacy.active) .hw-backdrop { background-image: var(--hw-bg-legacy); }
html.theme-halloween.hw-art-backdrops body:has(#tab-realm.active) .hw-backdrop { background-image: var(--hw-bg-realm); }
/* the active tab's lantern: the painted iron lantern on its chain (round 3), swaying */
html.theme-halloween.hw-art-lantern .nav-btn.active::after {
  top: 0; left: calc(50% + 13px); width: 10px; height: 22px;
  background: url("../assets/halloween/lantern.png") center top / contain no-repeat;
  filter: drop-shadow(0 0 4px rgba(255, 160, 60, 0.85));
}
html.theme-halloween.hw-art-lantern .nav-btn.active[data-tab="realm"]::after { left: calc(50% - 24px); }
/* the Legacy hall: painted candles guttering on the left of the title, a jack on the right */
html.theme-halloween.hw-art-candles .lh-hall::after {
  background:
    url("../assets/halloween/candles.png") left 10px bottom 108px / 44px 44px no-repeat,
    var(--hw-jack-img) right 14px bottom 112px / 38px 36px no-repeat,
    var(--hw-bats-img) 50% 22px / 160px 44px no-repeat;
}
html.theme-halloween.hw-art-candles.hw-art-bats .lh-hall::after {
  background:
    url("../assets/halloween/candles.png") left 10px bottom 108px / 44px 44px no-repeat,
    var(--hw-jack-img) right 14px bottom 112px / 38px 36px no-repeat,
    url("../assets/halloween/bats.png") 50% 12px / 150px auto no-repeat;
}

/* ---------------------------------------------------------------- the eyes in the dark */
.hw-eyes { position: absolute; width: var(--w, 22px); height: calc(var(--w, 22px) * 0.35); transform: translate(-50%, -50%); opacity: 0;
  animation: hw-eyes-op 4s ease both; }
.hw-eyes-svg { display: block; width: 100%; height: 100%; overflow: visible; fill: #ffcf4a;
  filter: drop-shadow(0 0 3px rgba(255, 170, 40, 0.95)) drop-shadow(0 0 8px rgba(255, 110, 20, 0.6)); }
.hw-eyes-lid { transform-origin: 50% 50%; animation: hw-eyes-lid 4s linear both; }
@keyframes hw-eyes-op { 0% { opacity: 0; } 10% { opacity: 1; } 84% { opacity: 1; } 100% { opacity: 0; } }
@keyframes hw-eyes-lid {
  0% { transform: scaleY(0.05); } 12% { transform: scaleY(1); } 40% { transform: scaleY(1); } 43% { transform: scaleY(0.08); }
  47% { transform: scaleY(1); } 64% { transform: scaleY(1); } 67% { transform: scaleY(0.08); } 71% { transform: scaleY(1); }
  86% { transform: scaleY(1); } 100% { transform: scaleY(0.05); }
}

/* ---------------------------------------------------------------- the spider on its thread */
.hw-spider { position: absolute; width: 0; height: 0; }
.hw-spider-thread { position: absolute; left: -0.5px; top: 0; width: 1px; height: calc(var(--drop, 90px) + 6px); transform-origin: 50% 0;
  background: linear-gradient(180deg, rgba(235, 228, 245, 0.15), rgba(235, 228, 245, 0.6)); animation: hw-thread 7s ease-in-out both; }
.hw-spider-bug { position: absolute; left: -13px; top: -6px; width: 26px; height: 26px; animation: hw-spider 7s ease-in-out both; }
.hw-spider-svg, .hw-spider-art { display: block; width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(0 0 2px rgba(255, 190, 120, 0.7)); }
.hw-spider-legs { transform-origin: 50% 55%; animation: hw-legs 0.5s steps(2, end) infinite alternate; }
.hw-spider.is-fleeing { transition: opacity 0.5s ease; opacity: 0; }
/* the painted spider hangs from the drawn thread: only its body shows (the image's own thread is cropped away) */
.hw-spider-bug:has(.hw-spider-art) { left: -16px; top: -18px; width: 32px; height: 40px; }
.hw-spider .hw-spider-art { object-fit: cover; object-position: 50% 100%; }
@keyframes hw-thread { 0% { transform: scaleY(0); } 22% { transform: scaleY(1); } 30% { transform: scaleY(0.93); } 36% { transform: scaleY(1); } 72% { transform: scaleY(1); } 100% { transform: scaleY(0); } }
@keyframes hw-spider {
  0% { transform: translateY(-20px); opacity: 0; } 6% { opacity: 1; }
  22% { transform: translateY(var(--drop, 90px)); } 30% { transform: translateY(calc(var(--drop, 90px) * 0.93)); }
  36% { transform: translateY(var(--drop, 90px)) rotate(8deg); } 50% { transform: translateY(var(--drop, 90px)) rotate(-8deg); }
  72% { transform: translateY(var(--drop, 90px)); } 96% { opacity: 1; } 100% { transform: translateY(-20px); opacity: 0; }
}
@keyframes hw-legs { from { transform: scaleX(1); } to { transform: scaleX(0.88); } }
/* the scurry (a scroll while it hangs): it lets go of its thread and dashes in a
   zig-zag off the screen (halloween.js scurry moves it, transforms only) */
.hw-spider-run { position: absolute; width: 26px; height: 26px; margin: -13px 0 0 -13px; will-change: transform; }
.hw-spider-run:has(.hw-spider-art) { width: 30px; height: 30px; margin: -15px 0 0 -15px; }
.hw-spider-run .hw-spider-art { object-fit: cover; object-position: 50% 100%; }
.hw-spider-run .hw-spider-legs { animation-duration: 0.09s; }

/* ---------------------------------------------------------------- the crow on the Reaper's card */
/* It lands on the scythe's haft, right of his face (the wide portrait's haft
   at x 565 y 180 of 700 x 350, cover-scaled to the 185px-tall frame). */
.hw-crow { position: absolute; z-index: 3; left: calc(50% + 90px); top: 57px; width: 46px; height: 38px; pointer-events: none; }
.hw-crow-land { width: 100%; height: 100%; animation: hw-crow-land 1.7s cubic-bezier(0.25, 0.8, 0.3, 1) 0.9s both; }
.hw-crow .hw-crow-svg, .hw-crow .hw-crow-art { display: block; width: 100%; height: 100%; object-fit: contain; object-position: center;
  filter: drop-shadow(0 0 1.5px rgba(255, 190, 110, 0.85)) drop-shadow(0 0 6px rgba(255, 120, 30, 0.3)); }
.hw-crow-head { transform-box: fill-box; transform-origin: 70% 90%; animation: hw-crow-look 9s steps(1, end) 3s infinite; }
@keyframes hw-crow-land {
  0% { transform: translate(150px, -80px) rotate(-16deg) scale(0.7); opacity: 0; } 12% { opacity: 1; }
  72% { transform: translate(5px, -5px) rotate(5deg) scale(1.03); } 86% { transform: translate(0, 1px) scaleY(0.94); } 100% { transform: none; opacity: 1; }
}
@keyframes hw-crow-look { 0% { transform: none; } 60% { transform: rotate(-16deg); } 66% { transform: rotate(10deg); } 72% { transform: none; } 90% { transform: translateY(1px); } }

/* ---------------------------------------------------------------- ghost wisps in Legacy */
/* In the hall's painting (behind the words), and two that roam the whole
   Legacy screen now and then (front layer, Legacy only). */
.hw-wisps { position: absolute; inset: 0; z-index: 3; pointer-events: none; overflow: hidden; }
.hw-wisp, .hw-roam i { position: absolute; width: 90px; height: 120px; opacity: 0; will-change: transform, opacity;
  background:
    radial-gradient(ellipse 36% 30% at 50% 36%, rgba(225, 255, 238, 0.55), rgba(150, 230, 200, 0.16) 60%, transparent 74%),
    radial-gradient(ellipse 16% 40% at 52% 72%, rgba(185, 240, 215, 0.24), transparent 72%); }
html.theme-halloween.hw-art-wisp .hw-wisp, html.theme-halloween.hw-art-wisp .hw-roam i { background: url("../assets/halloween/wisp.png") center / contain no-repeat; }
.hw-wisp { animation: hw-wisp 17s ease-in-out infinite; }
.hw-wisp--1 { left: 6%; top: 36%; animation-delay: -2s; }
.hw-wisp--2 { left: 64%; top: 16%; width: 70px; height: 94px; animation-duration: 22s; animation-delay: -10s; }
.hw-wisp--3 { left: 38%; top: 48%; width: 60px; height: 80px; animation-duration: 19s; animation-delay: -15s; }
@keyframes hw-wisp {
  0% { opacity: 0; transform: translate(0, 24px) scale(0.8); } 22% { opacity: 0.5; } 50% { opacity: 0.22; transform: translate(36px, -26px) scale(1); }
  74% { opacity: 0.45; } 100% { opacity: 0; transform: translate(-18px, -70px) scale(0.9); }
}
.hw-roam { display: none; position: absolute; inset: 0; overflow: hidden; }
html.theme-halloween body:has(#tab-legacy.active) .hw-roam { display: block; }
.hw-roam i { left: 0; top: 0; width: 110px; height: 140px; animation: hw-roam 38s linear infinite; }
.hw-roam i + i { width: 80px; height: 104px; animation-duration: 47s; animation-delay: -24s; animation-direction: reverse; }
@keyframes hw-roam {
  0% { transform: translate3d(-30vw, 78vh, 0); opacity: 0; } 8% { opacity: 0.14; } 40% { transform: translate3d(40vw, 46vh, 0); opacity: 0.08; }
  52% { opacity: 0; } 100% { transform: translate3d(110vw, 8vh, 0); opacity: 0; }
}

/* ---------------------------------------------------------------- the rare ghost (about 1 open in 15) */
.hw-ghost { position: absolute; left: 0; width: 84px; height: 106px; opacity: 0; will-change: transform, opacity; animation: hw-ghost-ltr 11s ease-in-out both; }
.hw-ghost.hw-rtl { animation-name: hw-ghost-rtl; }
.hw-ghost-bob { width: 100%; height: 100%; animation: hw-bob 1.8s ease-in-out infinite alternate; --bob: 16px; }
.hw-ghost-svg, .hw-ghost-art { display: block; width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(0 0 14px rgba(200, 225, 255, 0.55)); }
.hw-rtl .hw-ghost-svg, .hw-rtl .hw-ghost-art { transform: scaleX(-1); }
@keyframes hw-ghost-ltr { 0% { transform: translate3d(-25vw, 0, 0); opacity: 0; } 12% { opacity: 0.62; } 85% { opacity: 0.5; } 100% { transform: translate3d(115vw, -12vh, 0); opacity: 0; } }
@keyframes hw-ghost-rtl { 0% { transform: translate3d(115vw, 0, 0); opacity: 0; } 12% { opacity: 0.62; } 85% { opacity: 0.5; } 100% { transform: translate3d(-25vw, -12vh, 0); opacity: 0; } }

/* ---------------------------------------------------------------- the whisper and the secret */
/* THE WHISPER (Nick, Oct 25: "bolder and spookier and maybe sillier"): ghost-green
   Cinzel with a sickly glow, its words flickering and its letters wobbling, rising
   slowly and a little sideways through an empty patch of the screen (halloween.js
   whisperSpot sets its top, never over a card's words) as it fades in and out. */
.hw-whisper { position: absolute; left: 16px; right: 16px; text-align: center; opacity: 0;
  font: 700 21px/1.3 'Cinzel', serif; letter-spacing: 0.08em; color: #c6ffd8;
  text-shadow: 0 0 5px rgba(141, 255, 184, 0.95), 0 0 16px rgba(60, 255, 140, 0.6), 0 0 34px rgba(60, 255, 140, 0.32), 0 2px 3px #000; }
.hw-whisper.is-on { animation: hw-whisper 4.2s ease-in-out both; }
/* the fallback band just above the tab bar (whisperBand 'bar'): its own dark plate, so the
   line never tangles with a card's words; a scroll sends any whisper away at once */
.hw-whisper.hw-whisper--bar { left: 24px; right: 24px; padding: 6px 10px; border-radius: 12px; background: rgba(6, 4, 10, 0.92); box-shadow: 0 0 18px rgba(0, 0, 0, 0.8); }
.hw-whisper.hw-whisper--gone { opacity: 0 !important; transition: opacity 0.2s linear; animation-play-state: paused; }
.hw-wh-w { display: inline-block; animation: hw-wh-flick 1.1s steps(1, end) infinite; }
.hw-wh-w:nth-child(2n) { animation-delay: -0.5s; }
.hw-wh-c { display: inline-block; animation: hw-wh-wob 1.3s ease-in-out var(--d, 0s) infinite alternate; }
@keyframes hw-whisper { 0% { opacity: 0; transform: translate3d(0, 0, 0) scale(0.97); } 22% { opacity: 1; } 70% { opacity: 0.9; }
  100% { opacity: 0; transform: translate3d(var(--dx, 10px), -26px, 0) scale(1.03); } }
@keyframes hw-wh-flick { 0% { opacity: 1; } 18% { opacity: 0.62; } 26% { opacity: 1; } 58% { opacity: 0.8; } 64% { opacity: 0.45; } 70% { opacity: 1; } }
@keyframes hw-wh-wob { from { transform: translateY(-1.5px) rotate(-4deg); } to { transform: translateY(1.5px) rotate(4deg); } }
.hw-secret { position: absolute; left: 16px; right: 16px; bottom: calc(var(--nav-height, 64px) + 78px); text-align: center; opacity: 0;
  font: italic 600 20px/1.3 'Crimson Pro', Georgia, serif; color: #ffcf7a; text-shadow: 0 0 14px rgba(255, 138, 31, 0.8), 0 1px 2px #000;
  animation: hw-secret 4.5s ease both;
  padding: 18px 8px; background: radial-gradient(closest-side, rgba(4, 2, 8, 0.85), rgba(4, 2, 8, 0.55) 60%, transparent); }
@keyframes hw-secret { 0% { opacity: 0; transform: translateY(16px); } 15% { opacity: 1; transform: none; } 75% { opacity: 1; } 100% { opacity: 0; transform: translateY(-18px); } }
/* the candy: a wrapped sweet joins the corn and the seeds */
.hw-burst .hw-sweet { width: 13px; height: 7px; margin: -3.5px 0 0 -6.5px; border-radius: 3px;
  background: linear-gradient(90deg, #ffb347 0 22%, #9b5de5 22% 78%, #ffb347 78% 100%); clip-path: polygon(0 0, 22% 30%, 22% 0, 78% 0, 78% 30%, 100% 0, 100% 100%, 78% 70%, 78% 100%, 22% 100%, 22% 70%, 0 100%); }
.hw-burst--candy { z-index: 1; }

/* ---------------------------------------------------------------- the peeking pumpkin takes taps (only its own box) */
.hw-front .hw-peek-clip.is-up .hw-peek { pointer-events: auto; cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
.hw-peek--tap .hw-peek-img, .hw-peek--tap .hw-jack { animation: hw-wobble 0.35s ease; }
@keyframes hw-wobble { 0% { transform: rotate(0); } 30% { transform: rotate(-9deg) scale(1.05); } 65% { transform: rotate(6deg); } 100% { transform: none; } }
.hw-peek-clip.hw-peek--burst .hw-peek { transition: transform 0.3s ease, opacity 0.3s ease; transform: translateY(0) scale(1.6); opacity: 0; }

/* ---------------------------------------------------------------- the blow lands, the heart, the wind */
/* a Rune toast that struck the Lantern Reaper: one red-ember flicker over the screen */
.hw-flicker { position: absolute; inset: 0; opacity: 0;
  background: radial-gradient(ellipse 80% 70% at 50% 40%, rgba(255, 120, 30, 0.2), rgba(30, 0, 10, 0.55));
  animation: hw-flicker 0.6s steps(1, end) both; }
@keyframes hw-flicker { 0% { opacity: 0.8; } 18% { opacity: 0.1; } 34% { opacity: 0.6; } 52% { opacity: 0; } 70% { opacity: 0.3; } 86% { opacity: 0; } }
/* Vigor low (Grace's low bar, or the New Day card's warning on the page): a slow
   heartbeat at the screen's edges, two beats and a long rest */
.hw-heart { position: absolute; inset: 0; opacity: 0; display: none;
  background: radial-gradient(ellipse 62% 58% at 50% 50%, transparent 58%, rgba(150, 12, 24, 0.5) 100%); }
html.theme-halloween body:has(#screen-app.active):has(.gr-vigor-fill--low, .nd-lowv) .hw-heart { display: block; animation: hw-heartbeat 6.5s linear infinite; }
@keyframes hw-heartbeat { 0% { opacity: 0; } 4% { opacity: 0.8; } 10% { opacity: 0.18; } 14% { opacity: 0.62; } 24% { opacity: 0; } 100% { opacity: 0; } }
/* a fast scroll: every flame on screen gutters for a moment */
html.theme-halloween.hw-gust .qs-rune-bar-edge { animation: hw-gust-flame 1.2s ease-out both; }
html.theme-halloween.hw-gust :is(.hw-qb-halo, .hw-grace-jack > i, .hw-lantern-glow, .hw-face-glow, .hw-jack-face) { animation: hw-gust-dim 1.2s ease-out both; }
html.theme-halloween.hw-gust .nav-btn.active::after { animation: hw-gust-dim 1.2s ease-out both; }
html.theme-halloween.hw-gust .hw-lantern { animation-duration: 0.9s; }
@keyframes hw-gust-flame {
  0% { transform: none; opacity: 1; } 15% { transform: skewX(-28deg) scale(0.7, 0.55); opacity: 0.4; }
  35% { transform: skewX(18deg) scale(0.85, 0.7); opacity: 0.6; } 60% { transform: skewX(-8deg) scale(0.95); opacity: 0.85; } 100% { transform: none; opacity: 1; }
}
@keyframes hw-gust-dim { 0% { opacity: 1; } 15% { opacity: 0.18; } 35% { opacity: 0.55; } 55% { opacity: 0.28; } 100% { opacity: 1; } }

/* ---------------------------------------------------------------- the blood moon (Sat Oct 31, game date) */
/* A red moon, a crimson sky, thicker fog; the Hollow's Eve moment plays once. */
html.theme-halloween.hw-blood body {
  background:
    radial-gradient(ellipse 160% 50% at 50% 0%, rgba(110, 10, 22, 0.85) 0%, transparent 55%),
    radial-gradient(ellipse 70% 35% at 12% 38%, rgba(70, 10, 40, 0.55) 0%, transparent 60%),
    radial-gradient(ellipse 100% 40% at 50% 50%, rgba(14, 4, 10, 0.6) 0%, transparent 70%),
    radial-gradient(ellipse 130% 42% at 50% 100%, rgba(170, 30, 10, 0.45) 0%, transparent 62%),
    linear-gradient(180deg, #0d0306 0%, #12040a 35%, #0b0508 65%, #100506 100%);
}
html.theme-halloween.hw-blood .hw-moon {
  background:
    radial-gradient(circle at 62% 30%, rgba(90, 10, 10, 0.4) 0 5px, transparent 6px),
    radial-gradient(circle at 34% 62%, rgba(90, 10, 10, 0.35) 0 7px, transparent 8px),
    radial-gradient(circle at 38% 34%, #ffb08a 0%, #e04a2a 48%, #7a1208 100%);
  box-shadow: 0 0 40px 10px rgba(255, 60, 30, 0.4), 0 0 140px 56px rgba(200, 20, 10, 0.22);
}
html.theme-halloween.hw-blood body:has(#screen-app.active) .hw-moon {
  background: radial-gradient(ellipse at center, rgba(255, 70, 40, 0.34) 0%, rgba(200, 20, 10, 0.12) 42%, transparent 70%); box-shadow: none;
}
html.theme-halloween.hw-blood .hw-fog-floor { height: 52%; background: linear-gradient(0deg, rgba(150, 70, 90, 0.42) 0%, rgba(120, 50, 80, 0.2) 45%, transparent 100%); }
html.theme-halloween.hw-blood .hw-fog--a { top: 10%; height: 60%; }
html.theme-halloween.hw-blood .hw-ambient::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 70%; pointer-events: none;
  background: radial-gradient(ellipse 90% 60% at 30% 100%, rgba(170, 120, 150, 0.2), transparent 70%), radial-gradient(ellipse 80% 55% at 80% 100%, rgba(170, 120, 150, 0.16), transparent 70%);
}
/* the front layer reddens at the edges and the mist over the tab bar thickens */
html.theme-halloween.hw-blood .hw-front::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 62% 58% at 50% 46%, transparent 50%, rgba(120, 8, 16, 0.34) 100%); }
html.theme-halloween.hw-blood .hw-mist { height: 120px; }
html.theme-halloween.hw-blood .hw-mist i { background:
    radial-gradient(ellipse 16% 50% at 15% 100%, rgba(220, 150, 170, 0.2), transparent 70%),
    radial-gradient(ellipse 20% 46% at 45% 100%, rgba(200, 120, 140, 0.14), transparent 70%),
    radial-gradient(ellipse 16% 52% at 78% 100%, rgba(220, 150, 170, 0.18), transparent 70%);
  background-size: 50% 100%; background-repeat: repeat-x; }
.hw-arrival--eve::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; mix-blend-mode: multiply;
  background: radial-gradient(ellipse 90% 70% at 50% 35%, rgba(255, 120, 110, 0.5), rgba(150, 20, 30, 0.75)); }
html.theme-halloween.hw-blood .nav-btn.active::before { background: linear-gradient(90deg, transparent, #e0402a, transparent); box-shadow: 0 0 10px rgba(255, 60, 30, 0.85); }
html.theme-halloween.hw-blood .hw-qb-moon { background: radial-gradient(circle at 38% 34%, #ffb08a 0%, #e04a2a 50%, #7a1208 100%); box-shadow: 0 0 18px 5px rgba(255, 60, 30, 0.55), 0 0 50px 16px rgba(200, 20, 10, 0.3); }

/* ---------------------------------------------------------------- everything holds still under a cover */
/* While a moment, the arrival, the loot popup or a Log sheet covers the app,
   the skin's own decor pauses (the front layer is also hidden over the sheets). */
html.theme-halloween body:has(.mn-overlay, .hw-arrival, #loot-popup-overlay.open, .modal-overlay.modal--open, .wk-layer.open) :is(.hw-ambient, .hw-front, .hw-crow, .hw-wisps, .hw-qbanner, .hw-lanterns, .hw-grace-jacks) * { animation-play-state: paused; }

/* =============================================================================
   NICK'S OCT 25 ASKS: the reel first, the banner's rewatch, the painted tails.
   Same laws: every rule scoped, sentences Crimson Pro 500 16px, labels Cinzel,
   nothing new under 13px.
   ============================================================================= */

/* ---------------------------------------------------------------- the reel, in lantern colors */
/* The first showing (halloween.js playReelFirst, .hw-reel) and the banner's rewatch
   (the app's player, theme 'halloween') take the pumpkin ink. Continue (.hw-reel-go)
   sits low, clear of the picture: it shows when the reel ends, or as the safety net. */
html.theme-halloween .mn-reel--halloween, .hw-reel { --reel-rgb: 255, 138, 31; --reel-ink: #ffb347; }
.hw-reel-go { position: absolute; z-index: 3; left: 50%; bottom: calc(26px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%);
  min-width: 180px; min-height: 48px; padding: 0 26px; border-radius: 999px; cursor: pointer;
  background: rgba(10, 4, 14, 0.8); border: 1px solid rgba(255, 138, 31, 0.85); box-shadow: 0 0 20px rgba(255, 120, 20, 0.35);
  font: 700 14px/1 'Cinzel', serif; letter-spacing: 0.14em; text-transform: uppercase; color: #ffd27a;
  animation: hw-fade-in 0.5s ease both; -webkit-tap-highlight-color: transparent; }

/* ---------------------------------------------------------------- the banner replays the reel */
/* With the reel listed the Hollow Week banner takes a tap (the banner alone: its
   pieces stay pointer-events none) and says so in one small line. */
.hw-qbanner.hw-qbanner--reel { pointer-events: auto; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.hw-qbanner--reel:active { transform: scale(0.99); }
.hw-qbanner--reel:focus-visible { outline: 2px solid #ffb347; outline-offset: 2px; }
.hw-qb-w { display: inline-flex; align-items: center; gap: 7px; font: 700 13px/1.2 'Cinzel', serif; letter-spacing: 0.06em; color: #e9dcc4; text-shadow: 0 1px 2px #000; }
/* its X (Nick, Oct 25): hides it until the next game day; a 40px tap box, a small mark */
.hw-qbanner .hw-qb-x { position: absolute; z-index: 5; top: 0; right: 0; width: 40px; height: 40px; padding: 0; border: 0; background: none;
  pointer-events: auto; cursor: pointer; display: flex; align-items: center; justify-content: center; -webkit-tap-highlight-color: transparent; }
.hw-qb-x span { display: flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%;
  background: rgba(8, 3, 14, 0.72); border: 1px solid rgba(239, 230, 210, 0.3); color: rgba(239, 230, 210, 0.85);
  font: 400 17px/1 Georgia, serif; }
.hw-qb-x:focus-visible span { outline: 2px solid #ffb347; outline-offset: 2px; }
.hw-qb-w i { width: 0; height: 0; border-style: solid; border-width: 5px 0 5px 8px; border-color: transparent transparent transparent #ffb347; flex-shrink: 0; }

/* ---------------------------------------------------------------- the painted tails */
/* Every tab ends in an empty stretch (70% of the screen) so a player can scroll past
   the last card and see the tab's painting, with one quiet line at its very end.
   A pseudo-element: no app re-render can wipe it, nothing reads it, and it is gone
   the moment the skin's class comes off. The scroller ends at the tab bar's top
   edge (the bar is not over it), so the line sits just above the bar. */
html.theme-halloween .tab-panel::after {
  content: ""; display: flex; align-items: flex-end; justify-content: center; flex-shrink: 0;
  height: 70vh; height: 70svh; box-sizing: border-box; padding: 0 24px 20px; pointer-events: none; text-align: center;
  font: italic 500 16px/1.4 'Crimson Pro', Georgia, serif; letter-spacing: 0.03em; color: rgba(236, 227, 207, 0.5);
  text-shadow: 0 1px 3px #000, 0 0 14px rgba(0, 0, 0, 0.85);
}
html.theme-halloween #tab-quests::after { content: "The pumpkin field keeps watch."; }
html.theme-halloween #tab-grace::after { content: "The flame burns on."; }
html.theme-halloween #tab-legacy::after { content: "The crypt remembers."; }
html.theme-halloween #tab-realm::after { content: "The village sleeps. Mostly."; }
/* down in the tail (halloween.js updateTail: html.hw-at-tail) the fog thins and the
   painting comes up clear */
html.theme-halloween :is(.hw-fog, .hw-fog-floor, .hw-mist) { transition: opacity 0.8s ease; }
html.theme-halloween.hw-at-tail :is(.hw-fog, .hw-fog-floor) { opacity: 0.3; }
html.theme-halloween.hw-at-tail .hw-mist { opacity: 0.4; }
html.theme-halloween.hw-art-backdrops.hw-at-tail .hw-backdrop { opacity: 0.9; -webkit-mask-image: none; mask-image: none; }

/* ================================================================ ROUND 2 (Oct 25): the frights, the pokes, the eggs */
/* The DOM half is js/halloween-frights.js. Nothing here takes a tap except the
   black cat's own box while it walks and the moon on the Hollow Week banner. No
   sustained strobing: the light/dark cuts are a few hard steps (POWER_FAIL_PLAN). */

/* the frights' own top layer: over the app, its header and tab bar; under every sheet, popup and moment */
.hw-fx { position: fixed; inset: 0; z-index: 4; pointer-events: none; overflow: hidden; }
.hw-fx * { pointer-events: none; }
html.theme-halloween body:has(.modal-overlay.modal--open, .wk-layer.open) .hw-fx { visibility: hidden; }

/* 6.1 THE POWER FAILURE: hard cuts to black (no fade); between them the whole app stutters, skipping frames */
.hw-power { position: absolute; inset: 0; background: #000; opacity: 0; }
.hw-power.is-dark { opacity: 1; }
html.theme-halloween.hw-stutter #screen-app { animation: hw-stutter 0.24s steps(1, end) infinite; }
@keyframes hw-stutter { 0% { transform: translate(0, 0); } 20% { transform: translate(-7px, 3px); } 40% { transform: translate(6px, -4px) skewX(1.5deg); } 60% { transform: translate(-3px, -2px); } 80% { transform: translate(4px, 5px); } }

/* 6.2 THE GLITCHED HEADING: red, split, every letter jittering (letters move; the screen never flashes) */
html.theme-halloween .hw-glitching { color: #ff3a2a !important; text-shadow: 2px 0 rgba(0, 255, 240, 0.8), -2px 0 rgba(255, 0, 64, 0.9) !important; }
.hw-gl-c { display: inline-block; animation: hw-jit 0.09s steps(1, end) var(--j, 0s) infinite; }
@keyframes hw-jit { 0% { transform: translate(0, 0); } 25% { transform: translate(-1.5px, 1px); } 50% { transform: translate(1.5px, -1.5px) skewX(-8deg); } 75% { transform: translate(0, 1.5px); } }

/* 6.3 THE HANDPRINTS: slapped onto the glass at once, then fogging away */
.hw-print { position: absolute; width: 74px; height: 102px; opacity: 0; transform: rotate(var(--rot, 0deg)); filter: blur(1.4px);
  animation: hw-print 6s linear var(--d, 0s) forwards; }
.hw-print svg { width: 100%; height: 100%; display: block; }
@keyframes hw-print { 0% { opacity: 0; } 1% { opacity: 0.85; } 30% { opacity: 0.65; filter: blur(2px); } 100% { opacity: 0; filter: blur(8px); } }

/* 6.4 THE FIGURE far off in the painting, 6.5 THE FACE at the very bottom of the tail
   (both in the back layer: they show only through the empty painted tail) */
.hw-figure { position: absolute; width: 26px; height: 80px; margin-left: -13px; opacity: 0.85; filter: blur(0.3px) drop-shadow(0 0 5px rgba(0, 0, 0, 0.9)); }
.hw-figure svg { width: 100%; height: 100%; display: block; }
.hw-pale { position: absolute; bottom: calc(var(--nav-height, 64px) + 6px); width: 110px; height: 132px; margin-left: -55px; opacity: 0; filter: blur(1.2px);
  animation: hw-pale 1.5s linear forwards; }
.hw-pale svg { width: 100%; height: 100%; display: block; }
@keyframes hw-pale { 0% { opacity: 0; transform: translateY(26px) scale(0.92); } 8% { opacity: 0.75; transform: translateY(0) scale(1); } 74% { opacity: 0.6; } 80%, 100% { opacity: 0; } }

/* 5a THE BLACK CAT: its own tap box only while it walks */
.hw-cat { position: absolute; left: 0; top: calc(100% - var(--nav-height, 64px) - 50px); width: 92px; height: 54px; }
.hw-front .hw-cat .hw-cat-hit { pointer-events: auto; cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent; width: 100%; height: 100%; }
.hw-cat-svg { width: 100%; height: 100%; display: block; overflow: visible; filter: drop-shadow(0 0 4px rgba(255, 140, 40, 0.45)); animation: hw-cat-bob 0.42s ease-in-out infinite alternate; }
.hw-cat.hw-rtl .hw-cat-svg { transform: scaleX(-1); }
.hw-cat-tail { transform-origin: 18px 34px; animation: hw-cat-tail 1.1s ease-in-out infinite alternate; }
@keyframes hw-cat-bob { from { translate: 0 0; } to { translate: 0 -2px; } }
@keyframes hw-cat-tail { from { transform: rotate(-8deg); } to { transform: rotate(10deg); } }
.hw-cat-say { position: absolute; transform: translateY(-100%); white-space: nowrap;
  font: 600 14px/1.25 'Cinzel', serif; color: #ffe6b0; background: rgba(8, 5, 12, 0.94); padding: 6px 10px; border-radius: 10px; border: 1px solid rgba(255, 138, 31, 0.55); }

/* 5b LIGHTS OUT: black, with eyes opening in the dark */
.hw-lights { position: absolute; inset: 0; background: transparent; }
.hw-lights.is-dark { background: #000; }
.hw-le { position: absolute; width: 38px; height: 12px; margin: -6px 0 0 -19px; opacity: 0;
  background: radial-gradient(circle at 22% 50%, #fff2a0 0 2px, #ffb020 3px, rgba(255, 90, 0, 0.5) 5px, transparent 7px),
              radial-gradient(circle at 78% 50%, #fff2a0 0 2px, #ffb020 3px, rgba(255, 90, 0, 0.5) 5px, transparent 7px); }
.hw-lights.is-dark .hw-le { animation: hw-le 2s steps(1, end) var(--d, 0s) both; }
@keyframes hw-le { 0% { opacity: 0; } 15% { opacity: 1; } 55% { opacity: 0.05; } 60% { opacity: 1; } 100% { opacity: 1; } }

/* 5c THE 666 EMBER (display only) */
html.theme-halloween #header-ember-value.hw-666 { color: #ff2a1a; text-shadow: 0 0 8px rgba(255, 0, 0, 0.95); }

/* 5d THE MOON's wink: the moon takes its own tap (a bigger box than the moon), never the banner's reel */
.hw-qbanner .hw-qb-moon { pointer-events: auto; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.hw-qbanner .hw-qb-moon::after { content: ""; position: absolute; inset: -12px; }
.hw-qbanner .hw-qb-moon.hw-qb-moon--jack { background: none; box-shadow: 0 0 16px 5px rgba(255, 138, 31, 0.7); }
.hw-moonface { position: absolute; inset: -3px; width: calc(100% + 6px); height: calc(100% + 6px); display: block; animation: hw-mf-pop 0.3s cubic-bezier(0.3, 1.6, 0.5, 1) both; }
.hw-mf-l { transform-origin: 8px 8.5px; animation: hw-wink 2.4s ease-in-out both; }
@keyframes hw-mf-pop { from { transform: scale(0.3) rotate(-40deg); } to { transform: scale(1) rotate(0); } }
@keyframes hw-wink { 0%, 38% { transform: scaleY(1); } 46%, 60% { transform: scaleY(0.12); } 68%, 100% { transform: scaleY(1); } }

/* 5e THE SKELETON HAND: up out of the last task section's bottom edge, a wave, and down */
.hw-hand-clip { position: absolute; width: 60px; height: 96px; margin-left: -30px; overflow: hidden; }
.hw-hand { position: absolute; left: 0; bottom: 0; width: 60px; height: 100px; transform-origin: 50% 100%; transform: translateY(100%);
  filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.9)); animation: hw-hand 5s ease-in-out forwards; }
.hw-hand svg { width: 100%; height: 100%; display: block; }
@keyframes hw-hand { 0% { transform: translateY(100%); } 18% { transform: translateY(6%); } 30% { transform: translateY(5%) rotate(-12deg); } 42% { transform: translateY(5%) rotate(12deg); }
  54% { transform: translateY(5%) rotate(-12deg); } 66% { transform: translateY(5%) rotate(10deg); } 78% { transform: translateY(6%) rotate(0); } 100% { transform: translateY(100%); } }

/* 2. THE REAPER POKE: the portrait takes quick taps without a zoom; the candle flares, the crows scatter, his line */
html.theme-halloween .qs-boss-strip[data-hw-face] .qs-boss-portrait-wrap { touch-action: manipulation; -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; }
html.theme-halloween .qs-boss-strip.hw-poked .hw-face-glow { animation: hw-flare 1.6s ease-out; }
html.theme-halloween .qs-boss-strip.hw-poked .hw-crow { opacity: 0; transition: opacity 0.12s; }
@keyframes hw-flare { 0% { opacity: 1; filter: brightness(3.2) saturate(1.4); } 40% { opacity: 1; filter: brightness(2); } 100% { opacity: 0.85; filter: none; } }
.hw-poke-crow { position: absolute; width: 44px; height: 36px; margin: -18px 0 0 -22px; }
.hw-poke-crow svg, .hw-poke-crow img { width: 100%; height: 100%; display: block; object-fit: contain; }
.hw-poke-line { position: absolute; left: 24px; right: 24px; padding: 6px 8px; border-radius: 10px; background: rgba(6, 3, 2, 0.62); text-align: center; transform: translateY(-50%); opacity: 0;
  font: 700 18px/1.3 'Cinzel', serif; color: #ffd9a0; text-shadow: 0 0 10px rgba(255, 120, 20, 0.95), 0 0 2px #000, 0 2px 3px #000; animation: hw-poke-line 3.2s ease-out forwards; }
@keyframes hw-poke-line { 0% { opacity: 0; transform: translateY(-30%) scale(0.9); } 8% { opacity: 1; transform: translateY(-50%) scale(1.08); } 14% { transform: translateY(-50%) scale(1); } 80% { opacity: 1; } 100% { opacity: 0; transform: translateY(-80%); } }

/* 1. THE LANTERN GOES OUT: the Reaper's Victory Reveal opens with its own beat; the reveal's own
   entrances wait for it (each keeps its own style.css timing, shifted by the beat's 2.6 s) */
html.theme-halloween .qs-victory-overlay.hw-kill .qsv-flash { animation-delay: 2.7s; }
html.theme-halloween .qs-victory-overlay.hw-kill .qsv-portrait { animation-delay: 2.95s; }
html.theme-halloween .qs-victory-overlay.hw-kill .qsv-eyebrow { animation-delay: 3s; }
html.theme-halloween .qs-victory-overlay.hw-kill .qsv-title { animation-delay: 3.15s; }
html.theme-halloween .qs-victory-overlay.hw-kill .qsv-boss-name { animation-delay: 3.65s; }
html.theme-halloween .qs-victory-overlay.hw-kill .qsv-hint { animation-delay: 4.3s; }
.hw-killfx { position: absolute; inset: 0; z-index: 20; pointer-events: none; overflow: hidden; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(ellipse at 50% 42%, rgba(48, 14, 0, 0.7), rgba(0, 0, 0, 0.96) 70%); animation: hw-kf-out 2.6s linear forwards; }
.hw-killfx * { pointer-events: none; }
.hw-killfx.hw-killfx--solo { position: fixed; z-index: 7550; }
@keyframes hw-kf-out { 0%, 82% { opacity: 1; } 100% { opacity: 0; } }
.hw-kf-head { position: absolute; left: 50%; top: 38%; width: 150px; height: 140px; margin: -70px 0 0 -75px; opacity: 0; animation: hw-kf-head 0.62s cubic-bezier(0.3, 0, 0.6, 1) forwards; }
.hw-kf-head .hw-jack { width: 100%; height: 100%; display: block; }
@keyframes hw-kf-head { 0% { transform: scale(0.6); opacity: 0; } 30% { transform: scale(1.05); opacity: 1; } 70% { transform: scale(1) rotate(-4deg); opacity: 1; filter: brightness(1.6); }
  86% { transform: scale(1.35); opacity: 1; filter: brightness(3); } 100% { transform: scale(1.7); opacity: 0; } }
.hw-kf-bits { position: absolute; left: 50%; top: 38%; width: 0; height: 0; }
.hw-kf-bits i { position: absolute; left: 0; top: 0; opacity: 0; will-change: transform, opacity; }
.hw-kf-bits .hw-seed { width: 6px; height: 10px; margin: -5px 0 0 -3px; border-radius: 50% 50% 50% 50% / 62% 62% 38% 38%; background: linear-gradient(180deg, #fffaf0, #eadbb0); }
.hw-kf-bits .hw-corn { width: 8px; height: 10px; margin: -5px 0 0 -4px; clip-path: polygon(50% 100%, 0 0, 100% 0); background: linear-gradient(180deg, #fffbe8 0 30%, #ff9a1f 30% 68%, #ffd23f 68% 100%); }
.hw-kf-bits .hw-kf-flame { width: 10px; height: 15px; margin: -7px 0 0 -5px; border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
  background: radial-gradient(ellipse at 50% 70%, #fff6c2, #ffb030 45%, #ff5a10 80%); box-shadow: 0 0 12px rgba(255, 140, 30, 0.95); }
.hw-kf-words { position: relative; z-index: 2; padding: 0 14px; text-align: center; opacity: 0;
  font: 700 clamp(40px, 13vw, 78px)/1.04 'Cinzel', serif; letter-spacing: 0.04em; color: #ffcf7a;
  text-shadow: 0 0 22px rgba(255, 120, 20, 0.95), 0 0 60px rgba(255, 80, 0, 0.6), 0 4px 6px #000; animation: hw-kf-words 2.05s cubic-bezier(0.2, 0.8, 0.2, 1) 0.55s forwards; }
.hw-kf-words span { display: inline-block; }
@keyframes hw-kf-words { 0% { opacity: 0; transform: scale(1.8); letter-spacing: 0.3em; } 16% { opacity: 1; transform: scale(1); letter-spacing: 0.04em; } 82% { opacity: 1; } 100% { opacity: 0; transform: scale(0.96); } }

/* the bat bursts (the loot popup's, the moments', the kill's): out from the middle, then gone */
.hw-lbats, .hw-mbats, .hw-kbats { position: absolute; left: 50%; top: 50%; width: 0; height: 0; pointer-events: none; }
.hw-lbats { z-index: 0; }
.hw-mbats { z-index: -1; top: 24%; }
.hw-kbats { z-index: 1; top: 38%; }
.hw-bb { position: absolute; left: 0; top: 0; width: var(--s, 28px); height: calc(var(--s, 28px) * 0.47); opacity: 0; }

/* 4. THE POPUPS: the loot popup's cobwebbed frame and candle glow, under its words (the card is
   its own stack, so the frame paints above its ground and below every line, number and button) */
html.theme-halloween .loot-popup { isolation: isolate; z-index: 1; border-color: rgba(255, 138, 31, 0.6);
  box-shadow: 0 0 30px rgba(255, 120, 20, 0.42), 0 0 80px rgba(255, 90, 10, 0.2), inset 0 0 26px rgba(255, 120, 20, 0.16), 0 12px 50px rgba(0, 0, 0, 0.8); }
html.theme-halloween .loot-popup::before { content: ""; position: absolute; z-index: -1; left: 0; top: 0; width: 96px; height: 96px; pointer-events: none; border-top-left-radius: inherit;
  background: var(--hw-web-img) left top / contain no-repeat; opacity: 0.6; animation: hw-candle-op 2.6s steps(1, end) infinite; }
html.theme-halloween .loot-popup::after { content: ""; position: absolute; z-index: -1; right: 0; bottom: 0; width: 84px; height: 84px; pointer-events: none; transform: rotate(180deg);
  background: var(--hw-web-img) left top / contain no-repeat; opacity: 0.5; }
/* the moments' shared frame: candlelit edges and fog along the bottom, under every word (z -1 in the moment's own stack; the reel is left alone) */
html.theme-halloween .mn-overlay:not(.mn-reel)::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(0deg, rgba(190, 200, 225, 0.24), rgba(190, 200, 225, 0.08) 11%, transparent 24%),
              radial-gradient(ellipse 55% 42% at 0% 52%, rgba(255, 120, 20, 0.22), transparent 70%),
              radial-gradient(ellipse 55% 42% at 100% 52%, rgba(255, 120, 20, 0.22), transparent 70%);
  box-shadow: inset 0 0 70px rgba(255, 110, 20, 0.3); animation: hw-candle-op 2.6s steps(1, end) infinite; }

/* 7. THE DAILY JUMP SCARE: an old-TV glitch (scanlines, static, a vertical roll, the app stuttering
   under it, 0.4 s), then the picture SLAMS in with a jolt (0.6 s), then gone at once */
.hw-scare { position: absolute; inset: 0; }
.hw-tv { position: absolute; inset: 0; overflow: hidden; background: rgba(8, 8, 10, 0.55); }
.hw-tv-lines { position: absolute; inset: 0; background: repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.6) 0 2px, rgba(255, 255, 255, 0.07) 2px 4px); }
.hw-tv-static { position: absolute; inset: -50%; opacity: 0.5; animation: hw-static 0.2s steps(4, end) infinite;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.hw-tv-band { position: absolute; left: 0; right: 0; top: -25%; height: 25%; background: linear-gradient(rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0)); animation: hw-tv-band 0.4s linear forwards; }
@keyframes hw-static { 0% { transform: translate(0, 0); } 25% { transform: translate(-10%, 5%); } 50% { transform: translate(8%, -6%); } 75% { transform: translate(-4%, 9%); } }
@keyframes hw-tv-band { from { transform: translateY(0); } to { transform: translateY(520%); } }
html.theme-halloween.hw-roll #screen-app { animation: hw-vroll 0.4s steps(6, end) forwards; }
@keyframes hw-vroll { 0% { transform: translateY(0); } 30% { transform: translateY(-14%) skewX(2deg); } 31% { transform: translateY(-4%); } 100% { transform: translateY(-38%); } }
.hw-scare-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; }
.hw-scare.is-slam .hw-tv { display: none; }
.hw-scare.is-slam { background: #000; }
.hw-scare.is-slam .hw-scare-img { opacity: 1; animation: hw-slam 0.6s cubic-bezier(0.2, 0.9, 0.2, 1) forwards; }
.hw-scare-img.hw-scare-img--fallback { object-position: 50% 26%; filter: brightness(0.62) contrast(1.9) saturate(1.35) hue-rotate(-10deg); }
.hw-scare.is-slam .hw-scare-img.hw-scare-img--fallback { animation-name: hw-slam-fb; }
@keyframes hw-slam { 0% { transform: scale(1.4); } 12% { transform: scale(1) translate(-9px, 6px); } 22% { transform: translate(8px, -6px); } 34% { transform: translate(-4px, 3px); } 50%, 100% { transform: none; } }
@keyframes hw-slam-fb { 0% { transform: scale(2.2); } 12% { transform: scale(1.55) translate(-9px, 6px); } 22% { transform: scale(1.55) translate(8px, -6px); } 34% { transform: scale(1.55) translate(-4px, 3px); } 50%, 100% { transform: scale(1.55); } }

/* ---------------------------------------------------------------- round 3 (Oct 25): the app's own art in costume */
/* The <img> swaps are halloween.js dressArt (ART_SWAPS). These are the stylesheet
   backgrounds: Groat's study card and cart card, the Road's blurred sky and the
   Merchant strip on Quests. Listed = on (html.hw-art-groat / hw-art-roads); the
   same positions and gradients as css/style.css, only the picture changes. */
html.theme-halloween.hw-art-groat .rd-gcard-portrait { background-image: url('../assets/halloween/merchant/groat.png'); }
html.theme-halloween.hw-art-groat .rd-gkcard {
  background-image:
    linear-gradient(180deg, rgba(10, 8, 4, 0.02) 0%, rgba(10, 8, 4, 0.08) 48%, rgba(14, 10, 5, 0.8) 76%, #120d06 98%),
    url('../assets/halloween/merchant/groat.png');
}
html.theme-halloween.hw-art-roads #rd-sky-art { background-image: url('../assets/halloween/road/road_day.jpg'); }
html.theme-halloween.hw-art-roads body.rd-phase-night #rd-sky-art { background-image: url('../assets/halloween/road/road_night.jpg'); }
html.theme-halloween.hw-art-roads body.rd-phase-dusk #rd-sky-art { background-image: url('../assets/halloween/road/road_dusk.jpg'); }
html.theme-halloween.hw-art-roads .rd-arrcard-strip--eve { background-image: url('../assets/halloween/road/road_dusk.jpg'); }
html.theme-halloween.hw-art-roads .rd-arrcard-strip--day { background-image: url('../assets/halloween/road/road_day.jpg'); }

/* ---------------------------------------------------------------- round 3: the Hollow Week Secrets */
/* The drawer row (last in the list) and its count. */
.hw-secrets-btn .hw-secrets-icon { color: var(--hw-pumpkin); flex: 0 0 auto; }
.hw-secrets-btn { border-color: rgba(255, 138, 31, 0.22); }
.hw-secrets-btn .hw-secrets-n { margin-left: auto; white-space: nowrap; font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em; color: #b9a98c; }
/* The page: calm and readable (a utility page, not decor). Above the drawer
   (301) and the Settings screen (302), under every moment and popup. */
.hw-secrets {
  position: fixed; inset: 0; z-index: 310; display: flex; flex-direction: column;
  background: linear-gradient(180deg, #120a1a 0%, #0a0710 100%);
  color: #e6dccb; animation: hw-sx-in 0.22s ease-out both;
}
.hw-secrets.is-away { visibility: hidden; pointer-events: none; }
.hw-secrets.is-closing { opacity: 0; transition: opacity 0.2s ease; }
@keyframes hw-sx-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.hw-sx-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  padding: calc(18px + env(safe-area-inset-top, 0px)) 16px 8px;
  border-bottom: 1px solid rgba(255, 138, 31, 0.18);
}
.hw-sx-k { font-family: 'Cinzel', serif; font-size: 11.5px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: var(--hw-pumpkin); }
.hw-sx-t { font-family: 'Cinzel', serif; font-size: 24px; font-weight: 700; letter-spacing: 0.04em; color: #f2e6cf; margin-top: 2px; }
.hw-sx-x {
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%; border: 1px solid rgba(239, 230, 210, 0.22);
  background: rgba(255, 255, 255, 0.04); color: #e6dccb; font-size: 26px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.hw-sx-count { padding: 12px 16px 0; font-family: 'Cinzel', serif; font-size: 14px; font-weight: 700; letter-spacing: 0.06em; color: var(--hw-candle); }
.hw-sx-intro { margin: 4px 16px 8px; font-family: 'Crimson Pro', serif; font-weight: 500; font-size: 16px; line-height: 1.35; color: #b9ad99; }
.hw-sx-list { flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 4px 16px calc(24px + env(safe-area-inset-bottom, 0px)); }
.hw-sx-row {
  display: flex; align-items: center; gap: 12px; padding: 12px 12px; margin-bottom: 8px;
  border-radius: 10px; border: 1px solid rgba(239, 230, 210, 0.08); background: rgba(255, 255, 255, 0.025);
}
.hw-sx-row.is-seen { border-color: rgba(255, 138, 31, 0.24); background: rgba(255, 138, 31, 0.05); }
.hw-sx-txt { flex: 1 1 auto; min-width: 0; }
.hw-sx-name { font-family: 'Cinzel', serif; font-size: 15px; font-weight: 700; letter-spacing: 0.03em; color: #f2e6cf; }
.hw-sx-row:not(.is-seen) .hw-sx-name { color: #8a8070; letter-spacing: 0.2em; }
.hw-sx-line { margin: 3px 0 0; font-family: 'Crimson Pro', serif; font-weight: 500; font-size: 16px; line-height: 1.32; color: #d2c7b4; }
.hw-sx-row:not(.is-seen) .hw-sx-line { font-style: italic; color: #9a9080; }
.hw-sx-note { margin: 4px 0 0; font-family: 'Crimson Pro', serif; font-weight: 500; font-size: 15px; color: #e0a070; }
.hw-sx-replay {
  flex: 0 0 auto; min-width: 76px; height: 38px; padding: 0 12px; border-radius: 19px;
  border: 1px solid rgba(255, 138, 31, 0.55); background: rgba(255, 138, 31, 0.1); color: var(--hw-pumpkin-hi);
  font-family: 'Cinzel', serif; font-size: 12px; font-weight: 700; letter-spacing: 0.08em; cursor: pointer;
}
.hw-sx-replay:active { background: rgba(255, 138, 31, 0.22); }
