/* ==========================================================================
   assets/css/halloween.css — Halloween effects (public site + admin panel).

   Only loaded while Halloween is switched on (Admin → Settings → Holiday
   effects). Same rules as festive.css: animations change only transform and
   opacity, nothing takes a click, no blur over anything that moves.

   Layering, back to front (public site):
     z -1     .hw-moon, .hw-fog       behind the content, over the background
     z 1040   .hw-bats                in front of the content, under the navbar
     z 1045   .hw-greeting            bottom-right card
     z 1050   .hw-web                 cobweb in the top-right corner
     z 1060   .hw-ghost, .hw-spider   pass across under the navbar
     z 1090   .hw-lights              hang from the bottom edge of the navbar

   In the admin panel (.hw-in-admin) the bats, ghost, moon sit behind the
   cards; only the cobweb and the spider are in front, and only at the edges.
   ========================================================================== */

:root {
  --hw-orange: #F28C28;
  --hw-purple: #9A6AD6;
  --hw-green:  #7CD94A;
  --hw-candle: #FFD54A;
}

.hw-layer {
  position: fixed;
  pointer-events: none;
}

/* ---------------------------------------------------------------------------
   0. SEASONAL TINT — the site's own rising embers turn pumpkin and purple
   ------------------------------------------------------------------------ */
.hw-on .bg-embers i:nth-child(2n)  { background: var(--hw-orange) !important; }
.hw-on .bg-embers i:nth-child(3n)  { background: var(--hw-purple) !important; }
.hw-on .bg-embers i:nth-child(7n)  { background: var(--hw-green)  !important; }

/* The Halloween logo carries a hat, bats and pumpkins around the badge, so it
   is given a little more height than the plain logo to keep the name readable. */
[data-navbar] img[src*="logo-halloween"] { height: 64px !important; margin: -4px 0; }
footer img[src*="logo-halloween"]        { height: 6rem !important; }
@media (max-width: 480px) {
  [data-navbar] img[src*="logo-halloween"] { height: 56px !important; }
}

/* ---------------------------------------------------------------------------
   1. HARVEST MOON
   ------------------------------------------------------------------------ */
.hw-moon {
  top: calc(var(--nav-h, 76px) + 28px);
  right: 6vw;
  width: clamp(110px, 16vw, 210px);
  aspect-ratio: 1;
  z-index: -1;
  overflow: visible;
}
.hw-in-admin .hw-moon { top: 28px; right: 4vw; opacity: .55; }

.hw-moon-disc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle at 35% 32%, #FFF6D8 0%, #FFE2A0 38%, #F6B656 72%, #D9862C 100%);
  box-shadow:
    0 0 40px 10px rgba(246, 182, 86, .35),
    0 0 120px 40px rgba(242, 140, 40, .16);
  opacity: .9;
  animation: hw-moon-glow 7s ease-in-out infinite;
}
.hw-moon-disc i {
  position: absolute;
  border-radius: 50%;
  background: rgba(196, 118, 40, .28);
}
.hw-moon-disc i:nth-child(1) { width: 22%; height: 22%; left: 52%; top: 22%; }
.hw-moon-disc i:nth-child(2) { width: 14%; height: 14%; left: 28%; top: 58%; }
.hw-moon-disc i:nth-child(3) { width: 10%; height: 10%; left: 62%; top: 64%; }

@keyframes hw-moon-glow { 0%, 100% { opacity: .82; } 50% { opacity: .98; } }

.hw-cloud {
  position: absolute;
  height: 26%;
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(40, 26, 58, .0), rgba(40, 26, 58, .85) 40%, rgba(24, 14, 36, .9));
  will-change: transform;
}
.hw-cloud::before,
.hw-cloud::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  background: inherit;
}
.hw-cloud::before { width: 45%; height: 120%; left: 18%; top: -55%; }
.hw-cloud::after  { width: 35%; height: 100%; left: 52%; top: -40%; }

.hw-cloud.c1 { width: 120%; top: 58%; left: -10%; animation: hw-cloud 38s linear infinite; }
.hw-cloud.c2 { width: 90%;  top: 22%; left: 0;    animation: hw-cloud 52s linear -20s infinite; opacity: .7; }

