/* ==========================================================================
   Occasion pack: HALLOWEEN
   ==========================================================================
   Loaded by includes/occasion.php only while OCCASION=halloween in .env.
   Ported from references/halloween-touchups.html (v3, homepage only) and
   made sitewide; the markup is all injected by script.js.

   Ground rules (assets/occasions/README.md):
   - Every class and keyframe is ours: hw-* or occ-*. Nothing else on the site
     uses either prefix.
   - The FEW rules that touch an existing site class are all in section 9 and
     all scoped under html.occ-halloween, so they exist only while the pack
     is on. Do not add site-class rules anywhere else in this file.
   - Decorations are absolute or fixed, pointer-events: none and aria-hidden.
     The only thing in normal flow is the graveyard band above the footer.

   1. Tokens + base       6. Real Stories ghost (homepage)
   2. Fixed layers        7. Graveyard band + footer
   3. Hero                8. Guide bat
   4. Cobwebs + spiders   9. Overrides of site classes (scoped)
   5. Homepage props     10. Tablet / mobile / reduced motion
   ========================================================================== */

/* ---------- 1. Tokens + base ---------- */
:root { --hw-ink: #1e1e1e; --hw-web: rgba(30, 30, 30, .16); --hw-string: rgba(30, 30, 30, .45); --hw-glow: #ffb020; --hw-soil: #1e1e1e; }

/* Line art on a dark section (script.js asks Occ.dark()): light ink instead.
   This is what makes the ad-format pages work without per-page colours. */
.hw-on-dark { --hw-ink: #d9d4e6; --hw-web: rgba(255, 255, 255, .22); --hw-string: rgba(255, 255, 255, .4); }
.hw-on-dark .hw-thread { background: linear-gradient(rgba(255, 255, 255, .05), rgba(255, 255, 255, .45)) !important; }

.occ-deco { position: absolute; pointer-events: none; z-index: 2; }
.occ-deco svg { display: block; width: 100%; height: auto; overflow: visible; }

/* ---------- 2. Fixed layers (appended to <body>) ---------- */
/* Soft glowing corners; the top pair sits just under the header */
.hw-corners { position: fixed; inset: 0; z-index: 40; pointer-events: none; overflow: hidden; transition: opacity .6s ease; }
.hw-corners i { position: absolute; width: 44vmin; height: 44vmin; border-radius: 50%; animation: hw-corner 7s ease-in-out infinite; }
.hw-corners i:nth-child(1) { left: -22vmin; top: calc(96px - 22vmin); background: radial-gradient(closest-side, rgba(255, 122, 26, .42), rgba(255, 122, 26, 0)); }
.hw-corners i:nth-child(2) { right: -22vmin; top: calc(96px - 22vmin); background: radial-gradient(closest-side, rgba(150, 80, 255, .36), rgba(150, 80, 255, 0)); animation-delay: -1.75s; }
.hw-corners i:nth-child(3) { right: -22vmin; bottom: -22vmin; background: radial-gradient(closest-side, rgba(255, 122, 26, .42), rgba(255, 122, 26, 0)); animation-delay: -3.5s; }
.hw-corners i:nth-child(4) { left: -22vmin; bottom: -22vmin; background: radial-gradient(closest-side, rgba(150, 80, 255, .36), rgba(150, 80, 255, 0)); animation-delay: -5.25s; }
@keyframes hw-corner { 0%,100% { opacity: .55; transform: scale(.9); } 50% { opacity: 1; transform: scale(1.12); } }
.hw-corners.hw-off { opacity: 0; }   /* hidden while the graveyard / footer is on screen */

/* Ambient + click bats canvas */
.hw-sky { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 9000; pointer-events: none; }

/* ---------- 3. Hero ----------
   One clipping layer of our own instead of touching the hero's overflow.
   --hw-top pushes it below a header that overlays the hero (the ad-format
   pages' fixed header); 0 elsewhere.

   NOTHING GOES BEHIND THE HERO CONTENT. The reference did that with
   z-index -1 + isolation: isolate on the hero, and isolation made .ta-hero a
   stacking context, which trapped the ad-format pages' flown ad card under
   the next section. The layer is above the content instead, and the moon
   glow BLENDS: multiply on a light hero (white stays tinted, dark text stays
   dark, exactly as if the glow were behind it), screen on a dark one. */
.hw-layer { position: absolute; left: 0; right: 0; top: var(--hw-top, 0); bottom: 0; overflow: hidden; pointer-events: none; }
.hw-layer > * { position: absolute; }

.hw-moonglow { top: 40px; left: 50%; width: 560px; height: 560px; margin-left: -280px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 186, 70, .22) 0%, rgba(255, 186, 70, 0) 62%);
  mix-blend-mode: multiply;
  animation: hw-pulse 6s ease-in-out infinite; }
