/* Seasonal particles (seasons.js). The container must be positioned and clip its overflow;
   the span moves along the path, its ::before carries the shape plus a secondary motion. */
.season-p {
    position: absolute; left: var(--x); top: -40px;
    width: calc(var(--size) * 22px); height: calc(var(--size) * 22px);
    pointer-events: none; will-change: transform;
    animation: season-fall var(--dur) linear var(--delay) infinite;
}
.season-p::before {
    content: ""; position: absolute; inset: 0;
    background: center / contain no-repeat;
    animation: season-spin calc(var(--dur) / 2) ease-in-out var(--delay) infinite alternate;
}

.season-p--snow { width: calc(var(--size) * 9px); height: calc(var(--size) * 9px); opacity: .85; }
.season-p--snow::before { background: radial-gradient(circle, #fff 35%, rgba(255, 255, 255, 0) 70%); animation: none; }

.season-p--rain { width: 2px; height: calc(var(--size) * 22px); opacity: .55; }
.season-p--rain::before { background: linear-gradient(rgba(255, 255, 255, 0), #fff); border-radius: 1px; animation: none; transform: rotate(5deg); }

.season-p--autumn::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2C6 6 4 12 6 18c2 2 4 3 6 3s4-1 6-3c2-6 0-12-6-16z' fill='%23e8892b'/%3E%3Cpath d='M12 4v19' stroke='%23a5501a' stroke-width='1.2'/%3E%3C/svg%3E"); }

.season-p--halloween {
    top: var(--y); left: -60px; width: calc(var(--size) * 34px); height: calc(var(--size) * 18px); opacity: .8;
    animation-name: season-fly; animation-timing-function: ease-in-out;
}
.season-p--halloween::before {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 32'%3E%3Cpath d='M32 10c-2-3-1-6 0-8 1 2 2 2 2 2s1 0 2-2c1 2 2 5 0 8 6-4 14-8 28-6-6 2-8 6-8 10-4-3-8-2-10 2-2-3-6-3-9 0-1 4-3 8-5 10-2-2-4-6-5-10-3-3-7-3-9 0-2-4-6-5-10-2 0-4-2-8-8-10 14-2 22 2 28 6z' fill='%231b2333'/%3E%3C/svg%3E");
    animation: season-flap .22s ease-in-out infinite alternate;
}

.season-p--newyear { width: calc(var(--size) * 7px); height: calc(var(--size) * 12px); }
.season-p--newyear::before { background: var(--c); border-radius: 1px; animation-duration: .6s; }

.season-p--burst {
    left: var(--ox); top: var(--oy);
    animation: season-burst 1.6s cubic-bezier(.15, .7, .3, 1) forwards;
}

@keyframes season-fall { to { transform: translate3d(var(--drift), var(--fall), 0); } }
@keyframes season-spin { to { transform: rotate(var(--spin)); } }
@keyframes season-flap { to { transform: scaleY(.45); } }
@keyframes season-fly {
    0% { transform: translate3d(0, 0, 0); }
    25% { transform: translate3d(calc(var(--width) * .25), -30px, 0); }
    50% { transform: translate3d(calc(var(--width) * .5), 20px, 0); }
    75% { transform: translate3d(calc(var(--width) * .75), -20px, 0); }
    100% { transform: translate3d(var(--width), 0, 0); }
}
/* props around the mascot (christmas gifts, easter eggs): anchored bottom-center via `translate`,
   so the animation is free to use `transform`. Mostly still, a short wiggle or hop now and then. */
.season-prop {
    position: absolute; translate: -50% -100%; transform-origin: 50% 100%; pointer-events: none;
    animation: season-wiggle 6s ease-in-out var(--delay) infinite;
}
.season-prop--hop { animation-name: season-hop; }
@keyframes season-wiggle {
    0%, 82%, 100% { transform: rotate(0); }
    86% { transform: rotate(-7deg); }
    90% { transform: rotate(6deg); }
    94% { transform: rotate(-3deg); }
}
@keyframes season-hop {
    0%, 80%, 100% { transform: translateY(0) scale(1, 1); }
    83% { transform: translateY(0) scale(1.08, .9); }
    88% { transform: translateY(-22%) scale(.96, 1.05); }
    93% { transform: translateY(0) scale(1.06, .94); }
    96% { transform: translateY(-6%); }
}
/* glowing jack-o'-lantern (halloween): additive candle light over the pumpkin, flickering */
.season-glow {
    position: absolute; translate: -50% -50%; aspect-ratio: 1; border-radius: 50%; z-index: 3; pointer-events: none;
    mix-blend-mode: screen; opacity: .85;
    background: radial-gradient(circle, rgba(255, 200, 80, .75) 0 18%, rgba(255, 120, 0, .4) 42%, rgba(255, 80, 0, 0) 70%);
    animation: season-flicker var(--glow-dur, 3s) linear var(--glow-delay, 0s) infinite;
}
@keyframes season-flicker {
    0%, 100% { opacity: calc(var(--glow-max, 1) * .85); }
    8% { opacity: calc(var(--glow-max, 1) * .35); }
    11% { opacity: var(--glow-max, 1); }
    40% { opacity: calc(var(--glow-max, 1) * .75); }
    43% { opacity: calc(var(--glow-max, 1) * .2); }
    46% { opacity: calc(var(--glow-max, 1) * .95); }
    70% { opacity: calc(var(--glow-max, 1) * .6); }
    74% { opacity: var(--glow-max, 1); }
}
/* ground shadow under a dressed mascot (seasons.js ground()) */
.season-shadow {
    position: absolute; height: 34px; translate: -50% -60%; border-radius: 50%; z-index: 1; pointer-events: none;
    background: radial-gradient(closest-side, rgba(16, 30, 54, .5), rgba(16, 30, 54, .25) 55%, rgba(16, 30, 54, 0));
}
@media (prefers-reduced-motion: reduce) { .season-prop, .season-glow { animation: none; } }
@keyframes season-burst {
    from { transform: translate(-50%, -50%) scale(.3); opacity: 1; }
    to { transform: translate(calc(-50% + var(--bx)), calc(-50% + var(--by))) scale(1); opacity: 0; }
}

/* valentine: hearts rising from the bottom */
.season-p--hearts { top: auto; bottom: -30px; width: calc(var(--size) * 18px); height: calc(var(--size) * 16px); opacity: .85; animation-name: season-rise; }
.season-p--hearts::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 22'%3E%3Cpath d='M12 21S1 14 1 7a5.5 5.5 0 0 1 11-1 5.5 5.5 0 0 1 11 1c0 7-11 14-11 14z' fill='%23e94e77'/%3E%3C/svg%3E"); animation-name: season-sway; }
@keyframes season-rise { to { transform: translate3d(var(--drift), calc(var(--fall) * -1), 0); } }
@keyframes season-sway { from { transform: rotate(-12deg); } to { transform: rotate(12deg); } }

/* evening sky (seasons.js sky()) */
.season-sky { position: absolute; inset: 0; pointer-events: none; background: linear-gradient(180deg, rgba(10, 18, 48, .45), rgba(10, 18, 48, 0) 75%); }
.season-star {
    position: absolute; left: var(--x); top: var(--y); width: var(--size); height: var(--size); border-radius: 50%; pointer-events: none;
    background: #fff; box-shadow: 0 0 6px rgba(255, 255, 255, .8);
    animation: season-twinkle var(--dur) ease-in-out var(--delay) infinite alternate;
}
.season-moon {
    position: absolute; top: 9%; right: 5%; width: 64px; aspect-ratio: 1; border-radius: 50%; pointer-events: none;
    background: radial-gradient(circle at 38% 38%, #fffdf0, #f6e9b0 60%, #e6cf78);
    box-shadow: 0 0 40px 12px rgba(255, 240, 190, .3);
}
/* rays of a sparkling star, flaring up now and then */
.season-star--glint::before, .season-star--glint::after {
    content: ""; position: absolute; left: 50%; top: 50%; width: calc(var(--size) * 6); height: 1px; translate: -50% -50%;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0), #fff, rgba(255, 255, 255, 0));
}
.season-star--glint::after { rotate: 90deg; }
.season-star--glint { animation-name: season-glint; animation-direction: normal; animation-duration: calc(var(--dur) * 2); }
@keyframes season-twinkle { from { opacity: .25; scale: .7; } to { opacity: 1; scale: 1.15; } }
@keyframes season-glint {
    0%, 70%, 100% { opacity: .5; scale: .6; rotate: 0deg; }
    80% { opacity: 1; scale: 1.5; rotate: 45deg; }
    90% { opacity: .8; scale: 1; rotate: 45deg; }
}

/* thunderstorm: short double flash every few seconds */
.season-flash { position: absolute; inset: 0; pointer-events: none; background: #fff; opacity: 0; animation: season-flash 9s linear -6.6s infinite; }
@keyframes season-flash {
    0%, 88%, 100% { opacity: 0; }
    89% { opacity: .5; }
    90% { opacity: 0; }
    91.5% { opacity: .3; }
    93% { opacity: 0; }
}

/* greeting bubble above the mascot (click) */
.season-bubble {
    position: absolute; z-index: 5; translate: -50% -100%; pointer-events: none; white-space: nowrap;
    padding: 10px 16px; border-radius: 16px; background: #fff; color: #101e36; font-weight: 600; font-size: 15px; line-height: 1.3;
    box-shadow: 0 10px 28px rgba(16, 30, 54, .28); animation: season-pop .25s ease-out; transition: opacity .4s;
}
.season-bubble::after { content: ""; position: absolute; left: 50%; bottom: -8px; translate: -50% 0; border: 9px solid transparent; border-top-color: #fff; border-bottom: 0; }
.season-bubble--out { opacity: 0; }
@keyframes season-pop { from { transform: scale(.6); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .season-star, .season-bubble { animation: none; } }

/* alarm clock next to the sleeping mascot (seasons.js clock()): painted body, hands animate on from the visitor's time */
.season-clock { position: absolute; z-index: 3; aspect-ratio: 240 / 258; translate: -50% -100%; pointer-events: none; filter: drop-shadow(0 6px 10px rgba(16, 30, 54, .35)); }
.season-clock img { display: block; width: 100%; }
/* dial position within clock.webp */
.season-clock-face { position: absolute; left: 12.25%; top: 29.8%; width: 65.5%; aspect-ratio: 1; }
.season-clock-face::after { content: ""; position: absolute; left: 50%; top: 50%; width: 9%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; background: #e94e77; }
.season-clock-face span {
    position: absolute; left: 50%; bottom: 50%; translate: -50% 0; transform-origin: 50% 100%; border-radius: 2px;
    background: #101e36; rotate: var(--a); animation: season-hand var(--period) linear infinite;
}
.season-clock-hour { width: 7%; height: 24%; }
.season-clock-minute { width: 5%; height: 34%; }
.season-clock-face .season-clock-second { width: 2%; height: 38%; background: #e94e77; animation-timing-function: steps(60); }
@keyframes season-hand { to { rotate: calc(var(--a) + 360deg); } }
@media (prefers-reduced-motion: reduce) { .season-clock-face span { animation: none; } }