@keyframes hw-cloud {
  0%   { transform: translateX(-160%); opacity: 0; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { transform: translateX(160%); opacity: 0; }
}

/* ---------------------------------------------------------------------------
   2. FOG — two wide mist bands sliding in opposite directions
   ------------------------------------------------------------------------ */
.hw-fog {
  left: 0;
  right: 0;
  bottom: 0;
  height: 32vh;
  z-index: -1;
  overflow: hidden;
  contain: strict;
  -webkit-mask-image: linear-gradient(to top, #000 35%, transparent);
          mask-image: linear-gradient(to top, #000 35%, transparent);
}
.hw-fog > div {
  position: absolute;
  bottom: -10%;
  left: 0;
  width: 200%;
  height: 120%;
  will-change: transform;
}
.hw-fog-a {
  background:
    radial-gradient(30% 50% at 10% 70%, rgba(170, 150, 210, .20), transparent 70%),
    radial-gradient(25% 45% at 35% 80%, rgba(200, 190, 230, .16), transparent 70%),
    radial-gradient(30% 50% at 60% 75%, rgba(170, 150, 210, .20), transparent 70%),
    radial-gradient(25% 45% at 85% 80%, rgba(200, 190, 230, .16), transparent 70%);
  animation: hw-fog-left 46s linear infinite;
}
.hw-fog-b {
  background:
    radial-gradient(28% 55% at 20% 85%, rgba(242, 140, 40, .08), transparent 70%),
    radial-gradient(30% 50% at 45% 75%, rgba(190, 175, 225, .14), transparent 70%),
    radial-gradient(28% 55% at 70% 85%, rgba(242, 140, 40, .08), transparent 70%),
    radial-gradient(30% 50% at 95% 75%, rgba(190, 175, 225, .14), transparent 70%);
  animation: hw-fog-right 64s linear infinite;
}
@keyframes hw-fog-left  { from { transform: translate3d(0, 0, 0); }    to { transform: translate3d(-50%, 0, 0); } }
@keyframes hw-fog-right { from { transform: translate3d(-50%, 0, 0); } to { transform: translate3d(0, 0, 0); } }

/* ---------------------------------------------------------------------------
   3. COBWEB
   ------------------------------------------------------------------------ */
.hw-web {
  right: 0;
  width: clamp(90px, 11vw, 150px);
  aspect-ratio: 1;
  z-index: 1050;
  opacity: .45;
}
.hw-web svg { width: 100%; height: 100%; display: block; }
.hw-in-admin .hw-web { opacity: .3; width: 120px; }

/* ---------------------------------------------------------------------------
   4. JACK-O'-LANTERN LIGHTS
   ------------------------------------------------------------------------ */
.hw-lights {
  left: 0;
  right: 0;
  height: 48px;
  z-index: 1090;
  overflow: hidden;
  contain: strict;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='76' height='48' viewBox='0 0 76 48'%3E%3Cpath d='M0 2 Q38 24 76 2' fill='none' stroke='%231b1424' stroke-width='2.4'/%3E%3Cpath d='M0 2 Q38 24 76 2' fill='none' stroke='%23F28C28' stroke-opacity='.3' stroke-width='.8'/%3E%3C/svg%3E");
  background-repeat: repeat-x;
  background-size: 76px 48px;
}

.hw-lantern {
  position: absolute;
  top: 10px;
  width: 26px;
  height: 25px;
  margin-left: -13px;
  transform-origin: 50% -6px;
  animation: hw-sway var(--sw, 3s) ease-in-out var(--d, 0s) infinite alternate;
}
.hw-lantern svg { width: 100%; height: 100%; display: block; position: relative; }
/* The glow is painted once; flickering fades it with opacity (GPU only). */
.hw-lantern::before {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 196, 60, .55), rgba(242, 140, 40, .18) 50%, transparent 70%);
  will-change: opacity;
  animation: hw-flicker var(--t, 1.3s) steps(1, end) var(--d, 0s) infinite;
}
.hw-lantern.is-still,
.hw-lantern.is-still::before { animation: none; }

@keyframes hw-sway { from { transform: rotate(-6deg); } to { transform: rotate(6deg); } }
@keyframes hw-flicker {
  0%   { opacity: .95; }
  18%  { opacity: .6; }
  27%  { opacity: 1; }
  52%  { opacity: .75; }
  61%  { opacity: .98; }
  80%  { opacity: .55; }
  90%  { opacity: .9; }
}

.hw-bulb {
  position: absolute;
  top: 16px;
  width: 8px;
  height: 13px;
  margin-left: -4px;
  border-radius: 50% 50% 46% 46% / 40% 40% 60% 60%;
  background: var(--c);
  box-shadow: 0 0 6px 1px var(--c), 0 0 14px 3px color-mix(in srgb, var(--c) 40%, transparent);
  will-change: opacity;
  animation: hw-twinkle var(--t, 2.4s) ease-in-out var(--d, 0s) infinite;
}
.hw-bulb::before {
  content: "";
  position: absolute;
  top: -4px;
  left: 1px;
  width: 6px;
  height: 5px;
  border-radius: 1.5px;
  background: #241c2c;
}
.hw-bulb.is-still { animation: none; will-change: auto; }
@keyframes hw-twinkle { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

/* ---------------------------------------------------------------------------
   5. BATS CANVAS (size + top set by halloween.js)
   ------------------------------------------------------------------------ */
.hw-bats {
  left: 0;
  top: 0;
  z-index: 1040;
  transform: translateZ(0);
  contain: strict;
}
.hw-in-admin .hw-bats { z-index: -1; opacity: .8; }

/* ---------------------------------------------------------------------------
   6. DANGLING SPIDER
   ------------------------------------------------------------------------ */
.hw-spider {
  width: 44px;
  height: 0;
  margin-left: -22px;
  z-index: 1060;
  visibility: hidden;
  contain: layout;
}
.hw-thread {
  position: absolute;
  left: 21.5px;
  top: 0;
  width: 1px;
  height: var(--drop, 200px);
  background: linear-gradient(to bottom, rgba(237, 230, 250, .25), rgba(237, 230, 250, .75));
  transform-origin: top center;
  transform: scaleY(0);
}
.hw-spider-body {
  position: absolute;
  left: 0;
  top: -14px;
  width: 44px;
  height: 40px;
  transform: translateY(-50px);
}
.hw-spider-body svg { width: 100%; height: 100%; display: block; overflow: visible; }

.hw-spider.is-dropping { visibility: visible; animation: hw-show 10s linear forwards; }
.hw-spider.is-dropping .hw-thread      { will-change: transform; animation: hw-thread 10s cubic-bezier(.45, 0, .35, 1) forwards; }
.hw-spider.is-dropping .hw-spider-body { will-change: transform; animation: hw-drop 10s cubic-bezier(.45, 0, .35, 1) forwards; }
.hw-spider.is-dropping .legs-l,
.hw-spider.is-dropping .legs-r { transform-box: fill-box; animation: hw-legs .35s ease-in-out infinite alternate; }
.hw-spider.is-dropping .legs-l { transform-origin: right center; }
.hw-spider.is-dropping .legs-r { transform-origin: left center; animation-delay: -.17s; }

@keyframes hw-show { 0%, 100% { opacity: 1; } }
@keyframes hw-thread {
  0%   { transform: scaleY(0); }
  30%  { transform: scaleY(1); }
  34%  { transform: scaleY(.96); }
  38%  { transform: scaleY(1); }
  70%  { transform: scaleY(1); }
  100% { transform: scaleY(0); }
}
@keyframes hw-drop {
  0%   { transform: translateY(-50px) rotate(0); }
  30%  { transform: translateY(var(--drop, 200px)) rotate(0); }
  34%  { transform: translateY(calc(var(--drop, 200px) - 10px)) rotate(-6deg); }
  38%  { transform: translateY(var(--drop, 200px)) rotate(4deg); }
  46%  { transform: translateY(var(--drop, 200px)) rotate(-8deg); }
  54%  { transform: translateY(var(--drop, 200px)) rotate(8deg); }
  62%  { transform: translateY(var(--drop, 200px)) rotate(-3deg); }
  70%  { transform: translateY(var(--drop, 200px)) rotate(0); }
  100% { transform: translateY(-50px) rotate(0); }
}
@keyframes hw-legs { from { transform: rotate(-10deg); } to { transform: rotate(10deg); } }

/* ---------------------------------------------------------------------------
   7. GHOST
   ------------------------------------------------------------------------ */
.hw-ghost {
  left: 0;
  width: 78px;
  height: 94px;
  z-index: 1060;
  opacity: 0;
  visibility: hidden;
  contain: layout;
}
.hw-in-admin .hw-ghost { z-index: -1; }
.hw-ghost-inner { width: 100%; height: 100%; position: relative; }
.hw-ghost svg { width: 100%; height: 100%; display: block; overflow: visible; filter: drop-shadow(0 0 14px rgba(205, 188, 235, .45)); }

.hw-ghost.is-floating {
  visibility: visible;
  will-change: transform, opacity;
  animation: hw-float var(--fly, 16s) linear forwards;
}
.hw-ghost.is-floating .hw-ghost-inner { animation: hw-hover 2.2s ease-in-out infinite alternate; }
.hw-ghost.is-floating .hw-ghost-mouth { transform-box: fill-box; transform-origin: center; animation: hw-mouth 1.6s ease-in-out infinite alternate; }

@keyframes hw-float {
  0%   { opacity: 0;   transform: translate3d(-110px, 20px, 0); }
  8%   { opacity: .85; }
  30%  { transform: translate3d(28vw, -10px, 0); }
  55%  { transform: translate3d(55vw, 30px, 0); }
  80%  { transform: translate3d(82vw, 0, 0); }
  92%  { opacity: .85; }
  100% { opacity: 0;   transform: translate3d(calc(100vw + 40px), 18px, 0); }
}
@keyframes hw-hover { from { transform: translateY(-8px) rotate(-4deg); } to { transform: translateY(8px) rotate(4deg); } }
@keyframes hw-mouth { from { transform: scale(.7, .6); } to { transform: scale(1, 1.1); } }

/* The greeting card's "boo": the ghost swoops in close and shouts. */
.hw-boo {
  position: absolute;
  left: 70%;
  top: -10px;
  font: 800 1.15rem/1 Poppins, system-ui, sans-serif;
  letter-spacing: .04em;
  color: var(--hw-orange);
  text-shadow: 0 0 10px rgba(242, 140, 40, .6);
  opacity: 0;
  transform: scale(.4) rotate(-10deg);
}
.hw-ghost.is-booing { animation-name: hw-swoop; }
.hw-ghost.is-booing .hw-boo { animation: hw-boo 7s ease-out forwards; }
@keyframes hw-swoop {
  0%   { opacity: 0;  transform: translate3d(calc(100vw + 40px), 40vh, 0) scale(.8); }
  18%  { opacity: 1;  transform: translate3d(60vw, 18vh, 0) scale(1.35); }
  30%  { transform: translate3d(48vw, 14vh, 0) scale(1.45); }
  60%  { opacity: .9; transform: translate3d(25vw, 6vh, 0) scale(1.1); }
  100% { opacity: 0;  transform: translate3d(-120px, -4vh, 0) scale(.8); }
}
@keyframes hw-boo {
  0%, 14% { opacity: 0; transform: scale(.4) rotate(-10deg); }
  20%     { opacity: 1; transform: scale(1.3) rotate(6deg); }
  26%     { transform: scale(1) rotate(-4deg); }
  50%     { opacity: 1; }
  60%, 100% { opacity: 0; transform: scale(1) rotate(-4deg); }
}

/* ---------------------------------------------------------------------------
   8. GREETING CARD
   ------------------------------------------------------------------------ */
.hw-greeting {
  position: fixed;
  right: 18px;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 1045;
  width: min(300px, calc(100vw - 110px));
  padding: 14px 40px 14px 16px;
  border-radius: 18px;
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(242, 140, 40, .26), transparent 55%),
    radial-gradient(120% 140% at 100% 100%, rgba(122, 68, 184, .26), transparent 55%),
    rgba(14, 10, 18, .96);
  border: 1px solid rgba(242, 140, 40, .5);
  box-shadow: 0 18px 40px rgba(0, 0, 0, .5), 0 0 24px rgba(242, 140, 40, .12), inset 0 1px 0 rgba(255, 255, 255, .06);
  color: #F3EEDF;
  cursor: pointer;
  contain: layout paint;
  animation: hw-greet-in .9s cubic-bezier(.2, 1.3, .4, 1) .6s both;
}
.hw-greeting.is-leaving { animation: hw-greet-out .35s ease-in forwards; }
.hw-greeting.is-spooked { animation: hw-shake .55s ease-in-out; }
.hw-greeting:focus-visible { outline: 2px solid var(--hw-orange); outline-offset: 3px; }

@keyframes hw-greet-in  { from { opacity: 0; transform: translateY(24px) rotate(-3deg) scale(.94); } to { opacity: 1; transform: none; } }
@keyframes hw-greet-out { to   { opacity: 0; transform: translateY(18px) scale(.96); } }
@keyframes hw-shake {
  0%, 100% { transform: none; }
  20% { transform: translateX(-5px) rotate(-2deg); }
  40% { transform: translateX(5px) rotate(2deg); }
  60% { transform: translateX(-3px) rotate(-1deg); }
  80% { transform: translateX(3px) rotate(1deg); }
}

.hw-greet-line {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1.2;
}
.hw-greet-icon {
  flex: 0 0 auto;
  display: inline-block;
  font-size: 1.45rem;
  line-height: 1;
  animation: hw-wobble 2.4s ease-in-out infinite;
}
@keyframes hw-wobble { 0%, 100% { transform: translateY(0) rotate(-8deg); } 50% { transform: translateY(-3px) rotate(8deg); } }

/* Pumpkin-to-purple shine, three passes then still (it repaints text). */
.hw-greet-text {
  background: linear-gradient(90deg, #FFC27A, #F28C28 35%, #FFE7B8 50%, #B98AF0 65%, #FFC27A);
  background-size: 250% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: hw-shine 3s linear 1.2s 3;
}
@keyframes hw-shine { from { background-position: 100% 0; } to { background-position: -150% 0; } }

.hw-hint {
  display: block;
  margin-top: 8px;
  font-family: Poppins, system-ui, sans-serif;
  font-size: .68rem;
  color: #9A8FA8;
}

.hw-close {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 0;
  background: transparent;
  color: #9A8FA8;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  transition: color .2s, background .2s;
}
.hw-close:hover,
.hw-close:focus-visible { color: var(--hw-orange); background: rgba(255, 255, 255, .06); outline: none; }

/* ---------------------------------------------------------------------------
   9. ADMIN PANEL TOUCHES (body.hw-admin, only when "Decorate the admin" is on)
   ------------------------------------------------------------------------ */
.hw-admin .admin-sidebar {
  box-shadow: inset -1px 0 0 rgba(242, 140, 40, .25);
}
.hw-admin .admin-link.active {
  box-shadow: inset 3px 0 0 var(--hw-orange);
}
.hw-admin .admin-sidebar > div:first-child {
  background:
    radial-gradient(80% 120% at 50% 0%, rgba(242, 140, 40, .14), transparent 70%),
    radial-gradient(60% 100% at 100% 100%, rgba(122, 68, 184, .14), transparent 70%);
}
.hw-admin .admin-sidebar img[src*="logo-halloween"] { height: 4.25rem; }

/* ---------------------------------------------------------------------------
   10. SMALL SCREENS + DEVICE TIERS
   ------------------------------------------------------------------------ */
@media (max-width: 480px) {
  .hw-greeting {
    right: 12px;
    bottom: calc(78px + env(safe-area-inset-bottom, 0px));
    width: min(280px, calc(100vw - 24px));
  }
  .hw-greet-line { font-size: 1.08rem; }
  .hw-lights { height: 42px; }
  .hw-lantern { width: 22px; height: 21px; margin-left: -11px; }
  .hw-ghost { width: 58px; height: 70px; }
  .hw-moon { right: 4vw; width: 92px; }
}

/* Frosted-glass panels go solid on weaker devices, since bats moving behind
   a blur make the browser redo the blur every frame. */
.hw-low .glass,
.hw-mid .glass {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  background: rgba(20, 16, 24, .94);
}

.hw-low .bg-embers,
.hw-shed .bg-embers { display: none !important; }
.hw-low .hw-fog-b,
.hw-low .hw-cloud.c2 { display: none; }
.hw-low .hw-greet-text,
.hw-low .hw-greet-icon,
.hw-low .hw-moon-disc { animation: none; }
.hw-low .hw-bulb { box-shadow: 0 0 6px 1px var(--c); }
.hw-low .hw-ghost svg { filter: none; }

.hw-shed .hw-fog > div,
.hw-shed .hw-cloud,
.hw-shed .hw-lantern { animation: none !important; }

/* ---------------------------------------------------------------------------
   11. ACCESSIBILITY + PRINT
   ------------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .hw-lantern, .hw-lantern::before, .hw-bulb, .hw-greet-icon, .hw-greet-text,
  .hw-moon-disc, .hw-cloud, .hw-greeting { animation: none !important; will-change: auto; }
  .hw-cloud { display: none; }
}

@media print {
  .hw-layer, .hw-greeting { display: none !important; }
}