.hw-on-dark .hw-moonglow { mix-blend-mode: screen; }
@keyframes hw-pulse { 0%,100% { transform: scale(1); opacity: .8; } 50% { transform: scale(1.08); opacity: 1; } }

/* Garland of pumpkins + sleeping bats, strung between the cobwebs */
.hw-garland { top: 0; left: 7%; right: 7%; height: 72px; }
.hw-garland svg { display: block; width: 100%; height: auto; overflow: visible; }
.hw-garland .hw-string { position: absolute; inset: 0; width: 100%; height: 100%; }
.hw-hang { position: absolute; width: 24px; margin-left: -12px; transform-origin: 50% 0; animation: hw-swing 3.6s ease-in-out infinite; }
.hw-hang i { display: block; width: 1px; height: 10px; margin: 0 auto; background: var(--hw-string); }
.hw-hang--bat { width: 18px; margin-left: -9px; }
@keyframes hw-swing { 0%,100% { transform: rotate(-7deg); } 50% { transform: rotate(7deg); } }
.hw-face { animation: hw-flicker 2.4s infinite; }
@keyframes hw-flicker { 0%,100% { fill: #3b2200; } 40% { fill: #ffd34d; } 44% { fill: #3b2200; } 48% { fill: #ffc233; } 70% { fill: #ffb020; } }

/* ---------- 4. Cobwebs + spiders ---------- */
/* --s sets the size, the corner class mirrors it, tone classes recolour it */
.hw-web { width: var(--s, 170px); }
.hw-web svg { display: block; width: 100%; height: auto; }
.hw-web--tl { top: 0; left: 0; }
.hw-web--tr { top: 0; right: 0; transform: scaleX(-1); }
.hw-web--bl { bottom: 0; left: 0; transform: scaleY(-1); }
.hw-web--br { bottom: 0; right: 0; transform: scale(-1, -1); }
.hw-web--light { --hw-web: rgba(255, 255, 255, .32); }

/* Hero spider dropping on its thread */
.hw-spider { top: 0; left: 22%; width: 26px; transform-origin: top center;
  animation: hw-drop 1.6s cubic-bezier(.3, 1.4, .5, 1) .8s both, hw-sway 5s ease-in-out 2.4s infinite; }
.hw-spider svg, .hw-spider2 svg { display: block; width: 100%; height: auto; overflow: visible; }
.hw-thread { width: 1px; height: 120px; margin: 0 auto; background: linear-gradient(rgba(30, 30, 30, .05), rgba(30, 30, 30, .45)); }
/* Section spiders wait out of sight and drop in when their section scrolls into view */
.hw-spider2 { top: 0; width: 22px; transform-origin: top center; opacity: 0; transform: translateY(-170px); transition: opacity .3s ease; }
.hw-spider2.go { opacity: 1; animation: hw-drop2 1.8s cubic-bezier(.3, 1.4, .5, 1) both, hw-sway 5.5s ease-in-out 1.8s infinite; }
@keyframes hw-drop2 { from { transform: translateY(-170px); } to { transform: translateY(0); } }
.hw-legs { transform-origin: 50% 40%; animation: hw-wiggle 1.2s ease-in-out infinite; }
@keyframes hw-drop   { from { transform: translateY(-140px); } to { transform: translateY(0); } }
@keyframes hw-sway   { 0%,100% { transform: rotate(0) translateY(0); } 50% { transform: rotate(4deg) translateY(14px); } }
@keyframes hw-wiggle { 0%,100% { transform: scaleX(1); } 50% { transform: scaleX(.88); } }

/* ---------- 5. Homepage props ---------- */
/* Ghost peeking from behind the Ad Traffic Estimator. The clip box ends at
   the card's top edge (script.js sets its top), so the part of the ghost
   "behind" the card is simply cut off; the card itself is never touched.
   The ghost's 54px rise above the card is the clip's height minus its top. */
.hw-ghostclip { right: 110px; width: 74px; height: 100px; overflow: hidden; }
.hw-ghost { position: absolute; left: 0; top: 46px; width: 100%; animation: hw-peek 6s ease-in-out infinite; }
.hw-ghost svg { display: block; width: 100%; height: auto; overflow: visible; }
.hw-eyes { animation: hw-blink 5s infinite; transform-origin: 50% 46%; }
@keyframes hw-peek  { 0%,100% { transform: translateY(18px) rotate(-4deg); } 45%,60% { transform: translateY(0) rotate(3deg); } }
@keyframes hw-blink { 0%,92%,100% { transform: scaleY(1); } 95% { transform: scaleY(.1); } }

/* Crow perched on the demo CTA card */
.hw-crow { top: -58px; right: 90px; width: 82px; z-index: 4; animation: hw-hop 9s ease-in-out infinite; }
.hw-crow .hw-head { transform-origin: 46px 40px; animation: hw-tilt 7s ease-in-out infinite; }
@keyframes hw-tilt { 0%,70%,100% { transform: rotate(0); } 75%,88% { transform: rotate(-14deg); } }
@keyframes hw-hop  { 0%,40%,52%,100% { transform: translateY(0); } 44% { transform: translateY(-14px); } 48% { transform: translateY(0); } }

/* ---------- 6. Translucent ghost drifting across a section ----------
   The reference clipped the whole section (overflow-x: clip on
   #real-stories); a clipping wrapper of our own keeps the section untouched. */
.hw-driftwrap { inset: 0; overflow: hidden; z-index: 1; }
.hw-drift { position: absolute; top: 18%; left: 0; width: 58px; opacity: .42; animation: hw-drift 34s linear infinite; }
.hw-drift svg { display: block; width: 100%; height: auto; overflow: visible; animation: hw-bob 3s ease-in-out infinite; }
@keyframes hw-drift { from { transform: translateX(-120px) scaleX(-1); } to { transform: translateX(105vw) scaleX(-1); } }
@keyframes hw-bob   { 0%,100% { transform: translateY(0) rotate(-3deg); } 50% { transform: translateY(-22px) rotate(3deg); } }

/* ---------- 7. Graveyard band + footer ---------- */
/* Its own band between the last section and the footer: the one in-flow element */
.hw-horizon { position: relative; height: clamp(84px, 8vw, 150px); margin-bottom: -1px; pointer-events: none; overflow: hidden;
  background-image: radial-gradient(60% 150% at 50% 100%, rgba(255, 140, 50, .34), rgba(255, 140, 50, 0) 70%); }
.hw-horizon svg { position: absolute; left: 0; bottom: 0; width: 100%; height: 100%; display: block; }

/* Footer: fog + glowing eyes. The footer is already a stacking context of
   its own (position: relative; z-index: 2 in the site CSS), so z-index -1
   puts the fog above the footer's background and below its content without
   touching the footer's container. */
.hw-fogwrap { inset: 0; overflow: hidden; z-index: -1; }
.hw-fog { position: absolute; bottom: -30px; left: 0; width: 200%; height: 170px; opacity: .35;
  background:
    radial-gradient(closest-side, rgba(255,255,255,.10), transparent) 0 40px / 380px 140px repeat-x,
    radial-gradient(closest-side, rgba(255,255,255,.07), transparent) 190px 70px / 460px 120px repeat-x;
  animation: hw-fog 46s linear infinite; }
.hw-fog + .hw-fog { animation-duration: 70s; animation-direction: reverse; opacity: .25; bottom: -60px; }
@keyframes hw-fog { to { transform: translateX(-50%); } }
.hw-eyes-dark { top: 38%; right: 3%; width: 46px; animation: hw-blink 4s infinite; }
.hw-eyes-dark ellipse { fill: var(--hw-glow); filter: drop-shadow(0 0 4px var(--hw-glow)); }
.hw-pumpkin { display: inline-block; width: 18px; height: 18px; vertical-align: -3px; margin-right: 6px; }

/* ---------- 8. Guide bat: Register -> "As an Advertiser" -> Get Started ----------
   A canvas-drawn bat, fixed above the register popup (z 999); JS pins it to
   the live button rects every frame. */
.hw-gb { position: fixed; left: 0; top: 0; width: 176px; height: 176px; z-index: 1000; pointer-events: none; opacity: 0;
  transform-origin: 50% 64.5%; transition: opacity .35s ease; will-change: transform;
  filter: drop-shadow(0 0 2px rgba(255, 175, 95, 1)) drop-shadow(0 0 16px rgba(255, 110, 30, .6)); }
.hw-gb canvas { display: block; width: 100%; height: 100%; }
.hw-trail { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 999; pointer-events: none; }

/* Speech bubble that pops next to the guide bat */
.hw-tip { position: fixed; left: 0; top: 0; z-index: 1001; pointer-events: none; white-space: nowrap;
  font: 14px/1.2 Righteous, Barlow, sans-serif; letter-spacing: .02em; color: #fff; background: #1a0f24;
  padding: 9px 14px; border-radius: 14px; border: 1px solid rgba(255, 140, 0, .7);
  box-shadow: 0 10px 24px rgba(0, 0, 0, .35), 0 0 20px rgba(255, 122, 26, .45);
  opacity: 0; transform: scale(.5); transition: opacity .2s ease, transform .4s cubic-bezier(.3, 1.6, .5, 1); }
.hw-tip.on { opacity: 1; transform: none; }
.hw-tip b { color: #ffb020; font-weight: 400; }
.hw-tip::after { content: ""; position: absolute; top: 50%; width: 10px; height: 10px; margin-top: -5px;
  background: inherit; border: inherit; transform: rotate(45deg); }
.hw-tip--l { transform-origin: 100% 50%; }
.hw-tip--l::after { right: -6px; border-left-color: transparent; border-bottom-color: transparent; }
.hw-tip--r { transform-origin: 0 50%; }
.hw-tip--r::after { left: -6px; border-right-color: transparent; border-top-color: transparent; }

/* Pulsing ring on whatever the bat wants you to click next (an outline, so
   it never moves the button) */
.hw-ring { animation: hw-ring 1.5s ease-out infinite; }
@keyframes hw-ring {
  0%   { outline: 2px solid rgba(255, 122, 26, .95); outline-offset: 0; }
  100% { outline: 2px solid rgba(255, 122, 26, 0);   outline-offset: 12px; }
}

/* ---------- 9. Overrides of site classes — ONLY here, ONLY scoped ----------
   Paint-only changes. Never position, z-index, isolation, transform, opacity
   or filter on a site element: those change layout or make a stacking
   context and trap the element's layered content (see §3 and the
   README). */
/* Copyright row: no opaque box and no hard rule, a divider fading out at both
   ends (a border-image, so the row needs no position for a ::before) */
.occ-halloween .footer-wrapper .copyright-wrap { background-color: transparent !important;
  border-image: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, .1) 30%, rgba(255, 255, 255, .1) 70%, rgba(255, 255, 255, 0)) 1; }
.occ-halloween .hero-btn .th-btn:not(.th-send):hover { box-shadow: 0 0 0 4px rgba(255, 140, 0, .25), 0 0 24px rgba(255, 140, 0, .35); }

/* ---------- 10. Tablet / mobile / reduced motion ---------- */
@media (max-width: 991px) {
  .hw-gb { width: 136px; height: 136px; }
  .hw-tip { font-size: 12.5px; padding: 7px 11px; }
  .hw-web { width: calc(var(--s, 170px) * .65); }
  .hw-eyes-dark { display: none; }
  .hw-garland { left: 18%; right: 18%; height: 56px; }
  .hw-hang:nth-child(even) { display: none; }
  .hw-moonglow { width: 360px; height: 360px; margin-left: -180px; }
  .hw-ghostclip { width: 54px; right: 24px; }
  .hw-ghost { top: 60px; }
  .hw-crow { width: 60px; right: 24px; top: -43px; }
  .hw-spider { left: 72%; }
}
@media (max-width: 575px) {
  .hw-web { width: calc(var(--s, 170px) * .5); }
  .hw-garland { left: 12%; right: 12%; }
}
@media (prefers-reduced-motion: reduce) {
  .occ-deco, .occ-deco *, .hw-layer *, .hw-horizon *, .hw-corners i { animation: none !important; }
  .hw-spider2 { opacity: 1; transform: none; }
  .hw-ring { animation: none; outline: 2px solid rgba(255, 122, 26, .9); outline-offset: 3px; }
}
