/* ~ the flickering jack ~
        ___
     .-"   "-.
    /  _   _  \
   |  (o) (o)  |
    \    ^    /
     \ \___/ /
      "-...-"
*/


/* themes.css — seasonal overlay species packs.
   happy halloween: every species is transform/opacity-safe, like a candle
   flame that never burns the layout. the jack watches:
        ___
     .-"   "-.
    /  _   _  \
   |  (o) (o)  |
    \    ^    /
     \ \___/ /
      "-...-"
   Species animate transform/opacity only (compositor-safe), all decor gets
   aria-hidden via themes.js, body.th-paused freezes everything.
   Theme packs keyed by body.th-<name> so holidays swap cleanly. */

/* ============ shared machinery ============ */
body.th-paused .th-species,body.th-paused .th-species *{animation-play-state:paused!important}
.th-species{position:fixed;pointer-events:none}
#th-toggle{position:fixed;bottom:10px;right:10px;z-index:2147483000;font-size:11px;
  letter-spacing:1px;color:#8a7a66;background:rgba(5,2,8,.7);border:1px solid #2a1a10;
  padding:4px 9px;cursor:pointer;font-family:monospace;opacity:.55}
#th-toggle:hover{opacity:1}

/* ============ HALLOWEEN pack (body.th-halloween) ============ */
/* storm-mode lightning: brief blend flashes, double-tap strikes */
.th-lightning{inset:0;z-index:2147482900;background:#cfe8ff;opacity:0;
  mix-blend-mode:screen;animation:thStrike var(--lt,.9s) ease-out forwards}
@keyframes thStrike{0%{opacity:0}8%{opacity:.55}14%{opacity:.1}
  20%{opacity:.4}32%{opacity:.05}100%{opacity:0}}
