/**
 * Grimages seasonal – Halloween.
 * The tile starts as a normal tile (.is-dormant), trembles, flickers like a dying
 * bulb, then turns into its haunted version piece by piece (.is-awakening).
 * Without JS state classes (or with reduced motion) the haunted end state shows directly.
 *
 * Intro timeline (s):  0 ─ shake ─ 1.4 │ 1.2 ─ flicker/takeover ─ 2.2 │ 1.9 pumpkin │ 2.0 moon
 *                      │ 2.2 spider drops │ 2.5+ bats │ 3.2 end
 */

/* The template forces link colours with !important, which animations cannot override:
   the colour goes through an animatable custom property instead. */
@property --gri-hw-text {
  syntax: "<color>";
  inherits: true;
  initial-value: #ff8a1f;
}

/* Haunted background lives on ::before so the original tile stays underneath. */
.gri-season--halloween::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  background:
    radial-gradient(120% 140% at 50% 120%, rgba(255, 122, 26, .55) 0%, rgba(255, 122, 26, 0) 55%),
    linear-gradient(160deg, #2a0d45 0%, #160624 60%, #0b0313 100%);
}

.gri-season--halloween:not(#gri-season-none) {
  box-shadow: inset 0 0 0 1px rgba(255, 138, 31, .45), 0 0 18px rgba(255, 122, 26, .25);
}

