/* Calendario de Halloween (/halloween): cementerio nocturno con lápidas como puertas. */
/* La niebla desborda a propósito: se recorta en el documento (el overflow del body no
   basta, scrollea el <html>). Con :has deja de aplicar al salir por soft-nav. */
html:has(body.hw-page) { overflow-x: clip; }
.hw-page { overflow-x: hidden; background: radial-gradient(ellipse at 50% -10%, #3b1d5e 0%, #12081f 55%, #05030a 100%); min-height: 100dvh; }
.hw-scene { position: relative; max-width: 720px; margin: 0 auto; padding: 16px 16px 120px; color: #f5e6d3; }
.hw-sky { position: absolute; inset: 0 0 auto 0; height: 260px; pointer-events: none; }
.hw-moon { position: absolute; top: 4px; right: 10px; width: 58px; height: 58px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #fff8d6, #f5d77a 60%, #d9a441); box-shadow: 0 0 46px 14px rgba(245, 215, 122, .3); }
.hw-fog { position: absolute; left: -20%; right: -20%; bottom: 10px; height: 120px;
  background: radial-gradient(ellipse at 50% 60%, rgba(190, 180, 220, .16), transparent 70%); filter: blur(10px);
  animation: hw-fog 18s ease-in-out infinite alternate; }
@keyframes hw-fog { from { transform: translateX(-4%); } to { transform: translateX(4%); } }
.hw-hero { position: relative; z-index: 1; text-align: center; padding: 60px 0 18px; }
.hw-title { font-size: clamp(1.7rem, 6vw, 2.4rem); margin: 0; color: #ffb347; text-shadow: 0 0 18px rgba(255, 140, 0, .55); }
.hw-sub { margin: 8px auto 0; max-width: 34ch; opacity: .85; }
.hw-stats { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 14px; }
.hw-pill { padding: 6px 12px; border-radius: 999px; background: rgba(255, 140, 0, .14); border: 1px solid rgba(255, 140, 0, .35); font-weight: 700; font-size: .85rem; }
/* ── Cementerio: lápidas de piedra con volumen (oct-2026) ──────────────────────
   Cada puerta es una lápida clavada en su montículo: piedra con grano y bisel, el
   número grabado, un poco torcida, y se inclina hacia el dedo. Al cargar brotan
   del suelo en cascada; al pinchar tiemblan y se arrancan hacia ti (halloween.js).
   La piedra vive dentro de .hw-door para que el enlace, las clases de estado y el
   texto sigan donde los esperan los tests. */
.hw-doors { position: relative; display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: 26px 16px;
  margin-top: 22px; perspective: 900px; perspective-origin: 50% 20%; }
.hw-door { --tilt: 0deg; --rx: 0deg; --ry: 0deg; --stone-a: #8d8a9e; --stone-b: #4a4759; --aura: transparent;
  position: relative; display: block; aspect-ratio: 3 / 4.2; text-decoration: none; color: #e9e3f5;
  transform-style: preserve-3d; -webkit-tap-highlight-color: transparent;
  /* Por debajo del suelo no se ve nada: así la lápida «sale» de la tierra. */
  clip-path: inset(-300% -60% 0 -60%); }
.hw-stone { position: absolute; inset: 0 7% 13%; z-index: 1; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 2px; padding-top: 10%;
  border-radius: 50% 50% 9px 9px / 36% 36% 9px 9px;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E"),
    radial-gradient(120% 70% at 30% 18%, rgba(255, 255, 255, .22), transparent 55%),
    linear-gradient(180deg, var(--stone-a), var(--stone-b));
  background-blend-mode: overlay, normal, normal;
  box-shadow:
    inset 5px 6px 8px rgba(255, 255, 255, .22),
    inset -7px -9px 14px rgba(0, 0, 0, .5),
    5px 6px 0 -1px rgba(20, 16, 30, .95),
    0 0 26px 6px var(--aura),
    0 22px 26px -6px rgba(0, 0, 0, .7);
  transform-origin: 50% 100%;
  transform: rotate(var(--tilt)) rotateX(calc(6deg + var(--rx))) rotateY(var(--ry));
  transition: transform .25s cubic-bezier(.2, .8, .3, 1), box-shadow .3s; }
/* Grabado: oscuro en el fondo del surco, luz en el borde inferior. */
.hw-door-num, .hw-door-tag, .hw-door-rip { color: rgba(18, 14, 28, .82);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .28), 0 -1px 1px rgba(0, 0, 0, .55); }
.hw-door-rip { font-family: Georgia, 'Times New Roman', serif; font-size: .62rem; font-weight: 700; letter-spacing: 3px; opacity: .75; }
.hw-door-num { font-family: Georgia, 'Times New Roman', serif; font-size: 1.85rem; font-weight: 800; line-height: 1; }
.hw-door-tag { font-size: .68rem; font-weight: 800; text-align: center; padding: 0 6px; line-height: 1.15; }
/* Montículo de tierra con hierba, por delante del pie de la lápida. */
.hw-mound { position: absolute; left: -6%; right: -6%; bottom: 0; height: 22%; z-index: 3; pointer-events: none;
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  background: radial-gradient(90% 120% at 50% 0%, #5a3d2a, #2b1b12 62%, #140c08); box-shadow: inset 0 3px 4px rgba(255, 200, 150, .12); }
.hw-mound::before { content: ''; position: absolute; left: 22%; right: 22%; top: -6px; height: 10px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='10'%3E%3Cg stroke='%232f4a22' stroke-width='1.6' fill='none' stroke-linecap='round'%3E%3Cpath d='M3 10 Q4 6 2 3 M5 10 Q6 5 8 2 M14 10 Q13 7 15 5 M24 10 Q26 4 23 1 M27 10 Q28 7 31 5 M40 10 Q39 6 42 3 M43 10 Q45 7 44 4 M54 10 Q55 5 57 3'/%3E%3C/g%3E%3C/svg%3E") repeat-x;
  background-size: 60px 10px; opacity: .85; }
a.hw-door { cursor: pointer; }
a.hw-door:active .hw-stone { transform: rotate(var(--tilt)) rotateX(calc(10deg + var(--rx))) rotateY(var(--ry)) scale(.97); }
a.hw-door:focus-visible { outline: none; }
a.hw-door:focus-visible .hw-stone { box-shadow: 0 0 0 3px #ffb347, 0 22px 26px -6px rgba(0, 0, 0, .7); }

/* Estados */
.hw-door.is-open { --stone-a: #9b96b5; --stone-b: #4c4766; --aura: rgba(192, 132, 252, .28); }
.hw-door.is-missed { --stone-a: #6e6b7a; --stone-b: #34323d; filter: saturate(.5) brightness(.8); }
.hw-door.is-missed .hw-door-tag { font-size: 1.25rem; }
.hw-door.is-locked { --stone-a: #57545f; --stone-b: #26242c; filter: brightness(.62); }
.hw-door.is-locked .hw-stone { transform: rotate(var(--tilt)) rotateX(6deg) translateY(9%); }
/* Grieta en las que aún no se pueden abrir. */
.hw-door.is-locked .hw-stone::after { content: ''; position: absolute; inset: 58% 12% 8% 58%; opacity: .6;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 50'%3E%3Cpath d='M18 0 L12 14 L19 22 L9 35 L14 50' stroke='%23110e18' stroke-width='1.6' fill='none'/%3E%3C/svg%3E") no-repeat center / contain; }
.hw-door.is-completed { --stone-a: #8fa38a; --stone-b: #3c5140; --aura: rgba(134, 239, 172, .22); }
/* Musgo en el pie. */
.hw-door.is-completed .hw-stone::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 38%; border-radius: inherit;
  background: radial-gradient(60% 50% at 15% 100%, rgba(74, 122, 52, .85), transparent 70%),
              radial-gradient(50% 45% at 85% 100%, rgba(74, 122, 52, .75), transparent 70%); pointer-events: none; }
.hw-door.is-completed .hw-door-tag { color: #fde68a; font-size: 1rem; letter-spacing: 2px; text-shadow: 0 0 8px rgba(253, 230, 138, .8), 0 1px 0 rgba(0, 0, 0, .6); }
.hw-door.is-claimable { --aura: rgba(253, 230, 138, .55); }
.hw-door.is-claimable .hw-stone { animation: hw-claim 1.8s ease-in-out infinite; }
.hw-door.is-claimable .hw-door-tag { color: #fde68a; text-shadow: 0 0 8px rgba(253, 230, 138, .9), 0 1px 0 rgba(0, 0, 0, .7); }
@keyframes hw-claim { 50% { box-shadow: inset 5px 6px 8px rgba(255, 255, 255, .22), inset -7px -9px 14px rgba(0, 0, 0, .5), 5px 6px 0 -1px rgba(20, 16, 30, .95), 0 0 34px 12px rgba(253, 230, 138, .7), 0 22px 26px -6px rgba(0, 0, 0, .7); } }
/* Hoy: piedra encendida por una vela que parpadea. */
.hw-door.is-today { --stone-a: #ffb062; --stone-b: #b4410f; --aura: rgba(255, 140, 0, .6); }
.hw-door.is-today .hw-door-num, .hw-door.is-today .hw-door-tag, .hw-door.is-today .hw-door-rip { color: rgba(40, 12, 0, .88); text-shadow: 0 1px 0 rgba(255, 220, 170, .5); }
.hw-door.is-today .hw-stone { animation: hw-candle 2.4s steps(1, end) infinite, hw-candle-soft 1.1s ease-in-out infinite alternate; }
.hw-door.is-today .hw-mound::after { content: ''; position: absolute; left: 50%; top: -20px; width: 10px; height: 16px; margin-left: -5px;
  border-radius: 50% 50% 45% 45% / 70% 70% 30% 30%; background: radial-gradient(circle at 50% 70%, #fff6c9, #ffb347 55%, rgba(255, 90, 0, 0) 75%);
  filter: drop-shadow(0 0 8px #ff9a3c); animation: hw-flame .6s ease-in-out infinite alternate; transform-origin: 50% 100%; }
@keyframes hw-candle-soft { from { filter: brightness(1); } to { filter: brightness(1.12); } }
@keyframes hw-candle { 0%, 100% { --aura: rgba(255, 140, 0, .6); } 37% { --aura: rgba(255, 170, 40, .85); } 52% { --aura: rgba(255, 120, 0, .45); } }
@keyframes hw-flame { from { transform: scale(1, 1) rotate(-3deg); } to { transform: scale(.9, 1.12) rotate(3deg); } }

/* Brotar del suelo al llegar, en cascada. */
.hw-door.is-emerging .hw-stone { animation: hw-emerge .75s cubic-bezier(.2, .9, .25, 1.15) both; animation-delay: calc(var(--i) * 40ms); }
.hw-door.is-emerging.is-today .hw-stone { animation: hw-emerge .75s cubic-bezier(.2, .9, .25, 1.15) both, hw-candle-soft 1.1s ease-in-out .9s infinite alternate;
  animation-delay: calc(var(--i) * 40ms), calc(var(--i) * 40ms + .75s); }
@keyframes hw-emerge {
  from { transform: rotate(var(--tilt)) rotateX(20deg) translateY(95%); }
  70% { transform: rotate(var(--tilt)) rotateX(4deg) translateY(-4%); }
  to { transform: rotate(var(--tilt)) rotateX(6deg) translateY(0); } }

/* Arrancarla del suelo: tiembla, la tierra salta y sale volando hacia ti. */
.hw-door.is-rising { z-index: 5; }
.hw-door.is-rising .hw-stone { animation: hw-rise .72s cubic-bezier(.5, 0, .6, 1) forwards; }
@keyframes hw-rise {
  0% { transform: rotate(var(--tilt)) rotateX(6deg); }
  8% { transform: rotate(calc(var(--tilt) - 4deg)) rotateX(6deg) translateY(2%); }
  16% { transform: rotate(calc(var(--tilt) + 4deg)) rotateX(6deg) translateY(1%); }
  24% { transform: rotate(calc(var(--tilt) - 3deg)) rotateX(6deg) translateY(2%); }
  34% { transform: rotate(var(--tilt)) rotateX(6deg) translateY(-6%); }
  100% { transform: rotate(0deg) rotateX(-28deg) translateY(-70%) translateZ(220px) scale(1.25); opacity: 0; } }
.hw-clod { position: absolute; left: 50%; bottom: 14%; z-index: 3; width: 7px; height: 6px; margin-left: -3px; pointer-events: none;
  border-radius: 40% 60% 50% 45%; background: #4a3122; box-shadow: inset -1px -1px 0 rgba(0, 0, 0, .4);
  transform: scale(var(--s)); opacity: 0; animation: hw-clod .55s cubic-bezier(.2, .6, .4, 1) forwards; }
@keyframes hw-clod {
  0% { opacity: 1; transform: translate(0, 0) scale(var(--s)); }
  60% { opacity: 1; transform: translate(calc(var(--dx) * .8), var(--dy)) scale(var(--s)) rotate(120deg); }
  100% { opacity: 0; transform: translate(var(--dx), calc(var(--dy) + 40px)) scale(var(--s)) rotate(220deg); } }
.hw-pill-candy { background: rgba(194, 65, 12, .3); border-color: rgba(251, 146, 60, .6); }
/* Los caramelos llevan a la tienda: un botón, con una vuelta y un destello cada
   pocos segundos para invitar a tocarlo (y el contador de la cabecera, igual, solo
   en el calendario). */
button.hw-pill-candy { font: inherit; font-weight: 700; color: inherit; cursor: pointer; position: relative; overflow: hidden;
  -webkit-tap-highlight-color: transparent; }
button.hw-pill-candy:active { transform: scale(.95); }
.hw-candy-ic, .hw-page .hsb-candy > span:first-child { display: inline-block; animation: hw-candy-spin 5s ease-in-out infinite; }
.hw-page .hsb-candy > span:first-child { animation-delay: 2.5s; }
@keyframes hw-candy-spin {
  0%, 78%, 100% { transform: none; }
  82% { transform: translateY(-3px) rotate(-25deg) scale(1.15); }
  90% { transform: translateY(-5px) rotate(340deg) scale(1.2); }
  95% { transform: translateY(0) rotate(360deg) scale(.95); } }
button.hw-pill-candy::after { content: ''; position: absolute; top: 0; bottom: 0; left: -60%; width: 45%; pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255, 236, 200, .75), transparent); transform: skewX(-20deg);
  animation: hw-candy-shine 5s ease-in-out infinite; }
@keyframes hw-candy-shine { 0%, 84% { left: -60%; } 96%, 100% { left: 130%; } }
/* Llegada a la tienda: un resplandor naranja que se apaga. */
.hw-shop { scroll-margin-top: 84px; outline: none; }
.hw-shop.is-spotlight { animation: hw-spotlight 1.8s ease-out; border-radius: 18px; }
@keyframes hw-spotlight {
  0% { box-shadow: 0 0 0 0 rgba(255, 140, 0, 0); }
  25% { box-shadow: 0 0 0 6px rgba(255, 140, 0, .35), 0 0 40px 10px rgba(255, 140, 0, .35); }
  100% { box-shadow: 0 0 0 0 rgba(255, 140, 0, 0); } }
.hw-candy-toast { position: relative; z-index: 1; margin: 4px auto 0; width: fit-content; max-width: 100%; padding: 8px 16px; border-radius: 999px;
  background: linear-gradient(90deg, #c2410c, #ff9a3c); color: #1a0b00; font-weight: 800; text-align: center;
  box-shadow: 0 0 22px rgba(255, 140, 0, .5); animation: hw-toast-in .5s ease; }
@keyframes hw-toast-in { from { opacity: 0; transform: translateY(-8px) scale(.95); } }
.hw-how { position: relative; margin: 26px auto 0; max-width: 520px; padding: 12px 16px; border-radius: 14px;
  background: rgba(20, 10, 34, .7); border: 1px solid rgba(255, 140, 0, .3); }
.hw-how summary { cursor: pointer; font-weight: 800; color: #ffb347; }
.hw-how ul { margin: 10px 0 0; padding-left: 1.1rem; display: grid; gap: 6px; }
.hw-how p { margin: 10px 0 0; opacity: .85; }
/* Premio de las 27 puertas y tienda del terror (entrega 3). */
.hw-prize { position: relative; display: flex; align-items: center; gap: 14px; margin: 22px auto 0; max-width: 520px; padding: 14px 16px;
  border-radius: 16px; background: linear-gradient(135deg, rgba(59, 29, 94, .85), rgba(20, 10, 34, .9)); border: 1px solid rgba(192, 132, 252, .45); }
.hw-prize-emoji { font-size: 2.6rem; line-height: 1; }
.hw-prize-txt { display: flex; flex-direction: column; gap: 2px; }
.hw-prize-txt strong { color: #fde68a; }
.hw-prize-txt span { font-size: .88rem; opacity: .85; }
.hw-prize.is-owned { border-color: #86efac; }
.hw-shop { position: relative; margin: 26px auto 0; max-width: 520px; }
.hw-shop-title { margin: 0; font-size: 1.25rem; color: #ffb347; text-align: center; }
.hw-shop-sub { margin: 6px auto 12px; max-width: 36ch; text-align: center; font-size: .9rem; opacity: .85; }
.hw-shop-items { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; }
.hw-item { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 10px; border-radius: 16px;
  background: rgba(20, 10, 34, .75); border: 1px solid rgba(255, 140, 0, .3); text-align: center; }
.hw-item.is-owned { border-color: #86efac; }
.hw-item-emoji { font-size: 2.4rem; line-height: 1.1; }
.hw-item-swatch { width: 44px; height: 44px; border-radius: 12px; border: 3px solid #f59e0b;
  background: radial-gradient(circle at 50% 110%, rgba(245, 158, 11, .7), transparent 60%), linear-gradient(180deg, #1f1030, #0b0612); }
.hw-item-name { font-weight: 800; font-size: .92rem; }
.hw-item-btn { min-width: 100%; padding: 8px 10px; border-radius: 999px; border: 0; font-weight: 800; cursor: pointer;
  background: linear-gradient(90deg, #c2410c, #ff9a3c); color: #1a0b00; }
.hw-item-btn:disabled { opacity: .55; cursor: default; }
.hw-item-btn.is-use { background: rgba(134, 239, 172, .18); color: #bbf7d0; border: 1px solid #86efac; }
.hw-item-inuse { font-size: .85rem; font-weight: 800; color: #86efac; }
.hw-conversion { position: relative; margin: 18px auto 0; max-width: 520px; padding: 12px 16px; border-radius: 14px; text-align: center;
  background: rgba(34, 197, 94, .15); border: 1px solid rgba(134, 239, 172, .5); font-weight: 700; }
/* Bichos del cementerio (halloween-critters.js): siluetas pequeñas y oscuras que
   aparecen de una en una. La trayectoria la lleva la Web Animations API; aquí solo
   el aspecto y el movimiento de patas y alas. */
.hw-critter { position: absolute; left: 0; top: 0; pointer-events: none; color: #0b0712; will-change: transform; }
.hw-critter svg { display: block; width: 100%; height: 100%; }
.hw-spider { width: 22px; height: 22px; margin: -11px 0 0 -11px; color: #140f1c;
  filter: drop-shadow(0 0 1.5px rgba(255, 255, 255, .55)) drop-shadow(0 2px 2px rgba(0, 0, 0, .6)); }
.hw-spider .hw-legs { animation: hw-legs .18s steps(2, end) infinite; transform-origin: 50% 50%; }
.hw-beetle { width: 24px; height: 16px; z-index: 4; color: #161d15;
  /* Brillo de caparazón: sin él, negro sobre tierra oscura no se ve. */
  filter: drop-shadow(0 0 1.2px rgba(215, 240, 200, .5)) drop-shadow(0 2px 1px rgba(0, 0, 0, .7)); }
.hw-beetle .hw-legs { animation: hw-legs .12s steps(2, end) infinite; transform-origin: 50% 80%; }
@keyframes hw-legs { 50% { transform: scaleX(.86) translateY(.4px); } }
.hw-bat { width: 44px; height: 20px; z-index: 0; color: #1a1028;
  /* Borde de luz de luna: una silueta negra sobre el cielo oscuro no se lee. */
  filter: drop-shadow(0 0 2px rgba(225, 205, 255, .75)); }
.hw-bat .hw-wing { transform-box: fill-box; animation: hw-flap .22s ease-in-out infinite alternate; }
.hw-bat .hw-wing-l { transform-origin: 100% 60%; }
.hw-bat .hw-wing-r { transform-origin: 0% 60%; }
/* Gusano: rosado sobre la tierra, entre la lápida y el montículo (z 2 < 3). */
.hw-worm { width: 12px; height: 34px; margin-left: -6px; z-index: 2; color: #e39a9a; transform-origin: 50% 100%;
  filter: drop-shadow(0 0 1px rgba(255, 220, 220, .5)); }
.hw-worm .hw-worm-body { animation: hw-wiggle .5s ease-in-out infinite alternate; transform-origin: 50% 100%; transform-box: fill-box; }
@keyframes hw-wiggle { from { transform: skewX(-6deg); } to { transform: skewX(6deg); } }
@keyframes hw-flap { from { transform: scaleY(1); } to { transform: scaleY(-.35); } }

@media (prefers-reduced-motion: reduce) {
  .hw-fog, .hw-candy-toast, .hw-door .hw-stone, .hw-door.is-today .hw-mound::after, .hw-clod { animation: none !important; }
  .hw-critter { display: none; }
  .hw-candy-ic, .hw-page .hsb-candy > span:first-child, button.hw-pill-candy::after, .hw-shop.is-spotlight { animation: none !important; }
  .hw-stone { transition: none; }
}