/* forked bolt — thin jagged gradient line down from sky */
.th-bolt{top:-4vh;height:0;width:3px;z-index:2147482899;opacity:.9;
  background:linear-gradient(180deg,#fff,#cfe8ff 40%,transparent);
  filter:drop-shadow(0 0 12px rgba(207,232,255,.9));
  clip-path:polygon(0 0,100% 0,60% 34%,100% 34%,30% 68%,80% 68%,45% 100%,0 100%);
  animation:thBolt .5s ease-out forwards}
@keyframes thBolt{0%{height:0;opacity:0}15%{height:60vh;opacity:1}
  100%{height:60vh;opacity:0}}
/* shooting star — rare diagonal streak */
.th-star{top:var(--sy,8vh);left:-160px;width:140px;height:2px;z-index:4;
  background:linear-gradient(90deg,transparent,#e8e0d0 60%,#fff);
  transform:rotate(-24deg);opacity:0;animation:thStar 1.4s ease-out forwards}
@keyframes thStar{0%{transform:translate(0,0) rotate(-24deg);opacity:0}
  10%{opacity:.9}100%{transform:translate(120vw,38vh) rotate(-24deg);opacity:0}}
/* parallax fog banks — 3 depths, transform-only */
.th-fog{bottom:-6vh;width:140vw;height:26vh;z-index:3;opacity:var(--fo,.3);
  background:radial-gradient(ellipse 60% 100% at 20% 100%,rgba(191,95,255,.10),transparent),
             radial-gradient(ellipse 55% 90% at 55% 100%,rgba(232,224,208,.14),transparent),
             radial-gradient(ellipse 60% 100% at 85% 100%,rgba(255,117,24,.07),transparent);
  filter:blur(14px);animation:thFog var(--ft,40s) ease-in-out infinite alternate;
  will-change:transform}
@keyframes thFog{0%{transform:translateX(0)}100%{transform:translateX(-22vw)}}
.th-fog.deep{z-index:2;opacity:calc(var(--fo,.3)*.6);animation-duration:calc(var(--ft,40s)*1.7)}
/* haunted skyline — clip-path house + hills, flickering window */
.th-skyline{bottom:0;left:0;right:0;height:16vh;z-index:2;
  background:
   linear-gradient(0deg,#030204 0 62%,transparent),
   radial-gradient(ellipse 30% 90% at 12% 100%,#060307 55%,transparent 56%),
   radial-gradient(ellipse 34% 80% at 88% 100%,#050208 60%,transparent 61%);
  clip-path:polygon(0 100%,0 72%,6% 68%,6% 60%,8% 58%,8% 44%,10% 40%,12% 44%,
    12% 58%,14% 60%,14% 66%,22% 62%,30% 66%,44% 62%,58% 68%,70% 64%,82% 70%,
    100% 66%,100% 100%)}
.th-window{bottom:8.5vh;left:9.2%;width:8px;height:10px;z-index:3;
  background:#ff9a2a;opacity:.7;filter:blur(.4px);
  box-shadow:0 0 10px 3px rgba(255,154,42,.35);
  animation:thFlick 3.1s steps(1) infinite}
@keyframes thFlick{0%,100%{opacity:.75}17%{opacity:.15}23%{opacity:.8}
  41%{opacity:.2}55%{opacity:.9}78%{opacity:.3}}
/* drifting leaves — autumn tumble */
.th-leaf{top:-30px;z-index:5;font-size:var(--ls,16px);opacity:0;
  animation:thLeaf var(--lt2,9s) ease-in forwards;will-change:transform}
@keyframes thLeaf{0%{transform:translate(0,0) rotate(0);opacity:0}
  10%{opacity:.8}50%{transform:translate(var(--lx,4vw),55vh) rotate(200deg)}
  100%{transform:translate(calc(var(--lx,4vw)*-1),105vh) rotate(420deg);opacity:0}}
/* whisper apparition — faint phrase materializes and dissolves */
.th-whisper{z-index:6;font-family:'VT323',monospace;font-size:15px;
  letter-spacing:3px;color:rgba(191,95,255,.0);text-transform:lowercase;
  animation:thWhisper 6s ease-in-out forwards}
@keyframes thWhisper{0%{opacity:0;color:rgba(191,95,255,0)}
  35%{opacity:.5;color:rgba(191,95,255,.55)}
  70%{opacity:.4;color:rgba(255,117,24,.4)}100%{opacity:0}}
/* grave eyes — twin dots that blink from a dark corner */
.th-eyes{bottom:4vh;right:6vw;z-index:4;width:26px;height:9px;
  background:radial-gradient(circle 3px at 6px 4px,#ffdd55 90%,transparent),
             radial-gradient(circle 3px at 20px 4px,#ffdd55 90%,transparent);
  filter:drop-shadow(0 0 5px rgba(255,221,85,.8));
  animation:thBlink 5.2s ease-in-out infinite}
@keyframes thBlink{0%,90%,100%{transform:scaleY(1)}94%{transform:scaleY(.05)}}
/* cauldron-bubble embers — green witch-fire wisps */
.th-wisp{bottom:-10px;z-index:4;width:5px;height:5px;border-radius:50%;
  background:#39ff14;box-shadow:0 0 8px 2px rgba(57,255,20,.7);
  animation:thWisp var(--wt,6s) ease-out forwards;will-change:transform,opacity}
@keyframes thWisp{0%{transform:translate(0,0);opacity:0}
  12%{opacity:.85}100%{transform:translate(var(--wx,3vw),-70vh) scale(.3);opacity:0}}

/* bat swarm burst — flock erupts from a point */
.th-swarm{z-index:6;font-size:var(--ss,15px);opacity:0;
  animation:thSwarm var(--st2,3s) ease-out forwards;will-change:transform}
@keyframes thSwarm{0%{transform:translate(0,0) scale(.6);opacity:0}
  15%{opacity:.9}100%{transform:translate(var(--dx,30vw),var(--dy,-30vh)) scale(1.1);opacity:0}}
/* owl glide — silent hunter crossing mid-sky */
.th-owl{top:var(--oy,30vh);left:-60px;z-index:5;font-size:26px;opacity:0;
  animation:thOwl var(--ot,13s) linear forwards;will-change:transform}
@keyframes thOwl{0%{transform:translate(0,0);opacity:0}
  8%{opacity:.75}92%{opacity:.7}
  100%{transform:translate(115vw,var(--oy2,8vh));opacity:0}}
/* zombie hand — rises from bottom edge, grabs, sinks */
.th-hand{bottom:-70px;z-index:5;font-size:34px;opacity:0;
  animation:thHand 5s ease-in-out forwards}
@keyframes thHand{0%{transform:translateY(0) rotate(-14deg);opacity:0}
  20%{opacity:.85}45%{transform:translateY(-64px) rotate(6deg)}
  60%{transform:translateY(-58px) rotate(-8deg)}
  100%{transform:translateY(20px);opacity:0}}
/* rolling pumpkin — bounces across the bottom */
.th-roll{bottom:2vh;left:-50px;z-index:5;font-size:24px;
  animation:thRoll var(--rt,7s) linear forwards;will-change:transform}
@keyframes thRoll{0%{transform:translate(0,0) rotate(0)}
  25%{transform:translate(25vw,-3vh) rotate(300deg)}
  50%{transform:translate(50vw,0) rotate(600deg)}
  75%{transform:translate(75vw,-4vh) rotate(900deg)}
  100%{transform:translate(110vw,0) rotate(1200deg);opacity:0}}
/* haunt toast — console-style apparition, bottom-right */
.th-toast{bottom:8vh;right:2vw;z-index:7;max-width:280px;padding:8px 12px;
  font-family:'VT323',monospace;font-size:14px;letter-spacing:1px;
  color:rgba(255,150,60,.9);background:rgba(5,2,8,.85);
  border:1px solid rgba(255,117,24,.4);opacity:0;
  animation:thToast 5.5s ease-in-out forwards}
@keyframes thToast{0%{opacity:0;transform:translateX(20px)}
  12%{opacity:.95;transform:none}82%{opacity:.9}100%{opacity:0}}
/* boot sequence — one-shot startup load screen on every page */
.th-boot{inset:0;z-index:2147482950;background:#050208;
  display:flex;align-items:center;justify-content:center;
  animation:thBootOut 2.4s ease-in forwards}
@keyframes thBootOut{0%,72%{opacity:1}100%{opacity:0;visibility:hidden}}
.th-boot b{font-family:'VT323',monospace;font-size:clamp(26px,5vw,54px);
  letter-spacing:14px;color:#ff7518;text-shadow:0 0 24px rgba(255,117,24,.8);
  animation:thBootText 2.2s ease-out forwards}
@keyframes thBootText{0%{opacity:0;letter-spacing:30px;filter:blur(8px)}
  45%{opacity:1}80%{letter-spacing:14px;filter:blur(0)}
  100%{opacity:.95}}

/* ============ YULE pack (body.th-yule) — future-swappable ============ */
.th-snow{top:-16px;z-index:5;color:#eaf4ff;text-shadow:0 0 6px rgba(234,244,255,.7);
  animation:thSnow var(--st,9s) linear forwards;will-change:transform}
@keyframes thSnow{0%{transform:translate(0,0) rotate(0);opacity:0}
  8%{opacity:.9}100%{transform:translate(var(--sx,4vw),105vh) rotate(360deg);opacity:.2}}
.th-light{position:fixed;top:0;z-index:4;width:6px;height:6px;border-radius:50%;
  animation:thLight 2.4s ease-in-out infinite alternate}
@keyframes thLight{to{filter:brightness(1.6) saturate(1.4)}}

/* ============ NEWYEAR pack (body.th-newyear) ============ */
.th-confetti{top:-14px;z-index:5;width:8px;height:4px;
  animation:thConf var(--ct3,5s) ease-in forwards;will-change:transform}
@keyframes thConf{0%{transform:translate(0,0) rotate(0);opacity:1}
  100%{transform:translate(var(--cx2,6vw),105vh) rotate(720deg);opacity:0}}

@media (prefers-reduced-motion:reduce){
  /* calm: set dressing stays visible but frozen; ?theme=<x> (th-live) opts
     into full motion even under reduced-motion */
  body:not(.th-live) .th-species{animation:none!important}
  body:not(.th-live) #th-toggle{display:none!important}}