.gri-season--halloween:not(#gri-season-none):hover,
.gri-season--halloween:not(#gri-season-none):focus-within {
  box-shadow: inset 0 0 0 1px rgba(255, 138, 31, .9), 0 0 28px rgba(255, 122, 26, .55);
  animation: gri-hw-shiver .35s linear;
}

.gri-season--halloween:not(#gri-season-none) a {
  --gri-hw-text: #ff8a1f;
  color: var(--gri-hw-text) !important;
  text-shadow: 0 0 6px rgba(255, 138, 31, .8), 0 0 14px rgba(255, 90, 0, .5);
  animation: gri-hw-flicker 4s infinite;
}

.gri-season--halloween .gri-season-icon {
  transform-origin: 50% 90%;
  animation: gri-hw-wobble 2.8s ease-in-out infinite;
  filter: drop-shadow(0 0 4px rgba(255, 138, 31, .7));
}

.gri-season--halloween .gri-season-flame {
  animation: gri-hw-candle 1.6s steps(1) infinite;
}

.gri-season--halloween .gri-season-moon {
  /* Above the bats: they come out from behind the moon and its clouds */
  z-index: 1;
  top: 8%;
  right: 7%;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  /* Full moon with a few maria/craters */
  background:
    radial-gradient(circle at 34% 38%, rgba(196, 180, 128, .55) 0 13%, transparent 14%),
    radial-gradient(circle at 63% 60%, rgba(196, 180, 128, .45) 0 10%, transparent 11%),
    radial-gradient(circle at 62% 28%, rgba(196, 180, 128, .35) 0 6%, transparent 7%),
    radial-gradient(circle at 30% 70%, rgba(196, 180, 128, .3) 0 7%, transparent 8%),
    radial-gradient(circle at 40% 35%, #fffbea 0%, #f3e6b0 65%, #dccb86 100%);
  box-shadow: 0 0 14px 4px rgba(255, 240, 180, .55), 0 0 40px 10px rgba(255, 240, 180, .18);
  /* The halo dims while cloud 1 covers the moon (same 14s cycle) */
  animation: gri-hw-moonglow 14s linear infinite;
}

/* Two drifting clouds, dark and moon-lit on top, passing in front of the moon */
.gri-season--halloween .gri-season-moon::before,
.gri-season--halloween .gri-season-moon::after {
  content: "";
  position: absolute;
  left: 50%;
  border-radius: 50%;
  background:
    radial-gradient(60% 40% at 50% 15%, rgba(255, 240, 190, .35), transparent 70%),
    radial-gradient(35% 60% at 28% 60%, rgba(52, 32, 74, .96) 0 55%, transparent 100%),
    radial-gradient(35% 70% at 55% 45%, rgba(62, 40, 88, .96) 0 55%, transparent 100%),
    radial-gradient(30% 55% at 78% 62%, rgba(48, 30, 70, .95) 0 55%, transparent 100%);
  filter: blur(.6px);
}

.gri-season--halloween .gri-season-moon::before {
  top: 9px;
  width: 52px;
  height: 16px;
  animation: gri-hw-cloud 14s linear infinite;
}

.gri-season--halloween .gri-season-moon::after {
  top: 1px;
  width: 36px;
  height: 11px;
  opacity: .85;
  animation: gri-hw-cloud 21s linear -12s infinite;
}

/*
 * Bats leave the moon one after another, grow as they come towards the viewer
 * (depth), swoop and roll, and exit left; then a pause before the next sortie.
 * Layers: span = travel + depth, svg = swoop + roll, g = body bob, paths = wings.
 */
.gri-season--halloween .gri-season-bat {
  top: calc(10% + 4px);
  right: calc(7% + 2px);
  width: 30px;
  color: #1a0a26;
  opacity: 0;
  transform-origin: 50% 50%;
  animation: gri-hw-sortie var(--dur, 7.5s) cubic-bezier(.55, 0, .85, .6) calc(2.5s + var(--delay, 0s)) infinite;
}

.gri-season--halloween .gri-season-bat svg {
  display: block;
  width: 100%;
  overflow: visible;
  fill: currentColor;
  /* Silhouettes rim-lit in orange so they read on the night sky */
  filter: drop-shadow(0 0 1px #ffa94d) drop-shadow(0 0 4px rgba(255, 122, 26, .75));
  animation: gri-hw-swoop var(--swoop, 1.7s) ease-in-out infinite alternate;
}

.gri-season--halloween .gri-season-bat-body {
  animation: gri-hw-bob var(--flap, .3s) ease-in-out infinite;
}

.gri-season--halloween .gri-season-wing {
  transform-box: view-box;
  animation: var(--flap, .3s) ease-in-out infinite;
}

.gri-season--halloween .gri-season-wing--l {
  transform-origin: 30px 13px;
  animation-name: gri-hw-wing-l;
}

.gri-season--halloween .gri-season-wing--r {
  transform-origin: 34px 13px;
  animation-name: gri-hw-wing-r;
}

.gri-season--halloween .gri-season-eye {
  fill: #ffd43b;
}

.gri-season--halloween .gri-season-bat--1 { --delay: 0s; --dy: 22px; --s: 1.3; --swoop: 1.7s; }
.gri-season--halloween .gri-season-bat--2 { --delay: .9s; --dy: -8px; --s: 1; --swoop: 1.3s; --flap: .26s; }
.gri-season--halloween .gri-season-bat--3 { --delay: 3.2s; --dy: 12px; --s: .85; --swoop: 2.1s; --flap: .34s; }

.gri-season--halloween.is-dormant .gri-season-bat {
  animation: none;
}

.gri-season--halloween .gri-season-spider {
  top: 0;
  left: 9%;
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #1a0a26;
  transform: translateY(-14px);
  animation: gri-hw-dangle 5s ease-in-out infinite;
  transition: transform .5s cubic-bezier(.34, 1.56, .64, 1);
}

.gri-season--halloween .gri-season-thread {
  width: 1px;
  height: 22px;
  background: linear-gradient(rgba(255, 255, 255, .3), rgba(255, 255, 255, .85));
  box-shadow: 0 0 2px rgba(255, 255, 255, .6);
}

.gri-season--halloween .gri-season-spider svg {
  width: 18px;
  margin-top: -2px;
  filter: drop-shadow(0 0 1px #ffa94d) drop-shadow(0 0 4px rgba(255, 122, 26, .8));
}

.gri-season--halloween:hover .gri-season-spider {
  animation-play-state: paused;
  transform: translateY(6px);
}

.gri-season--halloween .gri-season-fog {
  left: -50%;
  right: -50%;
  bottom: -10px;
  height: 26px;
  background:
    radial-gradient(50% 100% at 25% 100%, rgba(220, 200, 255, .22), transparent 70%),
    radial-gradient(50% 100% at 75% 100%, rgba(220, 200, 255, .18), transparent 70%);
  animation: gri-hw-fog 12s ease-in-out infinite alternate;
}

/* ---------- Dormant: looks exactly like the other tiles ---------- */
.gri-season--halloween.is-dormant::before,
.gri-season--halloween.is-dormant .gri-season-decor {
  opacity: 0;
}

.gri-season--halloween.is-dormant:not(#gri-season-none) {
  box-shadow: none;
}

.gri-season--halloween.is-dormant:not(#gri-season-none) a {
  --gri-hw-text: #fff;
  text-shadow: none;
  animation: none;
}

.gri-season--halloween.is-dormant .gri-season-icon {
  width: 0;
  margin-right: -.45em;
  opacity: 0;
  animation: none;
}

/* ---------- Awakening: the transformation sequence ---------- */
.gri-season--halloween.is-awakening:not(#gri-season-none) {
  animation:
    gri-hw-shake 1.4s ease-in,
    gri-hw-glow .8s 2s both,
    gri-hw-intro-end 3.2s;
}

.gri-season--halloween.is-awakening::before {
  animation: gri-hw-takeover 1s 1.2s both;
}

.gri-season--halloween.is-awakening:not(#gri-season-none) a {
  animation: gri-hw-turn .8s 1.4s both;
}

.gri-season--halloween.is-awakening .gri-season-icon {
  animation: gri-hw-pop .6s 1.9s cubic-bezier(.34, 1.56, .64, 1) both;
}

.gri-season--halloween.is-awakening .gri-season-fog { animation: gri-hw-appear .8s 1.6s both; }
.gri-season--halloween.is-awakening .gri-season-moon { animation: gri-hw-moonrise .8s 2s ease-out both; }
.gri-season--halloween.is-awakening .gri-season-spider { animation: gri-hw-drop .9s 2.2s cubic-bezier(.34, 1.56, .64, 1) both; }

/* ---------- Keyframes ---------- */
@keyframes gri-hw-shake {
  0% { transform: none; }
  10% { transform: translate(-1px, 0) rotate(-.3deg); }
  20% { transform: translate(1px, 0) rotate(.3deg); }
  30% { transform: translate(-1px, 1px) rotate(-.5deg); }
  40% { transform: translate(2px, -1px) rotate(.6deg); }
  50% { transform: translate(-2px, 1px) rotate(-.8deg); }
  60% { transform: translate(3px, 0) rotate(1deg); }
  70% { transform: translate(-3px, -1px) rotate(-1.2deg); }
  80% { transform: translate(4px, 1px) rotate(1.4deg); }
  90% { transform: translate(-4px, 0) rotate(-1.6deg) scale(1.02); }
  100% { transform: none; }
}

@keyframes gri-hw-shiver {
  0%, 100% { transform: translateY(-2px); }
  25% { transform: translate(-2px, -2px) rotate(-.6deg); }
  75% { transform: translate(2px, -2px) rotate(.6deg); }
}

@keyframes gri-hw-takeover {
  0% { opacity: 0; }
  10% { opacity: .9; }
  18% { opacity: 0; }
  30% { opacity: 1; }
  38% { opacity: .15; }
  46% { opacity: .8; }
  52% { opacity: .3; }
  100% { opacity: 1; }
}

@keyframes gri-hw-turn {
  0% { --gri-hw-text: #fff; text-shadow: none; }
  30% { --gri-hw-text: #ff8a1f; text-shadow: 0 0 10px rgba(255, 90, 0, .9); }
  45% { --gri-hw-text: #fff; text-shadow: none; }
  100% { --gri-hw-text: #ff8a1f; text-shadow: 0 0 6px rgba(255, 138, 31, .8), 0 0 14px rgba(255, 90, 0, .5); }
}

@keyframes gri-hw-pop {
  from { width: 0; margin-right: -.45em; opacity: 0; transform: scale(0) rotate(-90deg); }
  to { width: 1.5em; margin-right: 0; opacity: 1; transform: none; }
}

@keyframes gri-hw-glow {
  from { box-shadow: none; }
}

@keyframes gri-hw-appear {
  from { opacity: 0; transform: translateY(10px); }
}

@keyframes gri-hw-cloud {
  from { transform: translateX(40px); }
  to { transform: translateX(-110px); }
}

/* Cloud 1 covers the moon around 38% of its cycle */
@keyframes gri-hw-moonglow {
  0%, 25%, 52%, 100% { box-shadow: 0 0 14px 4px rgba(255, 240, 180, .55), 0 0 40px 10px rgba(255, 240, 180, .18); }
  38% { box-shadow: 0 0 6px 1px rgba(255, 240, 180, .25), 0 0 20px 4px rgba(255, 240, 180, .06); }
}

@keyframes gri-hw-moonrise {
  from { opacity: 0; transform: translateY(18px) scale(.6); }
}

@keyframes gri-hw-drop {
  from { transform: translateY(-50px); }
  to { transform: translateY(-14px); }
}

@keyframes gri-hw-intro-end {
  from { opacity: 1; }
  to { opacity: 1; }
}

@keyframes gri-hw-sortie {
  0% { translate: 0 0; scale: .12; opacity: 0; }
  5% { opacity: 1; }
  55% { translate: calc(-100cqw + 20px) var(--dy, 10px); scale: var(--s, 1); opacity: 1; }
  56%, 100% { translate: calc(-100cqw + 20px) var(--dy, 10px); scale: var(--s, 1); opacity: 0; }
}

@keyframes gri-hw-swoop {
  from { transform: translateY(-7px) rotate(-12deg); }
  to { transform: translateY(8px) rotate(9deg); }
}

/* Fast downstroke, slower recovery */
@keyframes gri-hw-wing-l {
  0%, 100% { transform: rotate(32deg) scaleY(.85); }
  40% { transform: rotate(-24deg) scaleY(1); }
}

@keyframes gri-hw-wing-r {
  0%, 100% { transform: rotate(-32deg) scaleY(.85); }
  40% { transform: rotate(24deg) scaleY(1); }
}

@keyframes gri-hw-bob {
  0%, 100% { transform: translateY(1.5px); }
  40% { transform: translateY(-1.5px); }
}

@keyframes gri-hw-wobble {
  0%, 100% { transform: rotate(-6deg); }
  50% { transform: rotate(6deg) translateY(-1px); }
}

@keyframes gri-hw-candle {
  0%, 100% { opacity: 1; }
  20% { opacity: .75; }
  40% { opacity: .95; }
  70% { opacity: .65; }
}

@keyframes gri-hw-flicker {
  0%, 18%, 22%, 62%, 64%, 100% { opacity: 1; }
  20%, 63% { opacity: .55; }
}

@keyframes gri-hw-dangle {
  0%, 100% { transform: translateY(-14px); }
  50% { transform: translateY(-4px); }
}

@keyframes gri-hw-fog {
  from { transform: translateX(-8%); }
  to { transform: translateX(8%); }
}

@media (prefers-reduced-motion: reduce) {
  .gri-season--halloween .gri-season-bat { opacity: 1; }
  .gri-season--halloween .gri-season-bat--1 { translate: -60cqw 10px; }
  .gri-season--halloween .gri-season-bat--2 { translate: -25cqw 4px; scale: .7; }
  .gri-season--halloween .gri-season-bat--3 { display: none; }
}
