/* Seasonal site themes, picked by the owner in /admin → Theme Switcher.
   Only loaded while one is on: <html data-site-theme="halloween|christmas|newyear">.
   Every visitor's own colour theme stays; the season retints the accent, dresses
   the orb (hat, cape, scarf, bow tie) and adds decorations that never take clicks.
   site-themes.js builds the moving parts (bats, snow, fireworks, mascot, lights). */

/* ------------------------------------------------------------- accents
   --blue drives --brand everywhere. Dark colour themes get a brighter shade so
   buttons and links keep their contrast on both backgrounds. */
html[data-site-theme="halloween"] { --blue: #ea580c; --blue-rgb: 234, 88, 12; --violet: #9333ea; --violet-rgb: 147, 51, 234; --purple: #ea580c; --st-glow: 249, 115, 22; }
html[data-site-theme="christmas"] { --blue: #dc2626; --blue-rgb: 220, 38, 38; --violet: #16a34a; --violet-rgb: 22, 163, 74; --purple: #dc2626; --st-glow: 239, 68, 68; }
html[data-site-theme="newyear"] { --blue: #b7791f; --blue-rgb: 183, 121, 31; --violet: #7c3aed; --violet-rgb: 124, 58, 237; --purple: #b7791f; --st-glow: 245, 197, 66; }
html[data-site-theme="halloween"]:is([data-theme="dyno"], [data-theme="super"], [data-theme="dusk"]) { --blue: #f97316; --blue-rgb: 249, 115, 22; --purple: #f97316; }
html[data-site-theme="christmas"]:is([data-theme="dyno"], [data-theme="super"], [data-theme="dusk"]) { --blue: #ef4444; --blue-rgb: 239, 68, 68; --purple: #ef4444; }
html[data-site-theme="newyear"]:is([data-theme="dyno"], [data-theme="super"], [data-theme="dusk"]) { --blue: #f5c542; --blue-rgb: 245, 197, 66; --purple: #f5c542; }

/* The floating bar picks up a soft seasonal glow. */
html[data-site-theme] .topbar-floating { box-shadow: 0 0 0 1px rgb(var(--st-glow) / .22), 0 12px 34px rgb(var(--st-glow) / .16); }

/* Shared layer for everything decorative. */
.st-layer { position: fixed; pointer-events: none; z-index: 55; }
.st-layer svg { display: block; width: 100%; height: 100%; }

/* ------------------------------------------------------------- the orb in costume
   Every .nx-orb on the site (empty states, 404 DJ, shop, mascot, the one by the
   logo) becomes a little character: a face with sparkly eyes, rosy cheeks and a
   mouth, a hat (::before) and a cape / scarf / bow tie (::after). Everything
   scales with --s. [data-st-preview] lets the admin Theme Switcher cards show
   a costume without the whole site switching theme. */
:is(html[data-site-theme], [data-st-preview]) :is(.nx-orb, .cb-blob-wrap)::before,
:is(html[data-site-theme], [data-st-preview]) :is(.nx-orb, .cb-blob-wrap)::after { content: ""; position: absolute; pointer-events: none; background: center / contain no-repeat; }
:is(html[data-site-theme], [data-st-preview]) :is(.nx-orb, .cb-blob-wrap)::before { z-index: 3; }
:is(html[data-site-theme], [data-st-preview]) :is(.nx-orb, .cb-blob-wrap)::after { z-index: 2; left: calc(var(--s) * -.2); top: calc(var(--s) * -.15); width: calc(var(--s) * 1.4); height: calc(var(--s) * 1.3); }
:is(html[data-site-theme], [data-st-preview]) .nx-orb-eyes { gap: calc(var(--s) * .2); top: 44%; }
/* Rosy cheeks, just outside and below the eyes. */
:is(html[data-site-theme], [data-st-preview]) .nx-orb-eyes::before { content: ""; position: absolute; left: 50%; top: calc(var(--s) * .1); width: calc(var(--s) * .66); height: calc(var(--s) * .11); transform: translateX(-50%); pointer-events: none;
    background: radial-gradient(closest-side, rgb(255 105 150 / .6), transparent) 0 0 / 27% 100% no-repeat, radial-gradient(closest-side, rgb(255 105 150 / .6), transparent) 100% 0 / 27% 100% no-repeat; }
:is(html[data-site-theme], [data-st-preview]) .nx-orb-eyes::after { content: ""; position: absolute; left: 50%; transform: translateX(-50%); pointer-events: none; }
/* Big glossy eyes with a sparkle (Christmas and New Year; Halloween glows instead). */
:is(html:is([data-site-theme="christmas"], [data-site-theme="newyear"]), [data-st-preview="christmas"], [data-st-preview="newyear"]) .nx-orb-eyes i {
    width: calc(var(--s) * .12); height: calc(var(--s) * .16); border-radius: 50%; box-shadow: none;
    background: radial-gradient(circle at 34% 28%, #fff 0 17%, transparent 19%), radial-gradient(circle at 66% 70%, rgb(255 255 255 / .7) 0 8%, transparent 10%), #24132e; }
:is(html[data-site-theme], [data-st-preview]) .nx-orb.is-happy .nx-orb-eyes i { height: calc(var(--s) * .09); border-radius: 99px 99px var(--radius-sm) var(--radius-sm); }

/* Halloween: a cute jack-o'-lantern in a witch hat and a little vampire cape. */
:is(html[data-site-theme="halloween"], [data-st-preview="halloween"]) .nx-orb {
    background:
        radial-gradient(circle at 30% 22%, rgb(255 247 230 / .9) 0 5%, rgb(255 214 170 / .45) 11%, transparent 26%),
        radial-gradient(ellipse 20% 46% at 33% 52%, transparent 88%, rgb(124 45 18 / .28) 94%, transparent 100%),
        radial-gradient(ellipse 20% 46% at 67% 52%, transparent 88%, rgb(124 45 18 / .28) 94%, transparent 100%),
        radial-gradient(ellipse 70% 40% at 50% 100%, #ffd166 0 18%, rgb(255 190 92 / .45) 45%, transparent 72%),
        radial-gradient(circle at 48% 44%, #ffa23d 0 36%, #f47414 60%, #c2470c 86%, #7c2d12 100%);
    box-shadow: inset 0 calc(var(--s) * -.07) calc(var(--s) * .14) rgb(255 200 100 / .5), inset 0 calc(var(--s) * .06) calc(var(--s) * .16) rgb(255 255 255 / .3),
        0 calc(var(--s) * .2) calc(var(--s) * .38) calc(var(--s) * -.1) rgb(234 88 12 / .55), 0 0 calc(var(--s) * .4) calc(var(--s) * -.08) rgb(147 51 234 / .45);
}
/* Glowing, softly rounded triangle eyes with a candle flicker. */
:is(html[data-site-theme="halloween"], [data-st-preview="halloween"]) .nx-orb-eyes i { width: calc(var(--s) * .19); height: calc(var(--s) * .17); border-radius: var(--radius-sm); box-shadow: none;
    background: radial-gradient(circle at 50% 70%, #fff7c2 0 25%, #fde047 55%, #f59e0b 100%); clip-path: polygon(50% 0, 98% 82%, 88% 100%, 12% 100%, 2% 82%);
    filter: drop-shadow(0 0 calc(var(--s) * .05) #facc15); animation: nx-orb-blink 4.8s infinite, st-flicker 2.6s ease-in-out infinite; }
@keyframes st-flicker { 0%, 100% { opacity: 1; } 45% { opacity: .82; } 55% { opacity: .95; } }
:is(html[data-site-theme="halloween"], [data-st-preview="halloween"]) .nx-orb-eyes { gap: calc(var(--s) * .16); }
:is(html[data-site-theme="halloween"], [data-st-preview="halloween"]) .nx-orb-eyes::before { top: calc(var(--s) * .14); width: calc(var(--s) * .74); background: radial-gradient(closest-side, rgb(255 120 90 / .55), transparent) 0 0 / 27% 100% no-repeat, radial-gradient(closest-side, rgb(255 120 90 / .55), transparent) 100% 0 / 27% 100% no-repeat; }
/* A small carved smile with one little tooth. */
:is(html[data-site-theme="halloween"], [data-st-preview="halloween"]) .nx-orb-eyes::after { top: calc(var(--s) * .22); width: calc(var(--s) * .38); height: calc(var(--s) * .13); background: radial-gradient(circle at 50% 70%, #fff7c2, #fde047 60%, #f59e0b);
    filter: drop-shadow(0 0 calc(var(--s) * .03) #facc15); clip-path: polygon(0 0, 22% 22%, 44% 30%, 44% 0, 56% 0, 56% 30%, 78% 22%, 100% 0, 92% 55%, 72% 92%, 50% 100%, 28% 92%, 8% 55%); }
:is(html[data-site-theme="halloween"], [data-st-preview="halloween"]) :is(.nx-orb, .cb-blob-wrap)::before { width: calc(var(--s) * .98); height: calc(var(--s) * .82); left: 50%; bottom: calc(var(--s) * .7); transform: translateX(-44%) rotate(-9deg); background-image: url("/site-themes/witch-hat.webp"); }
:is(html[data-site-theme="halloween"], [data-st-preview="halloween"]) :is(.nx-orb, .cb-blob-wrap)::after { background-image: url("/site-themes/cape.webp");
    /* The cape sits behind the orb: everything inside the orb's circle is masked away. */
    -webkit-mask: radial-gradient(circle calc(var(--s) * .5) at calc(var(--s) * .7) calc(var(--s) * .65), transparent 97%, #000 100%);
    mask: radial-gradient(circle calc(var(--s) * .5) at calc(var(--s) * .7) calc(var(--s) * .65), transparent 97%, #000 100%); }

/* Christmas: a glossy red bauble with a sweet smile, Santa hat and striped scarf. */
:is(html[data-site-theme="christmas"], [data-st-preview="christmas"]) .nx-orb {
    background:
        radial-gradient(ellipse 18% 11% at 30% 22%, rgb(255 255 255 / .95) 0 40%, transparent 100%),
        radial-gradient(circle at 31% 24%, rgb(255 228 228 / .55) 0 10%, transparent 26%),
        radial-gradient(ellipse 70% 40% at 50% 100%, #fecaca 0 14%, rgb(254 202 202 / .35) 42%, transparent 72%),
        radial-gradient(circle at 48% 42%, #f25757 0 38%, #dc2626 60%, #b91c1c 84%, #7f1d1d 100%);
    box-shadow: inset 0 calc(var(--s) * -.07) calc(var(--s) * .14) rgb(255 220 220 / .45), inset 0 calc(var(--s) * .06) calc(var(--s) * .16) rgb(255 255 255 / .35),
        0 calc(var(--s) * .2) calc(var(--s) * .38) calc(var(--s) * -.1) rgb(220 38 38 / .5), 0 0 calc(var(--s) * .4) calc(var(--s) * -.08) rgb(22 163 74 / .4);
}
:is(html[data-site-theme="christmas"], [data-st-preview="christmas"]) .nx-orb-eyes::before { background: radial-gradient(closest-side, rgb(255 190 200 / .75), transparent) 0 0 / 27% 100% no-repeat, radial-gradient(closest-side, rgb(255 190 200 / .75), transparent) 100% 0 / 27% 100% no-repeat; }
/* A small "u" smile. */
:is(html[data-site-theme="christmas"], [data-st-preview="christmas"]) .nx-orb-eyes::after { top: calc(var(--s) * .19); width: calc(var(--s) * .12); height: calc(var(--s) * .065); border: calc(var(--s) * .024) solid #3b0a0a; border-top: 0; border-radius: 0 0 99px 99px; }
:is(html[data-site-theme="christmas"], [data-st-preview="christmas"]) :is(.nx-orb, .cb-blob-wrap)::before { width: calc(var(--s) * .98); height: calc(var(--s) * .8); left: 50%; bottom: calc(var(--s) * .76); transform: translateX(-46%) rotate(-6deg); background-image: url("/site-themes/santa-hat.webp"); }
:is(html[data-site-theme="christmas"], [data-st-preview="christmas"]) :is(.nx-orb, .cb-blob-wrap)::after { background-image: url("/site-themes/scarf.webp"); height: calc(var(--s) * 1.7); }

/* New Year: a shiny gold orb with a big happy grin, party hat and bow tie. */
:is(html[data-site-theme="newyear"], [data-st-preview="newyear"]) .nx-orb {
    background:
        radial-gradient(ellipse 18% 11% at 30% 22%, rgb(255 255 255 / .95) 0 40%, transparent 100%),
        radial-gradient(circle at 31% 24%, rgb(255 246 214 / .55) 0 10%, transparent 26%),
        radial-gradient(ellipse 70% 40% at 50% 100%, #fff1b8 0 16%, rgb(255 236 170 / .4) 44%, transparent 72%),
        radial-gradient(circle at 48% 42%, #f9dc7c 0 34%, #e8b740 58%, #c08a1e 82%, #7a5200 100%);
    box-shadow: inset 0 calc(var(--s) * -.07) calc(var(--s) * .14) rgb(255 240 190 / .55), inset 0 calc(var(--s) * .06) calc(var(--s) * .16) rgb(255 255 255 / .4),
        0 calc(var(--s) * .2) calc(var(--s) * .38) calc(var(--s) * -.1) rgb(212 160 23 / .55), 0 0 calc(var(--s) * .45) calc(var(--s) * -.06) rgb(124 58 237 / .4);
}
/* An open happy grin with a little tongue. */
:is(html[data-site-theme="newyear"], [data-st-preview="newyear"]) .nx-orb-eyes::after { top: calc(var(--s) * .18); width: calc(var(--s) * .15); height: calc(var(--s) * .085); border-radius: 0 0 99px 99px;
    background: radial-gradient(ellipse 60% 70% at 50% 100%, #f472b6 0 55%, transparent 58%), #3d1f00; }
:is(html[data-site-theme="newyear"], [data-st-preview="newyear"]) :is(.nx-orb, .cb-blob-wrap)::before { width: calc(var(--s) * .8); height: calc(var(--s) * .88); left: 50%; bottom: calc(var(--s) * .74); transform: translateX(-40%) rotate(12deg); background-image: url("/site-themes/party-hat.webp"); }
:is(html[data-site-theme="newyear"], [data-st-preview="newyear"]) :is(.nx-orb, .cb-blob-wrap)::after { background-image: url("/site-themes/bowtie.webp"); }

/* The "Start bot" blob (partials/customBotLaunch.ejs) wears the same costume and
   takes on the season's colour. --s is its size, so the hat and cape fit it. */
:is(html[data-site-theme], [data-st-preview]) .cb-blob-wrap { --s: 11rem; }
html[data-site-theme="halloween"] .cb-blob { filter: hue-rotate(148deg) saturate(1.25); }
html[data-site-theme="christmas"] .cb-blob { filter: hue-rotate(118deg) saturate(1.3); }
html[data-site-theme="newyear"] .cb-blob { filter: hue-rotate(168deg) saturate(1.1) brightness(1.08); }

/* Sleeping orbs (empty states) keep their closed eyes under any costume. */
:is(html[data-site-theme], [data-st-preview]) .nx-orb.is-asleep .nx-orb-eyes i { animation: none; transform: scaleY(.14); }

/* ------------------------------------------------------------- mascot
   The orb in costume, bottom-left on every page (the chat bubble owns bottom-right).
   It says the greeting once a visit and does a little party trick when tapped. */
.st-mascot { position: fixed; left: max(18px, env(safe-area-inset-left)); bottom: max(18px, env(safe-area-inset-bottom)); z-index: 1150; display: flex; align-items: flex-end; gap: 10px; pointer-events: none; }
.st-mascot-btn { pointer-events: auto; position: relative; display: grid; place-items: center; width: 78px; height: 78px; padding: 0; border: 0; background: none; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.st-mascot-btn .nx-orb { animation: st-bob 3.4s ease-in-out infinite; }
.st-mascot-btn:active .nx-orb { transform: scale(.92); }
.st-mascot-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 4px; border-radius: 50%; }
@keyframes st-bob { 50% { transform: translateY(-6px) rotate(-3deg); } }
/* Hover: a happy little squish, then back to bobbing. */
.st-mascot-btn:hover .nx-orb { animation: st-squish .6s ease, st-bob 3.4s ease-in-out .6s infinite; }
@keyframes st-squish { 30% { transform: scale(1.1, .88); } 60% { transform: scale(.94, 1.07) translateY(-4px); } }
.st-bubble { pointer-events: auto; position: relative; margin-bottom: 52px; padding: 10px 34px 10px 14px; border-radius: var(--radius-lg) var(--radius-lg) var(--radius-lg) var(--radius-sm); background: var(--bg, #111); color: var(--text); border: 1px solid rgb(var(--st-glow) / .45);
    box-shadow: 0 10px 28px rgb(0 0 0 / .25), 0 0 0 4px rgb(var(--st-glow) / .08); font-weight: 800; font-size: 15px; white-space: nowrap; max-width: calc(100vw - 130px); overflow: hidden; text-overflow: ellipsis;
    opacity: 0; transform: translateY(6px) scale(.96); transform-origin: bottom left; transition: opacity .25s, transform .35s cubic-bezier(.16, 1, .3, 1); }
.st-bubble.is-on { opacity: 1; transform: none; }
.st-bubble-x { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); width: 26px; height: 26px; display: grid; place-items: center; border: 0; border-radius: 50%; background: none; color: var(--muted); cursor: pointer; font-size: 16px; line-height: 1; }
@media (hover: hover) and (pointer: fine) {
.st-bubble-x:hover { background: var(--hover); color: var(--text); }
}
@keyframes st-shine { to { background-position: -200% 0; } }
html.mnav-open .st-mascot,
body:has(.modal-backdrop:not(.hidden), .nx-modal:not(.hidden), #setupWizard:not([hidden])) .st-mascot { display: none; }
@media (max-width: 640px) {
    .st-mascot-btn { width: 62px; height: 62px; }
    /* Narrow screens: the spider keeps to the edge so it never hangs over text. */
    .st-spider { right: 4px; animation-name: st-dangle-short; }
    .st-bubble { font-size: 13px; margin-bottom: 42px; }
}

/* ------------------------------------------------------------- Halloween decor */
.st-web { top: 0; width: clamp(80px, 10vw, 150px); height: clamp(80px, 10vw, 150px); color: rgb(203 213 225 / .38); }
.st-web-l { left: 0; }
.st-web-r { right: 0; transform: scaleX(-1); }
html[data-theme="default"] .st-web, html[data-theme="red"] .st-web, html[data-theme="mono"] .st-web, html:not([data-theme]) .st-web { color: rgb(71 85 105 / .35); }
.st-spider { top: 0; right: clamp(70px, 9vw, 130px); width: 34px; height: 210px; transform-origin: top center; animation: st-dangle 6s ease-in-out infinite; }
.st-spider::before { content: ""; position: absolute; left: 50%; top: 0; width: 1px; height: calc(100% - 30px); background: linear-gradient(rgb(148 163 184 / .2), rgb(148 163 184 / .7)); }
.st-spider img { position: absolute; left: 0; bottom: 0; width: 34px; height: auto; animation: st-wiggle 1.8s ease-in-out infinite; }
@keyframes st-dangle { 0%, 100% { height: 150px; transform: rotate(2deg); } 50% { height: 230px; transform: rotate(-2deg); } }
@keyframes st-wiggle { 50% { transform: rotate(8deg); } }
@keyframes st-dangle-short { 0%, 100% { height: 90px; transform: rotate(2deg); } 50% { height: 130px; transform: rotate(-2deg); } }
.st-bat { top: 0; left: 0; width: 70px; height: 35px; z-index: 56; will-change: transform; filter: drop-shadow(0 0 2px rgb(249 115 22 / .55)); }
.st-bat .w { transform-origin: 50px 22px; animation: st-flap .22s ease-in-out infinite alternate; }
@keyframes st-flap { to { transform: scaleY(.25); } }
.st-fog { left: -10%; right: -10%; bottom: 0; height: 30vh; z-index: 1; opacity: .5;
    background: radial-gradient(40% 60% at 20% 100%, rgb(var(--violet-rgb) / .22), transparent 70%), radial-gradient(45% 55% at 70% 100%, rgb(var(--st-glow) / .16), transparent 70%), radial-gradient(35% 50% at 45% 100%, rgb(148 163 184 / .16), transparent 70%);
    filter: blur(8px); animation: st-drift 18s ease-in-out infinite alternate; }
@keyframes st-drift { to { transform: translateX(6%); } }

/* ------------------------------------------------------------- Christmas decor */
.st-snow, .st-fireworks { inset: 0; width: 100%; height: 100%; }
/* The garland hangs from the bottom edge of the top bar on every page: fairy
   lights, pumpkins and bats, or gold bunting. It never takes a click. */
.st-garland { position: absolute; left: 14px; right: 14px; top: 100%; height: 30px; margin-top: -5px; pointer-events: none; z-index: 1; }
.topbar:not(.topbar-floating) .st-garland { left: 0; right: 0; margin-top: -3px; }
.st-garland svg { overflow: visible; }
.st-garland .wire { fill: none; stroke: rgb(30 41 59 / .75); stroke-width: 1.5; }
html:is([data-theme="dyno"], [data-theme="super"], [data-theme="dusk"]) .st-garland .wire { stroke: rgb(203 213 225 / .4); }
.st-garland.is-newyear .wire { stroke: #d4a017; stroke-width: 1.2; }
.st-swing { transform-box: fill-box; transform-origin: 50% 0; animation: st-swing 3.2s ease-in-out infinite alternate; }
@keyframes st-swing { from { transform: rotate(-7deg); } to { transform: rotate(7deg); } }

/* Work pages: a small costumed orb sits beside the logo instead of the mascot. */
.st-barorb { display: inline-grid; place-items: center; width: 30px; height: 30px; margin-inline: 2px 6px; flex: none; }
@media (max-width: 640px) { .st-barorb { display: none; } }
.st-bulb { animation: st-twinkle 1.6s ease-in-out infinite alternate; }
.st-bulb ellipse { filter: drop-shadow(0 0 3px currentColor); }
@keyframes st-twinkle { from { opacity: .45; } to { opacity: 1; } }
/* A drift of snow along the top of the floating bar. */
.st-cap { position: absolute; left: 10px; right: 10px; top: -7px; height: 13px; pointer-events: none; z-index: 2; filter: drop-shadow(0 1px 1px rgb(15 23 42 / .18)); }
html[data-site-theme="christmas"] .topbar:not(.topbar-floating) .st-cap { display: none; }

/* ------------------------------------------------------------- New Year decor */
.st-cheer { position: fixed; left: 50%; top: calc(var(--nav-float-clear, 64px) + 10px); z-index: 58; display: flex; align-items: center; gap: 10px; padding: 9px 12px 9px 16px; border-radius: 999px;
    background: color-mix(in srgb, var(--surface, #1e1e1e) 82%, transparent); border: 1px solid rgb(245 197 66 / .55); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
    box-shadow: 0 10px 30px rgb(0 0 0 / .25), 0 0 24px rgb(245 197 66 / .25); transform: translate(-50%, -8px); opacity: 0; transition: opacity .35s, transform .5s cubic-bezier(.16, 1, .3, 1); max-width: calc(100vw - 24px); }
.st-cheer.is-on { opacity: 1; transform: translate(-50%, 0); }
.st-cheer b { font-size: 15px; font-weight: 900; letter-spacing: .01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    background: linear-gradient(90deg, #b7791f, #fde68a, #f5c542, #fff7d1, #b7791f); background-size: 250% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; animation: st-shine 4s linear infinite; }
html:not([data-theme="dyno"]):not([data-theme="super"]):not([data-theme="dusk"]) .st-cheer b { background-image: linear-gradient(90deg, #8a5a00, #c08a1e, #e3b23c, #8a5a00); }
.st-cheer button { width: 26px; height: 26px; display: grid; place-items: center; border: 0; border-radius: 50%; background: none; color: var(--muted); cursor: pointer; font-size: 16px; }
@media (hover: hover) and (pointer: fine) {
.st-cheer button:hover { background: var(--hover); color: var(--text); }
}
.st-cheer svg { flex: none; }

/* ------------------------------------------------------------- scenery (site pages)
   site-themes.js adds these only outside the work pages. */
/* A scene drawn across the top of the footer: graveyard, snowy village, skyline. */
.st-scene { display: block; height: clamp(80px, 9vw, 120px); margin: 0 0 18px; pointer-events: none; }
.st-scene svg { display: block; }
/* Hero: behind the content (the hero's inner block sits at z-index 1). */
.st-hero { position: absolute; inset: 0; pointer-events: none; }
.st-hero-moon { position: absolute; right: 5%; top: calc(var(--nav-float-clear, 72px) + 4px); width: clamp(110px, 14vw, 200px); height: auto; opacity: .9; filter: drop-shadow(0 0 30px rgb(253 230 138 / .25)); }
.st-bauble { position: absolute; top: 0; transform-origin: 50% 0; animation: st-swing-slow 4.5s ease-in-out infinite alternate; filter: drop-shadow(0 6px 10px rgb(0 0 0 / .25)); }
@keyframes st-swing-slow { from { transform: rotate(-4deg); } to { transform: rotate(4deg); } }
.st-hero-year { position: absolute; z-index: 0; left: 50%; top: calc(var(--nav-float-clear, 72px) + 40px); width: min(1000px, 92vw); transform: translateX(-50%); opacity: .09; }
@media (max-width: 640px) {
    .st-hero-moon { width: 84px; right: 10px; opacity: .55; }
    .st-bauble:nth-of-type(2), .st-bauble:nth-of-type(3) { display: none; }
}
/* Tap targets: the moon, baubles, stars, tombstones, pumpkins, trees, the cabin,
   presents, the skyline, the spider, bats and flyers. They glow on hover. Hero
   pieces sit above the hero text on wide screens only (they live at the edges);
   on phones they stay behind it so they never block a button. */
.st-poke { pointer-events: auto; cursor: pointer; transform-box: fill-box; transform-origin: 50% 100%; transition: filter .2s; }
@media (hover: hover) and (pointer: fine) {
.st-poke:hover { filter: brightness(1.25) drop-shadow(0 0 8px rgb(var(--st-glow) / .65)); }
}
.st-hero .st-poke { z-index: 2; }
.st-bauble.st-poke { transform-origin: 50% 0; }
@media (max-width: 640px) { .st-hero .st-poke { z-index: 0; pointer-events: none; } }
.st-spider img, .st-bat, .st-flyer { pointer-events: auto; cursor: pointer; }
.st-ghost { z-index: 1160; filter: drop-shadow(0 0 12px rgb(255 255 255 / .55)); }

/* A few cards wear something: a cobweb, a snow cap, a streamer. */
.st-card-deco { position: absolute; top: 0; pointer-events: none; z-index: 2; }
.st-card-deco.is-right { right: 0; }
.st-card-deco.is-left { left: 0; }
.st-card-web { display: block; width: 64px; height: 64px; color: rgb(148 163 184 / .45); }
.is-right > .st-card-web { transform: scaleX(-1); }
.st-card-deco:has(.st-card-cap) { left: 14px; right: 14px; top: -5px; }
.st-card-cap { display: block; filter: drop-shadow(0 1px 1px rgb(15 23 42 / .15)); }
.st-card-streamer { display: block; }
.is-left > .st-card-streamer { transform: scaleX(-1); }
/* Something crossing the top of the screen now and then. */
.st-flyer { top: 0; left: 0; z-index: 56; filter: drop-shadow(0 0 3px rgb(255 255 255 / .35)); }

/* ------------------------------------------------------------- dressing */
/* site-themes.js dressUp(): caps on the logo and main buttons, a sweet at the
   button's bottom-left, a big piece on the footer divider. None takes a click. */
html[data-site-theme] .topbar .brand-link { position: relative; }
.st-cap-art, .st-side-art { position: absolute; z-index: 2; height: auto; pointer-events: none; filter: drop-shadow(0 2px 3px rgb(0 0 0 / .35)); }
.brand-link > .st-cap-art { top: -8px; left: 20px; width: 21px; transform: rotate(14deg); }
html[data-site-theme="christmas"] .brand-link > .st-cap-art { top: -11px; left: 2px; width: 26px; transform: rotate(-18deg); }
html[data-site-theme="newyear"] .brand-link > .st-cap-art { top: -14px; left: 6px; width: 17px; transform: rotate(-16deg); }
.st-dressed { overflow: visible !important; position: relative; }
.st-dressed[data-glow]::after { border-radius: inherit; }
.st-dressed > .st-cap-art { top: -13px; right: -9px; width: 25px; transform: rotate(12deg); animation: st-cap-wobble 3.2s ease-in-out infinite; }
html[data-site-theme="newyear"] .st-dressed > .st-cap-art { top: -17px; width: 19px; }
.st-dressed > .st-side-art { bottom: -11px; left: -8px; width: 14px; transform: rotate(-28deg); }
html[data-site-theme="newyear"] .st-dressed > .st-side-art { bottom: -9px; left: -9px; width: 18px; transform: none; filter: none; animation: st-twinkle 1.2s ease-in-out infinite alternate; }
@keyframes st-cap-wobble { 0%, 100% { transform: rotate(12deg); } 50% { transform: rotate(-6deg) translateY(-2px); } }
html[data-site-theme] .site-footer-inner { position: relative; }
.st-foot-art { position: absolute; left: 50%; bottom: 0; width: 160px; display: grid; justify-items: center; transform: translateX(-50%); pointer-events: none; }
.st-foot-art img { display: block; width: 100%; height: auto; filter: drop-shadow(0 8px 18px rgb(0 0 0 / .35)); transform-origin: 50% 100%; animation: st-bob 4.5s ease-in-out infinite; }
.st-foot-year { margin-top: -8px; font-size: 1.9rem; font-weight: 900; line-height: 1; letter-spacing: .04em; background: linear-gradient(180deg, #fef9c3, #facc15 55%, #b45309); -webkit-background-clip: text; background-clip: text; color: transparent; filter: drop-shadow(0 0 10px rgb(250 204 21 / .45)); }
@media (max-width: 1200px) { .st-foot-art { width: 124px; } }
@media (max-width: 760px) {
    .st-foot-art { position: static; width: 120px; margin: 18px auto 0; transform: none; }
}

/* ------------------------------------------------------------- calm modes */
@media (prefers-reduced-motion: reduce) {
    .st-layer, .st-layer *, .st-mascot *, .st-cheer, .st-cheer b, .st-bulb, .st-swing, .st-bauble, .st-cap-art, .st-side-art, .st-foot-art img { animation: none !important; transition: none !important; }
}
@media print { .st-layer, .st-mascot, .st-cheer, .st-garland, .st-cap, .st-barorb, .st-scene, .st-hero, .st-card-deco, .st-cap-art, .st-side-art, .st-foot-art { display: none !important; } }
