/* The Halloween landing page (/halloween), a night scene on campaign.css:
   the pitch under stars, a moon, and bats beside a block of the map with a
   ghost peeking over it, the neighborhood's lit windows and
   jack-o'-lanterns across the page, then the film, three points, and the
   apps. Only this page is dark. At the owner's request (2026-10-30) its
   night is purple fading to near black, colors the brand doesn't have, so
   they live here as page-only properties; everything else is the brand's
   tokens and logo accents. */
@layer components {
  body.halloween-surface {
    --halloween-sky: #1d1433;
    --halloween-dusk: #120d20;
    --halloween-night: #0a0810;
    --halloween-house: #06050a;
    --campaign-heading: var(--color-white);
    --campaign-accent: var(--color-orange);
    --campaign-lede: rgb(244 238 227 / 88%);
    --campaign-copy: rgb(244 238 227 / 82%);
    --campaign-legal: rgb(244 238 227 / 70%);
    --campaign-rule: rgb(244 238 227 / 14%);
    --campaign-glow: rgb(252 121 83 / 35%);
    --campaign-map-shadow: 0 1.5rem 4rem rgb(0 0 0 / 55%), 0 0 0 .0625rem rgb(244 238 227 / 12%);

    color-scheme: dark;
    background:
      radial-gradient(38rem 28rem at 85% 0, rgb(163 139 218 / 30%), transparent),
      radial-gradient(26rem 18rem at 10% 4rem, rgb(163 139 218 / 12%), transparent),
      linear-gradient(var(--halloween-sky), var(--halloween-dusk) 18rem, var(--halloween-night) 36rem);
    background-color: var(--halloween-night);
    background-repeat: no-repeat;
    color: var(--color-ivory);
  }

  .halloween-stars {
    position: absolute;
    z-index: -1;
    inset: 0 0 auto;
    inline-size: 100%;
    block-size: min(46rem, 100svh);
    pointer-events: none;
  }

  .halloween-star {
    fill: var(--color-ivory);
  }

  .halloween-star.is-twinkling {
    animation: halloween-twinkle var(--twinkle-length, 3.6s) ease-in-out var(--twinkle-delay, 0s) infinite;
  }

  .halloween-tail-start {
    stop-color: var(--color-ivory);
    stop-opacity: 0;
  }

  .halloween-tail-end {
    stop-color: var(--color-ivory);
    stop-opacity: .9;
  }

  /* Hidden most of the time; one streak every 16 seconds. */
  .halloween-shooting-star {
    stroke-width: 1.6;
    stroke-linecap: round;
    opacity: 0;
    animation: halloween-shooting 16s linear 4s infinite;
  }

  /* The wordmark is navy artwork, so it sits on an ivory badge. */
  .halloween-surface .campaign-brand {
    display: inline-flex;
    padding: .4rem 1.1rem .4rem .45rem;
    background: var(--color-ivory);
    box-shadow: 0 .5rem 2rem rgb(252 121 83 / 28%);
  }

  .halloween-surface .campaign-brand:focus-visible {
    outline: .18rem solid var(--color-orange);
    outline-offset: .2rem;
  }

  .halloween-sky {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
  }

  .halloween-moon {
    flex: 0 0 auto;
    inline-size: clamp(8.5rem, 34vw, 12rem);
    block-size: auto;
  }

  .halloween-moon-glow-inner {
    stop-color: var(--color-ivory);
    stop-opacity: .28;
  }

  .halloween-moon-glow-outer {
    stop-color: var(--color-ivory);
    stop-opacity: 0;
  }

  .halloween-moon-halo {
    animation: halloween-breathe 7s ease-in-out infinite alternate;
  }

  .halloween-moon-face {
    fill: var(--color-ivory);
  }

  .halloween-moon-crater {
    fill: rgb(16 38 83 / 8%);
  }

  /* Each bat drifts in its own small loop, and the dark one glides back
     and forth across the moon. Their wings beat by squashing the body. */
  .halloween-bat {
    fill: var(--color-logo-purple);
    animation: halloween-bat-loop 16s ease-in-out var(--bat-delay, 0s) infinite;
  }

  .halloween-bat.is-dark {
    fill: var(--color-navy-wordmark);
    animation: halloween-bat-glide 22s ease-in-out infinite alternate;
  }

  .halloween-bat-wings {
    transform-box: fill-box;
    transform-origin: center;
    animation: halloween-wingbeat var(--bat-wingbeat, .8s) ease-in-out infinite alternate;
  }

  .halloween-ghost {
    position: absolute;
    z-index: 1;
    inset-block-start: -3.1rem;
    inset-inline-end: .75rem;
    inline-size: 4.5rem;
    block-size: auto;
    filter: drop-shadow(0 .5rem 1rem rgb(244 238 227 / 22%));
    animation: halloween-float 3.2s ease-in-out infinite alternate;
  }

  .halloween-ghost-body {
    fill: var(--color-ivory);
  }

  .halloween-ghost-eye {
    fill: var(--color-navy);
  }

  .halloween-surface .campaign-film .about-film-video {
    border-color: rgb(244 238 227 / 14%);
    box-shadow: 0 1.5rem 4rem rgb(0 0 0 / 55%);
  }

  /* The full width of the page, whatever the column's width. */
  .halloween-street {
    display: block;
    inline-size: 100vw;
    max-inline-size: none;
    block-size: clamp(10rem, 20vw, 16rem);
    opacity: .7;
    margin-block-start: clamp(1.5rem, 4vh, 3rem);
    margin-inline: calc(50% - 50vw);
  }

  .halloween-glow-top {
    stop-color: var(--color-logo-purple);
    stop-opacity: 0;
  }

  .halloween-glow-bottom {
    stop-color: var(--color-logo-purple);
    stop-opacity: .1;
  }

  .halloween-house {
    fill: var(--halloween-house);
  }

  .halloween-window {
    fill: rgb(244 238 227 / 4%);
  }

  .halloween-window.is-lit {
    fill: var(--color-logo-yellow);
    opacity: .45;
    filter: drop-shadow(0 0 .15rem rgb(252 190 69 / 30%));
  }

  .halloween-window.is-switching {
    animation: halloween-lights 14s ease-in-out var(--switch-delay, 0s) infinite;
  }

  /* The spider on the map drops once on its thread as the page opens,
     bounces, and climbs back, then lets out a little thread and climbs
     back from then on. */
  .halloween-spider-thread {
    transform-box: fill-box;
    transform-origin: top;
    animation:
      halloween-thread-drop 7s .6s both,
      halloween-thread 4.5s ease-in-out 7.6s infinite alternate;
  }

  .halloween-spider {
    animation:
      halloween-drop 7s .6s both,
      halloween-dangle 4.5s ease-in-out 7.6s infinite alternate;
  }

  .halloween-door {
    fill: var(--color-orange);
    opacity: .25;
  }

  .halloween-ground {
    fill: var(--halloween-night);
  }

  .halloween-curb {
    stroke: rgb(163 139 218 / 22%);
    stroke-width: 1.5;
  }

  .halloween-pumpkin-stem {
    fill: var(--color-logo-green-dark);
  }

  .halloween-pumpkin-rib,
  .halloween-pumpkin-body {
    fill: var(--color-orange);
    stroke: var(--color-orange-dark);
    stroke-width: 1.6;
  }

  .halloween-pumpkin-face {
    fill: var(--color-logo-yellow);
    animation: halloween-flicker 2.8s steps(1, end) infinite;
  }

  .halloween-street > g:nth-last-of-type(2) .halloween-pumpkin-face {
    animation-delay: -.9s;
  }

  .halloween-street > g:nth-last-of-type(1) .halloween-pumpkin-face {
    animation-delay: -1.7s;
  }

  @keyframes halloween-float {
    to {
      transform: translateY(-.45rem) rotate(-3deg);
    }
  }

  @keyframes halloween-twinkle {
    50% {
      opacity: .15;
    }
  }

  @keyframes halloween-shooting {
    0% { opacity: 0; transform: translateX(-60px); }
    1.5% { opacity: 1; }
    6% { opacity: 0; transform: translateX(260px); }
    100% { opacity: 0; transform: translateX(260px); }
  }

  @keyframes halloween-breathe {
    from { opacity: .75; }
    to { opacity: 1; }
  }

  @keyframes halloween-bat-loop {
    0%, 100% { transform: translate(0, 0); }
    25% { transform: translate(3px, -2px); }
    50% { transform: translate(6px, 0); }
    75% { transform: translate(3px, 2px); }
  }

  @keyframes halloween-bat-glide {
    from { transform: translate(-6px, 1px); }
    to { transform: translate(6px, -1px); }
  }

  @keyframes halloween-wingbeat {
    to { transform: scaleY(.75); }
  }

  /* On most of the time, briefly off, then on again. */
  @keyframes halloween-lights {
    0%, 55% { opacity: .45; }
    60%, 78% { opacity: .05; }
    83%, 100% { opacity: .45; }
  }

  @keyframes halloween-thread {
    to { transform: scaleY(1.3); }
  }

  /* One slow, smooth fall of about three seconds, a short hang, and an
     equally slow climb. The thread is 21 units long, so the spider's drop
     of 35 units, into the first row of homes, stretches it to 56. */
  @keyframes halloween-thread-drop {
    0% { transform: scaleY(1); animation-timing-function: ease-in-out; }
    45%, 55% { transform: scaleY(2.667); animation-timing-function: ease-in-out; }
    100% { transform: scaleY(1); }
  }

  @keyframes halloween-drop {
    0% { transform: translateY(0); animation-timing-function: ease-in-out; }
    45%, 55% { transform: translateY(35px); animation-timing-function: ease-in-out; }
    100% { transform: translateY(0); }
  }

  @keyframes halloween-dangle {
    to { transform: translateY(6.3px); }
  }

  /* A candle's uneven flicker. */
  @keyframes halloween-flicker {
    0%, 100% { opacity: 1; }
    38% { opacity: .78; }
    42% { opacity: .95; }
    70% { opacity: .84; }
    74% { opacity: 1; }
  }

  @media (prefers-reduced-motion: reduce) {
    .halloween-ghost,
    .halloween-star.is-twinkling,
    .halloween-moon-halo,
    .halloween-bat,
    .halloween-bat-wings,
    .halloween-window.is-switching,
    .halloween-spider-thread,
    .halloween-spider,
    .halloween-pumpkin-face {
      animation: none;
    }

    .halloween-shooting-star {
      display: none;
    }
  }

  @media (forced-colors: active) {
    .halloween-surface .campaign-brand {
      border: .0625rem solid CanvasText;
    }
  }
}

/* The public pages' header and footer rules in interest.css sit outside any
   layer, so a layered rule can't override them. These do, with more
   specific selectors, since interest.css loads after this file. */
.halloween-surface .site-header .campaign-brand {
  border-radius: var(--radius-panel);
}

.halloween-surface .campaign-header .header-link {
  color: var(--color-ivory);
}

.halloween-surface .site-footer {
  border-color: rgb(244 238 227 / 14%);
  color: rgb(244 238 227 / 72%);
}

.halloween-surface .site-footer a {
  color: rgb(244 238 227 / 72%);
}

.halloween-surface .site-footer a:hover {
  color: var(--color-ivory);
}
