/* ==========================================================================
   Store theme
   --------------------------------------------------------------------------
   Brand colours are injected by layout.html from the template config, so they
   are editable in the creator panel. Everything below is derived from those
   few tokens with color-mix() — change --brand and the whole store follows.
   ========================================================================== */

/* --- Derived tokens ------------------------------------------------------ */

:root {
    /* Fallbacks so the CSS still renders if config() returns empty.
       Sampled from the Beneath the Cape logo: blood red, dried blood,
       bone white, warm near-black. */
    --brand: #C41E25;
    --brand-alt: #7A0F14;
    --accent: #E8E2D4;
    --on-accent: #120C0B;
    --bg: #0A0908;
    --surface: #15100F;
    --text: #EFE9DC;
    --muted: #9A8F88;
    --radius: 4px;
    --hero-overlay: 0.7;

    --font-body: Inter, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-display: Oswald, "Arial Narrow", Impact, var(--font-body);

    --surface-2: color-mix(in srgb, var(--surface) 82%, white 18%);
    --line: color-mix(in srgb, var(--text) 12%, transparent);
    --line-strong: color-mix(in srgb, var(--text) 22%, transparent);
    --brand-soft: color-mix(in srgb, var(--brand) 16%, transparent);
    --brand-glow: color-mix(in srgb, var(--brand) 38%, transparent);

    /* Brand red is dark enough that it fails contrast as text on the page
       background (~3:1). Links use a lightened version instead (~5.4:1).
       Solid brand fills keep the true colour — white on red is fine. */
    --brand-text: color-mix(in srgb, var(--brand) 70%, white);
    --gradient: linear-gradient(135deg, var(--brand), var(--brand-alt));

    --radius-sm: calc(var(--radius) * 0.6);
    --radius-lg: calc(var(--radius) * 1.5);

    --shell: 1240px;
    --gap: 24px;

    --shadow: 0 2px 4px rgb(0 0 0 / 0.25), 0 12px 32px rgb(0 0 0 / 0.35);
    --shadow-lift: 0 4px 8px rgb(0 0 0 / 0.3), 0 24px 56px rgb(0 0 0 / 0.5);

    --ease: cubic-bezier(0.22, 0.61, 0.36, 1);

    color-scheme: dark;
}

/* --- Reset --------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-body);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* A soft brand wash behind the whole page — cheap depth, no images. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(60rem 40rem at 12% -10%, var(--brand-soft), transparent 60%),
        radial-gradient(50rem 36rem at 105% 0%, color-mix(in srgb, var(--brand-alt) 14%, transparent), transparent 60%);
}

/* A film of grain over everything. The logo is a distressed print; a perfectly
   clean ground fights it. Generated, so it costs no request. */
body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    opacity: 0.5;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.06'/%3E%3C/svg%3E");
}

/* Everything the reader interacts with sits above the grain. */
.masthead, main, .footer, .notice, .skip-link { position: relative; z-index: 2; }

img, svg { display: block; max-width: 100%; }
img { height: auto; }

h1, h2, h3 {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: 0.015em;
    text-transform: uppercase;
}
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

a { color: inherit; text-decoration: none; }

button, input, select, textarea { font: inherit; color: inherit; }

.sr-only {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
    position: absolute; left: 50%; top: 0;
    transform: translate(-50%, -120%);
    z-index: 100;
    padding: 12px 20px;
    background: var(--brand); color: #fff;
    border-radius: 0 0 var(--radius-sm) var(--radius-sm);
    transition: transform 0.2s var(--ease);
}
.skip-link:focus { transform: translate(-50%, 0); }

:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 3px;
    border-radius: 4px;
}

/* --- Layout -------------------------------------------------------------- */

.shell {
    width: 100%;
    max-width: var(--shell);
    margin-inline: auto;
    padding-inline: 20px;
}
.shell--narrow { max-width: 760px; }

.section { padding-block: clamp(40px, 6vw, 72px); }
.section--narrow { padding-block: clamp(32px, 5vw, 56px); }

.section__head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--gap);
    margin-bottom: 28px;
    flex-wrap: wrap;
}

.section__title { font-size: clamp(22px, 3vw, 30px); }

.section__desc {
    margin-top: 6px;
    color: var(--muted);
    max-width: 60ch;
}

.section__more {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--brand-text);
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 15px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    white-space: nowrap;
}
.section__more svg { transition: transform 0.2s var(--ease); }
.section__more:hover svg { transform: translateX(3px); }

/* --- Buttons ------------------------------------------------------------- */

.btn {
    --btn-bg: transparent;
    --btn-fg: var(--text);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 11px 20px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: var(--btn-bg);
    color: var(--btn-fg);
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 15px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    cursor: pointer;
    white-space: nowrap;
    transition: transform 0.15s var(--ease), box-shadow 0.2s var(--ease),
                background-color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

.btn--primary {
    background: var(--gradient);
    color: #fff;
    box-shadow: 0 4px 16px var(--brand-glow);
}
.btn--primary:hover { box-shadow: 0 8px 28px var(--brand-glow); }

.btn--ghost {
    border-color: var(--line-strong);
    background: color-mix(in srgb, var(--surface) 70%, transparent);
    backdrop-filter: blur(8px);
}
.btn--ghost:hover { border-color: var(--brand); background: var(--brand-soft); }

.btn--disabled {
    background: color-mix(in srgb, var(--surface) 80%, transparent);
    color: var(--muted);
    cursor: not-allowed;
    border-color: var(--line);
}
.btn--disabled:hover { transform: none; }

.btn--lg { padding: 14px 26px; font-size: 16px; }
.btn--block { width: 100%; }
.btn--icon svg { flex: none; }

/* Purchase controls. A "both" package shows Subscribe and Add side by side,
   so the pair splits the row; every other case is a single full-width button. */
.actions { display: grid; gap: 8px; }
.actions--pair { grid-template-columns: 1fr 1fr; }

/* Dimmed but still clickable — on a store that asks for an in-game name,
   clicking through is how the customer reaches that prompt. */
.btn[disabled] { opacity: 0.72; }
.btn[disabled]:hover { opacity: 1; transform: translateY(-1px); }

.actions__reason {
    grid-column: 1 / -1;
    margin-top: 2px;
    color: var(--muted);
    font-size: 13px;
    line-height: 1.45;
}

@media (max-width: 380px) {
    .actions--pair { grid-template-columns: 1fr; }
}

/* --- Masthead ------------------------------------------------------------ */

.masthead {
    position: sticky;
    top: 0;
    z-index: 50;
    background: color-mix(in srgb, var(--bg) 78%, transparent);
    backdrop-filter: blur(16px) saturate(1.4);
    border-bottom: 1px solid transparent;
    transition: border-color 0.25s var(--ease), background-color 0.25s var(--ease);
}
.masthead.is-stuck {
    border-bottom-color: var(--line);
    background: color-mix(in srgb, var(--bg) 92%, transparent);
}

.masthead__inner {
    display: flex;
    align-items: center;
    gap: var(--gap);
    min-height: 72px;
}

.brand { flex: none; display: flex; align-items: center; }
.brand__logo { max-height: 40px; width: auto; }
.brand__name { font-weight: 800; font-size: 19px; letter-spacing: -0.02em; }

.nav { margin-inline-start: auto; }

.nav__list { display: flex; align-items: center; gap: 4px; }

.nav__link {
    display: block;
    padding: 9px 14px;
    border-radius: var(--radius-sm);
    font-family: var(--font-display);
    font-weight: 500;
    font-size: 15px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    /* Never break a category name across two lines — it grows the header and
       reads as a layout fault rather than a wrap. */
    white-space: nowrap;
    color: color-mix(in srgb, var(--text) 82%, transparent);
    transition: color 0.18s var(--ease), background-color 0.18s var(--ease);
}

/* Long category names plus a wide basket total can outgrow the row before the
   mobile breakpoint. Tighten the nav rather than let it wrap. */
@media (max-width: 1240px) {
    .nav__link { padding: 9px 10px; font-size: 14px; letter-spacing: 0.03em; }
    .masthead__inner { gap: 14px; }
}

@media (max-width: 1080px) {
    .nav__link { padding: 8px 8px; font-size: 13px; }
    /* Drop the Discord label to its icon, but keep the signed-in name. */
    .masthead__actions .btn--icon:not(.whoami) span { display: none; }
}
.nav__link:hover { color: var(--text); background: color-mix(in srgb, var(--text) 7%, transparent); }
.nav__link--muted { color: var(--muted); }

.nav__link.is-active {
    color: var(--text);
    background: var(--brand-soft);
    box-shadow: inset 0 -2px 0 var(--brand);
}

/* The signed-in name swaps to "Log out" on hover, so one control does both
   without spending a second slot in the header. */
.whoami__out { display: none; }
.whoami:hover .whoami__name { display: none; }
.whoami:hover .whoami__out { display: inline; }

.masthead__actions { display: flex; align-items: center; gap: 10px; flex: none; }

.basket-pill {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 10px 16px;
    border-radius: 999px;
    background: var(--gradient);
    color: #fff;
    font-weight: 600;
    font-size: 15px;
    box-shadow: 0 4px 16px var(--brand-glow);
    transition: box-shadow 0.2s var(--ease), transform 0.15s var(--ease);
}
.basket-pill:hover { transform: translateY(-1px); box-shadow: 0 8px 26px var(--brand-glow); }

.basket-pill__count {
    position: absolute;
    top: -5px; right: -5px;
    min-width: 20px; height: 20px;
    display: grid; place-items: center;
    padding-inline: 5px;
    border-radius: 999px;
    background: var(--accent);
    color: var(--on-accent);
    font-size: 11px; font-weight: 800;
    border: 2px solid var(--bg);
}

.masthead__burger {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 42px; height: 42px;
    margin-inline-start: auto;
    padding: 0 10px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: transparent;
    cursor: pointer;
}
.masthead__burger span {
    display: block; height: 2px; width: 100%;
    background: var(--text); border-radius: 2px;
    transition: transform 0.22s var(--ease), opacity 0.18s var(--ease);
}
.masthead__burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.masthead__burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.masthead__burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* --- Hero ---------------------------------------------------------------- */

.hero {
    position: relative;
    isolation: isolate;
    padding-block: clamp(64px, 11vw, 132px);
    overflow: hidden;
    text-align: center;
}

.hero::before {
    content: "";
    position: absolute; inset: 0; z-index: -2;
    background-image: var(--hero-image, none);
    background-size: cover;
    background-position: center;
    transform: scale(1.06);
}

.hero::after {
    content: "";
    position: absolute; inset: 0; z-index: -1;
    background:
        /* Torn streaks — the cape, abstracted. Reads as slashes of light
           through fabric rather than a flat vignette. */
        linear-gradient(103deg, transparent 38%, color-mix(in srgb, var(--brand-alt) 50%, transparent) 39.2%, transparent 40%),
        linear-gradient(97deg, transparent 56%, color-mix(in srgb, var(--brand) 32%, transparent) 57%, transparent 58.4%),
        linear-gradient(110deg, transparent 66%, color-mix(in srgb, var(--brand-alt) 40%, transparent) 67%, transparent 67.8%),
        linear-gradient(to bottom,
            color-mix(in srgb, var(--bg) calc(var(--hero-overlay) * 100%), transparent),
            var(--bg));
}

/* Without a hero image the section needs its own light source. */
.hero:not([style]) {
    background:
        radial-gradient(70% 90% at 50% 0%, color-mix(in srgb, var(--brand) 30%, transparent), transparent 70%),
        linear-gradient(180deg, color-mix(in srgb, var(--brand) 9%, var(--bg)), var(--bg));
}

.hero__title {
    font-size: clamp(38px, 7.5vw, 76px);
    font-weight: 700;
    letter-spacing: 0.01em;
    background: linear-gradient(180deg, var(--text), color-mix(in srgb, var(--text) 62%, var(--brand)));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.hero__subtitle {
    margin: 18px auto 0;
    max-width: 62ch;
    color: var(--muted);
    font-size: clamp(15px, 1.7vw, 18px);
}

.hero__actions {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 32px;
}

.hero__trust {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 10px 32px;
    margin-top: 40px;
    color: var(--muted);
    font-size: 14px;
}
.hero__trust strong { color: var(--text); }

/* --- Package grid -------------------------------------------------------- */

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--gap);
}

/* A category set to "list" in the panel. Same markup as the grid, laid out as
   compact rows so a whole catalogue fits on one screen instead of one
   package filling the viewport. */
.stack { display: grid; gap: 12px; }

.stack .card {
    flex-direction: row;
    align-items: center;
    gap: 18px;
    padding: 12px 18px 12px 12px;
    container-type: normal;
}

.stack .card__media {
    flex: none;
    width: 108px;
    aspect-ratio: 1;
    padding: 6px;
    border-radius: var(--radius-sm);
}

.stack .card__body { padding: 0; }
.stack .card__title { font-size: 18px; }

.stack .card__foot {
    grid-template-columns: auto auto;
    align-items: center;
    gap: 20px;
    padding: 0;
    margin-left: auto;
}
.stack .card__foot .actions { min-width: 170px; }

@media (max-width: 620px) {
    .stack .card { flex-wrap: wrap; }
    .stack .card__media { width: 72px; }
    .stack .card__foot {
        grid-template-columns: 1fr;
        gap: 10px;
        margin-left: 0;
        width: 100%;
    }
}

/* --- Category tiles (home page) ------------------------------------------ */

/* Full-width tracks. The art no longer scales with the tile — it's contained
   and padded inside it — so large tiles read as generous rather than shouty. */
.cats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--gap);
}

.cat {
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow);
    transition: transform 0.25s var(--ease), border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.cat:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--brand) 55%, transparent);
    box-shadow: var(--shadow-lift);
}

.cat__media {
    position: relative;
    display: block;
    aspect-ratio: 16 / 9;
    padding: 16px 18px;
    overflow: hidden;
    background:
        radial-gradient(90% 120% at 30% 0%, color-mix(in srgb, var(--brand) 34%, transparent), transparent 68%),
        linear-gradient(135deg, color-mix(in srgb, var(--brand-alt) 30%, #150f0e), #100c0b);
}

/* Same torn streaks as the hero, so an image-less tile still has the brand's
   texture rather than reading as an empty box. */
.cat__media::before {
    content: "";
    position: absolute; inset: 0;
    background:
        linear-gradient(104deg, transparent 40%, color-mix(in srgb, var(--brand) 34%, transparent) 41.4%, transparent 42.4%),
        linear-gradient(96deg, transparent 62%, color-mix(in srgb, var(--brand-alt) 46%, transparent) 63%, transparent 64.6%);
}

/* The store logo, ghosted. Set from the template; absent if no logo. */
.cat__media::after {
    content: "";
    position: absolute; inset: 14%;
    background-image: var(--watermark, none);
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
    opacity: 0.16;
    transition: opacity 0.3s var(--ease), transform 0.4s var(--ease);
}
.cat:hover .cat__media::after { opacity: 0.26; transform: scale(1.04); }

/* "contain", not "cover": the banners are complete artworks with their own
   lettering. Cover scales them up until they fill the tile and slices the top
   and bottom off, so shrinking the tile only tightened the crop. */
.cat__media img {
    position: relative;
    z-index: 1;
    width: 100%; height: 100%;
    object-fit: contain;
    transition: transform 0.4s var(--ease);
}
.cat:hover .cat__media img { transform: scale(1.04); }

.cat__body {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 18px;
}

.cat__name {
    font-family: var(--font-display);
    font-size: 19px;
    font-weight: 700;
    letter-spacing: 0.015em;
    text-transform: uppercase;
    line-height: 1.15;
}

.cat__go {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--brand-text);
    font-family: var(--font-display);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    white-space: nowrap;
}
.cat__go svg { transition: transform 0.2s var(--ease); }
.cat:hover .cat__go svg { transform: translateX(3px); }

.card {
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow);
    container-type: inline-size;
    transition: transform 0.25s var(--ease), border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.card:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--brand) 55%, transparent);
    box-shadow: var(--shadow-lift);
}

.card--featured { border-color: color-mix(in srgb, var(--brand) 42%, transparent); }

.card__media {
    position: relative;
    display: block;
    aspect-ratio: 4 / 3;
    padding: 10px;
    background:
        radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--brand) 20%, transparent), transparent 70%),
        #0d0b0a;
    overflow: hidden;
}

/* Package art is emblem-shaped, not photographic — "cover" crops the tops and
   bottoms off. "contain" shows the whole badge and letterboxes against the
   tile, which reads as deliberate on a dark ground. */
.card__media img {
    width: 100%; height: 100%;
    object-fit: contain;
    transition: transform 0.4s var(--ease);
}
.card:hover .card__media img { transform: scale(1.04); }

.card__media-fallback {
    position: absolute; inset: 0;
    display: grid; place-items: center;
    font-size: 48px; font-weight: 800;
    color: color-mix(in srgb, var(--text) 30%, transparent);
}

.card__body { padding: 18px 18px 8px; flex: 1; }

.card__title { font-size: 17px; }
.card__title a { transition: color 0.18s var(--ease); }
.card__title a:hover { color: var(--brand-text); }

.card__desc {
    margin-top: 8px;
    color: var(--muted);
    font-size: 14px;
    line-height: 1.55;
}

/* Price above, button below at full width. Side-by-side looked tidier with
   short labels, but "Currently unavailable" and "Subscribe" overflowed the
   card and pushed "/mo" onto its own line. */
.card__foot {
    display: grid;
    gap: 12px;
    padding: 14px 18px 18px;
}

/* --- Price & badges ------------------------------------------------------ */

.price {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
    font-family: var(--font-display);
    font-variant-numeric: tabular-nums;
}

.price__now { font-weight: 600; font-size: 20px; letter-spacing: 0.01em; }

/* Pay-what-you-want has no figure to show, so it reads as a label, not a price. */
.price__now--soft {
    color: var(--muted);
    font-family: var(--font-body);
    font-size: 14px;
    font-weight: 500;
    text-transform: none;
}

.price__was {
    color: var(--muted);
    font-size: 14px;
    text-decoration: line-through;
}

/* Recurring marker — pulled tight to the figure so the two read as one unit. */
.price__per {
    margin-left: -4px;
    color: var(--muted);
    font-family: var(--font-body);
    font-size: 14px;
    font-weight: 500;
}

.price--lg .price__now { font-size: 40px; }
.price--lg .price__was { font-size: 19px; }
.price--lg .price__per { font-size: 17px; margin-left: -2px; }

.product__recurring {
    margin-top: 8px;
    color: var(--muted);
    font-size: 14px;
}

.badge {
    position: absolute;
    top: 12px; left: 12px;
    padding: 5px 10px;
    border-radius: 999px;
    background: var(--accent);
    color: var(--on-accent);
    font-family: var(--font-display);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.badge--lg { font-size: 14px; padding: 7px 14px; }

/* --- Page head & breadcrumbs --------------------------------------------- */

.pagehead {
    padding-block: clamp(32px, 5vw, 56px) 0;
    border-bottom: 1px solid var(--line);
    padding-bottom: clamp(28px, 4vw, 44px);
}

.pagehead__title { font-size: clamp(28px, 4.5vw, 42px); margin-top: 10px; }

.pagehead__desc { margin-top: 12px; color: var(--muted); max-width: 70ch; }

.crumbs {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--muted);
    font-size: 14px;
}
.crumbs a:hover { color: var(--brand-text); }

/* --- Product page -------------------------------------------------------- */

.product { padding-block: clamp(32px, 5vw, 56px); }

.product__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(28px, 5vw, 56px);
    align-items: start;
}

.product__media {
    position: relative;
    aspect-ratio: 4 / 3;
    padding: 18px;
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: 1px solid var(--line);
    background:
        radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--brand) 22%, transparent), transparent 70%),
        #0d0b0a;
    box-shadow: var(--shadow);
}
.product__media img { width: 100%; height: 100%; object-fit: contain; }

.product__media-fallback {
    position: absolute; inset: 0;
    display: grid; place-items: center;
    font-size: 86px; font-weight: 800;
    color: color-mix(in srgb, var(--text) 26%, transparent);
}

.product__gallery { display: grid; gap: 12px; }

.thumbs {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
    gap: 10px;
}

.thumb {
    display: block;
    width: 100%;
    aspect-ratio: 1;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    overflow: hidden;
    cursor: pointer;
    opacity: 0.6;
    transition: opacity 0.18s var(--ease), border-color 0.18s var(--ease);
}
.thumb img { width: 100%; height: 100%; object-fit: cover; }
.thumb:hover { opacity: 1; }
.thumb.is-active { opacity: 1; border-color: var(--brand); }

.badge--ending { background: var(--brand); color: #fff; }

.product__title { font-size: clamp(26px, 3.6vw, 38px); margin-block: 12px 16px; }

.product__inbasket {
    margin-top: 12px;
    color: var(--accent);
    font-size: 14px;
    font-weight: 600;
}

.product__buy { display: grid; gap: 10px; margin-top: 28px; }

.product__assurances {
    display: grid;
    gap: 12px;
    margin-top: 28px;
    padding-top: 24px;
    border-top: 1px solid var(--line);
    color: var(--muted);
    font-size: 14px;
}
.product__assurances li { display: flex; align-items: center; gap: 10px; }
.product__assurances svg { flex: none; color: var(--brand-text); }

.payform { display: grid; gap: 10px; }
.payform__label { font-size: 14px; color: var(--muted); font-weight: 500; }
.payform__row { display: flex; gap: 10px; }
.payform__input {
    flex: 1; min-width: 0;
    padding: 14px 16px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-size: 17px; font-weight: 600;
}
.payform__input:focus { border-color: var(--brand); outline: none; box-shadow: 0 0 0 3px var(--brand-soft); }

/* --- Prose (descriptions, CMS pages) ------------------------------------- */

.prose { max-width: 75ch; color: color-mix(in srgb, var(--text) 88%, transparent); }
.prose > * + * { margin-top: 1em; }
/* Long-form copy reads better without shouted headings. */
.prose h2, .prose h3 { text-transform: none; letter-spacing: 0.005em; }
.prose h2 { font-size: 24px; margin-top: 1.6em; }
.prose h3 { font-size: 19px; margin-top: 1.4em; }
.prose a { color: var(--brand-text); text-decoration: underline; text-underline-offset: 3px; }
.prose ul, .prose ol { padding-left: 1.3em; list-style: revert; }
.prose li + li { margin-top: 0.4em; }
.prose img { border-radius: var(--radius-sm); }
.prose code {
    padding: 2px 6px;
    border-radius: 5px;
    background: var(--surface-2);
    font-size: 0.9em;
}
.prose hr { border: 0; border-top: 1px solid var(--line); margin-block: 2em; }
.prose table { width: 100%; border-collapse: collapse; }
.prose th, .prose td { padding: 10px 12px; border-bottom: 1px solid var(--line); text-align: left; }

/* --- Basket / checkout --------------------------------------------------- */

.checkout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: var(--gap);
    align-items: start;
}

.checkout__items { display: grid; gap: 12px; }

/* Flex, not grid: the image tile is omitted when a basket package has no
   media, and fixed grid tracks would leave a hole or shift every column. */
.lineitem {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 14px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}
.lineitem__media { flex: none; }
.lineitem__body { flex: 1; min-width: 0; }
.qty, .lineitem__price, .lineitem__remove { flex: none; }
.lineitem__price { min-width: 84px; text-align: right; }

.lineitem__trial {
    display: inline-block;
    margin-top: 4px;
    color: var(--accent);
    font-size: 13px;
    font-weight: 600;
}

.lineitem__options {
    margin-top: 4px;
    color: var(--muted);
    font-size: 13px;
    line-height: 1.5;
}
.lineitem__options strong { color: var(--text); font-weight: 600; }

.qty__input {
    width: 68px;
    padding: 9px 10px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--bg);
    font-family: var(--font-display);
    font-size: 16px;
    font-variant-numeric: tabular-nums;
    text-align: center;
}
.qty__input:focus { border-color: var(--brand); outline: none; box-shadow: 0 0 0 3px var(--brand-soft); }
.qty__input:disabled { opacity: 0.45; cursor: not-allowed; }

.lineitem__media {
    width: 72px; height: 72px;
    border-radius: var(--radius-sm);
    overflow: hidden;
    display: grid; place-items: center;
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--brand) 24%, var(--surface)),
        color-mix(in srgb, var(--brand-alt) 18%, var(--surface)));
    font-weight: 800; font-size: 26px;
    color: color-mix(in srgb, var(--text) 40%, transparent);
}
.lineitem__media img { width: 100%; height: 100%; object-fit: cover; }

.lineitem__title { font-size: 16px; }
.lineitem__title a:hover { color: var(--brand-text); }
.lineitem__qty { color: var(--muted); font-size: 14px; }
.lineitem__price { font-weight: 700; font-size: 17px; }

.lineitem__remove {
    display: grid; place-items: center;
    width: 36px; height: 36px;
    border-radius: var(--radius-sm);
    color: var(--muted);
    transition: color 0.18s var(--ease), background-color 0.18s var(--ease);
}
.lineitem__remove:hover { color: #ff6b6b; background: color-mix(in srgb, #ff6b6b 14%, transparent); }

.summary {
    position: sticky;
    top: 92px;
    padding: 22px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.summary__title { font-size: 18px; margin-bottom: 16px; }

.summary__coupons {
    display: grid; gap: 6px;
    margin-bottom: 14px;
    color: var(--accent);
    font-size: 14px;
}
.summary__coupons code { font-family: ui-monospace, "SF Mono", Menlo, monospace; }

.summary__total {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding-block: 16px;
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    margin-bottom: 18px;
}
.summary__total strong { font-size: 26px; letter-spacing: -0.02em; }

.summary__ign { margin-bottom: 14px; color: var(--muted); font-size: 14px; }

.summary__gateways { margin-bottom: 16px; }
.summary__gateways-label {
    display: block;
    margin-bottom: 6px;
    color: var(--muted);
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.summary__gateways ul { display: flex; flex-wrap: wrap; gap: 6px; }
.summary__gateways li {
    padding: 4px 10px;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    font-size: 13px;
    color: var(--muted);
}

.summary .btn + .btn { margin-top: 10px; }

.summary__fineprint {
    margin-top: 16px;
    color: var(--muted);
    font-size: 13px;
    line-height: 1.5;
}

/* --- Panels, forms, empty states ----------------------------------------- */

.panel {
    padding: clamp(24px, 4vw, 40px);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
}

.panel__title { font-size: clamp(22px, 3vw, 28px); }
.panel__text { margin-top: 10px; color: var(--muted); }
.panel__hint { margin-top: 16px; color: var(--muted); font-size: 13px; }

.panel--centred { text-align: center; }
.panel--centred .panel__text { margin-inline: auto; max-width: 46ch; }
.panel__cta { margin-top: 26px; }

.form { display: grid; gap: 16px; margin-top: 24px; }
.form__field { display: grid; gap: 7px; }
.form__label { font-size: 14px; font-weight: 600; }

.form__input {
    width: 100%;
    padding: 13px 16px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--bg);
    font-size: 16px;
    transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
.form__input:focus { border-color: var(--brand); outline: none; box-shadow: 0 0 0 3px var(--brand-soft); }

.form__help { color: var(--muted); font-size: 13px; }

.form__suffix {
    align-self: center;
    color: var(--muted);
    font-family: var(--font-display);
    font-size: 15px;
    letter-spacing: 0.04em;
}

/* The options page reuses .actions for its buttons; give it room to breathe
   below the last field. */
.store-product-options .actions { margin-top: 24px; }

.empty {
    padding: clamp(40px, 7vw, 72px) 24px;
    text-align: center;
    background: var(--surface);
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius-lg);
}
.empty__title { font-size: 22px; }
.empty__text { margin-block: 10px 22px; color: var(--muted); }

/* --- Flash messages ------------------------------------------------------- */

/* Tebex returns add-to-basket failures as a message rather than an error page,
   so they need somewhere visible to land. */
.flash {
    position: fixed;
    left: 50%;
    bottom: 24px;
    transform: translateX(-50%);
    z-index: 80;
    max-width: min(440px, calc(100vw - 32px));
    padding: 13px 20px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--text);
    font-size: 15px;
    box-shadow: var(--shadow-lift);
}
.flash--error { border-color: color-mix(in srgb, #ff6b6b 55%, transparent); color: #ffb0b0; }

.btn.is-busy { opacity: 0.6; pointer-events: none; }

/* --- Basket drawer -------------------------------------------------------- */

.drawer { position: fixed; inset: 0; z-index: 60; }

.drawer__scrim {
    position: absolute; inset: 0;
    background: rgb(0 0 0 / 0.6);
    backdrop-filter: blur(2px);
    animation: drawer-fade 0.2s var(--ease);
}

.drawer__panel {
    position: absolute;
    top: 0; right: 0; bottom: 0;
    width: min(420px, 100%);
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border-left: 1px solid var(--line);
    box-shadow: -24px 0 60px rgb(0 0 0 / 0.55);
    animation: drawer-in 0.26s var(--ease);
}

@keyframes drawer-fade { from { opacity: 0; } }
@keyframes drawer-in { from { transform: translateX(100%); } }

.drawer__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 18px 18px 16px;
    border-bottom: 1px solid var(--line);
}
.drawer__title { font-size: 19px; }

.drawer__close {
    display: grid; place-items: center;
    width: 36px; height: 36px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    transition: color 0.18s var(--ease), border-color 0.18s var(--ease);
}
.drawer__close:hover { color: var(--text); border-color: var(--brand); }

.drawer__form { display: flex; flex-direction: column; min-height: 0; flex: 1; }

.drawer__items { flex: 1; overflow-y: auto; padding: 14px 18px; display: grid; gap: 12px; align-content: start; }

.dline {
    display: flex;
    gap: 12px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--line);
}
.dline__media { flex: none; }
.dline__body { flex: 1; min-width: 0; }
.dline__remove { flex: none; }
.dline:last-child { border-bottom: 0; padding-bottom: 0; }

.dline__media {
    width: 64px; height: 64px;
    padding: 5px;
    border-radius: var(--radius-sm);
    background: #0d0b0a;
    overflow: hidden;
}
.dline__media img { width: 100%; height: 100%; object-fit: contain; }

.dline__title {
    font-family: var(--font-display);
    font-size: 15px; font-weight: 600;
    letter-spacing: 0.02em; text-transform: uppercase;
    line-height: 1.2;
}
.dline__title:hover { color: var(--brand-text); }

.dline__trial { display: block; margin-top: 3px; color: var(--accent); font-size: 12px; font-weight: 600; }
.dline__options { margin-top: 3px; color: var(--muted); font-size: 12px; line-height: 1.45; }
.dline__options strong { color: var(--text); }

.dline__row { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.dline__row .qty__input { width: 60px; padding: 6px 8px; font-size: 14px; }
.dline__price { font-family: var(--font-display); font-weight: 600; font-size: 16px; font-variant-numeric: tabular-nums; }

.dline__remove {
    display: grid; place-items: center;
    width: 30px; height: 30px;
    border-radius: var(--radius-sm);
    color: var(--muted);
    align-self: start;
    transition: color 0.18s var(--ease), background-color 0.18s var(--ease);
}
.dline__remove:hover { color: #ff6b6b; background: color-mix(in srgb, #ff6b6b 14%, transparent); }

.drawer__foot {
    flex: none;
    padding: 16px 18px;
    border-top: 1px solid var(--line);
    background: color-mix(in srgb, var(--bg) 55%, var(--surface));
}

.drawer__total {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 14px;
}
.drawer__total strong { font-family: var(--font-display); font-size: 26px; font-variant-numeric: tabular-nums; }

.drawer__fineprint { margin-top: 12px; color: var(--muted); font-size: 12px; line-height: 1.45; }

.drawer__empty { padding: 40px 24px; text-align: center; color: var(--muted); display: grid; gap: 18px; justify-items: center; }

@media (prefers-reduced-motion: reduce) {
    .drawer__panel, .drawer__scrim { animation: none; }
}

/* --- Notices & toasts ---------------------------------------------------- */

.notice--store {
    padding-block: 12px;
    background: var(--brand-soft);
    border-bottom: 1px solid color-mix(in srgb, var(--brand) 30%, transparent);
    font-size: 14px;
    text-align: center;
}

.toast {
    margin-top: 18px;
    padding: 14px 18px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--line-strong);
    background: var(--surface);
    font-size: 15px;
    font-weight: 500;
}
.toast--success { border-color: color-mix(in srgb, var(--accent) 50%, transparent); color: var(--accent); }
.toast--error   { border-color: color-mix(in srgb, #ff6b6b 50%, transparent); color: #ff8f8f; }
.toast--warning { border-color: color-mix(in srgb, #ffb454 50%, transparent); color: #ffc477; }

/* --- CTA ----------------------------------------------------------------- */

.cta { padding-block: clamp(48px, 7vw, 80px); }

.cta__inner {
    padding: clamp(32px, 5vw, 56px);
    border-radius: var(--radius-lg);
    text-align: center;
    background:
        linear-gradient(135deg, var(--brand-soft), color-mix(in srgb, var(--brand-alt) 12%, transparent)),
        var(--surface);
    border: 1px solid color-mix(in srgb, var(--brand) 30%, transparent);
}
.cta__title { font-size: clamp(24px, 3.4vw, 34px); }
.cta__text { margin-block: 12px 26px; color: var(--muted); }

/* --- Footer -------------------------------------------------------------- */

.footer {
    margin-top: clamp(48px, 8vw, 96px);
    border-top: 1px solid var(--line);
    background: color-mix(in srgb, var(--surface) 55%, transparent);
}

.footer__inner {
    display: grid;
    grid-template-columns: 1.6fr repeat(3, minmax(0, 1fr));
    gap: var(--gap);
    padding-block: clamp(36px, 5vw, 56px);
}

.footer__logo { max-height: 36px; width: auto; margin-bottom: 14px; }

.footer__note { color: var(--muted); font-size: 14px; max-width: 42ch; }

.footer__heading {
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--muted);
    margin-bottom: 14px;
}

.footer__links ul { display: grid; gap: 9px; }
.footer__links a { color: color-mix(in srgb, var(--text) 82%, transparent); font-size: 15px; }
.footer__links a:hover { color: var(--brand-text); }

.footer__legal {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
    padding-block: 20px;
    border-top: 1px solid var(--line);
    color: var(--muted);
    font-size: 13px;
}

/* --- Responsive ---------------------------------------------------------- */

@media (max-width: 1000px) {
    .checkout { grid-template-columns: 1fr; }
    .summary { position: static; }
    .footer__inner { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 860px) {
    .product__grid { grid-template-columns: 1fr; }
    .product__media { aspect-ratio: 16 / 9; }
}

@media (max-width: 780px) {
    .masthead__burger { display: flex; }

    .nav {
        position: fixed;
        inset: 72px 0 auto;
        margin: 0;
        padding: 12px 20px 20px;
        background: color-mix(in srgb, var(--bg) 97%, transparent);
        backdrop-filter: blur(16px);
        border-bottom: 1px solid var(--line);
        transform: translateY(-12px);
        opacity: 0;
        visibility: hidden;
        transition: opacity 0.2s var(--ease), transform 0.2s var(--ease), visibility 0.2s;
    }
    .nav.is-open { opacity: 1; visibility: visible; transform: translateY(0); }

    .nav__list { flex-direction: column; align-items: stretch; gap: 2px; }
    .nav__link { padding: 13px 14px; font-size: 16px; }

    .masthead__actions { order: 3; }
    .masthead__burger { order: 2; margin-inline-start: 0; }
    .masthead__inner { gap: 12px; }
    .brand { margin-inline-end: auto; }
}

@media (max-width: 560px) {
    :root { --gap: 16px; }

    .grid { grid-template-columns: 1fr; }

    .lineitem { flex-wrap: wrap; gap: 12px; }
    .lineitem__media { width: 56px; height: 56px; }
    .lineitem__body { flex: 1 1 60%; }
    .lineitem__price { margin-left: auto; }

    .footer__inner { grid-template-columns: 1fr; }
    .hero__actions .btn { width: 100%; }
    .payform__row { flex-direction: column; }
}

/* --- Motion & print ------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
    .card:hover, .btn:hover, .basket-pill:hover { transform: none; }
}

@media print {
    .masthead, .footer, .hero, .cta, .skip-link { display: none; }
    body { background: #fff; color: #000; }
}

/* ==========================================================================
   Seasonal: Halloween
   --------------------------------------------------------------------------
   Switched on from the panel (Seasonal -> Halloween). Everything here is
   scoped to .season-halloween on <body>, which beats the :root tokens the
   template writes from config without altering them — turning it Off restores
   the real brand colours with no edit.
   ========================================================================== */

body.season-halloween {
    --brand: #FF6A13;
    --brand-alt: #6A2E9D;
    --accent: #B6FF3C;
    --on-accent: #12170A;
    --bg: #090709;
    --surface: #151019;
    --text: #F2E9DC;
    --muted: #9C8FA0;

    --brand-text: color-mix(in srgb, var(--brand) 86%, white);
}

/* A cold purple cast under the usual brand wash. */
body.season-halloween::before {
    background:
        radial-gradient(60rem 40rem at 12% -10%, color-mix(in srgb, var(--brand) 16%, transparent), transparent 60%),
        radial-gradient(50rem 36rem at 105% 0%, color-mix(in srgb, var(--brand-alt) 26%, transparent), transparent 62%),
        radial-gradient(70rem 44rem at 50% 108%, color-mix(in srgb, var(--brand-alt) 20%, transparent), transparent 64%);
}

/* --- Decorations ---------------------------------------------------------- */

.spooky {
    position: fixed;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    overflow: hidden;
}

.spooky__web {
    position: absolute;
    top: 0;
    width: clamp(90px, 11vw, 160px);
    height: auto;
    color: color-mix(in srgb, var(--text) 26%, transparent);
    opacity: 0.55;
}
.spooky__web--left { left: 0; }
.spooky__web--right { right: 0; }

.spooky__defs { position: absolute; width: 0; height: 0; overflow: hidden; }

.spooky__bat {
    position: absolute;
    left: 0;
    top: var(--lane, 15%);
    width: var(--size, 32px);
    height: auto;
    color: #090407;
    opacity: var(--fade, 0.7);
    animation: bat-cross var(--dur, 34s) linear var(--delay, 0s) infinite;
    will-change: transform;
}

/* --- Flap ------------------------------------------------------------------
   Two poses stacked, swapped on a hard step. A crossfade would read as a
   dissolve; bats snap. Each bat carries its own --flap so the flock is never
   in sync, which is what makes a cut-out look like a cut-out. */

.bat__pose { transform-origin: 50% 50%; }

.bat__pose--down { animation: bat-pose-a var(--flap, 0.26s) steps(1, end) infinite; }
.bat__pose--up   { animation: bat-pose-b var(--flap, 0.26s) steps(1, end) infinite; }

@keyframes bat-pose-a { 0%, 49.9% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes bat-pose-b { 0%, 49.9% { opacity: 0; } 50%, 100% { opacity: 1; } }

/* --- Flight path -----------------------------------------------------------
   Bats don't track straight. This weaves vertically, banks into each turn
   (rotation follows the climb or dive), and eases between waypoints so there
   are fast swoops and slower drifts rather than one constant speed. */

@keyframes bat-cross {
    0%   { transform: translate(-16vw, 0) rotate(-7deg); animation-timing-function: cubic-bezier(.4,0,.5,1); }
    14%  { transform: translate(8vw, -7vh) rotate(11deg); animation-timing-function: cubic-bezier(.3,0,.7,1); }
    27%  { transform: translate(24vw, 3vh) rotate(-9deg); animation-timing-function: cubic-bezier(.5,0,.4,1); }
    43%  { transform: translate(44vw, -9vh) rotate(13deg); animation-timing-function: cubic-bezier(.3,0,.6,1); }
    58%  { transform: translate(62vw, 1vh) rotate(-6deg); animation-timing-function: cubic-bezier(.45,0,.5,1); }
    72%  { transform: translate(79vw, -6vh) rotate(9deg); animation-timing-function: cubic-bezier(.35,0,.6,1); }
    87%  { transform: translate(98vw, 4vh) rotate(-8deg); animation-timing-function: cubic-bezier(.4,0,.5,1); }
    100% { transform: translate(124vw, -2vh) rotate(5deg); }
}

/* Fog pooling at the base of the hero. */
body.season-halloween .hero { overflow: hidden; }
body.season-halloween .hero__inner { position: relative; z-index: 1; }
body.season-halloween .hero::after {
    background:
        radial-gradient(60% 40% at 20% 100%, color-mix(in srgb, var(--brand-alt) 34%, transparent), transparent 70%),
        radial-gradient(55% 36% at 78% 100%, color-mix(in srgb, var(--brand) 20%, transparent), transparent 70%),
        linear-gradient(103deg, transparent 38%, color-mix(in srgb, var(--brand-alt) 46%, transparent) 39.2%, transparent 40%),
        linear-gradient(97deg, transparent 56%, color-mix(in srgb, var(--brand) 30%, transparent) 57%, transparent 58.4%),
        linear-gradient(to bottom,
            color-mix(in srgb, var(--bg) calc(var(--hero-overlay) * 100%), transparent),
            var(--bg));
}

/* A carved-pumpkin glow behind the headline. */
body.season-halloween .hero__title {
    background: linear-gradient(180deg, #FFD9A8, color-mix(in srgb, var(--brand) 92%, white));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    text-shadow: 0 0 44px color-mix(in srgb, var(--brand) 34%, transparent);
}

/* Cards get a faint purple rim so the season reads below the fold too. */
body.season-halloween .card:hover,
body.season-halloween .cat:hover {
    border-color: color-mix(in srgb, var(--brand) 60%, transparent);
    box-shadow: var(--shadow-lift), 0 0 32px color-mix(in srgb, var(--brand-alt) 26%, transparent);
}

@media (max-width: 700px) {
    /* Webs crowd a phone header; bats alone carry it. */
    .spooky__web { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .spooky__bat { animation: none; display: none; }
}
/* --- Halloween: neon, pumpkins, candy -------------------------------------
   A real neon tube is a near-white core with a coloured halo around it —
   colouring the letterform itself and adding a soft shadow looks like glowing
   text, not like a tube. So the stroke stays almost white and every drop of
   colour lives in stacked drop-shadows at increasing blur.
   ------------------------------------------------------------------------- */

body.season-halloween {
    --brand-alt: #B026FF;   /* neon purple reads better than the dusty one */
    --neon-pink: #FF2D95;
    --neon-lime: #39FF14;
    --candy-cream: #FFF3D6;
    --candy-orange: #FF9A1F;
    --candy-yellow: #FFD43B;
}

/* --- Neon sign ------------------------------------------------------------ */

.spooky__sign {
    position: absolute;
    right: 1.6vw;
    bottom: 9vh;
    width: clamp(150px, 13vw, 215px);
    transform: rotate(-4deg);
}

.sign__line {
    font-family: Oswald, "Arial Narrow", Impact, sans-serif;
    font-weight: 700;
    letter-spacing: 0.07em;
    fill: none;
    stroke-width: 2.2;
    stroke-linejoin: round;
}

.sign__line--a {
    font-size: 42px;
    stroke: #FFE9F4;
    filter:
        drop-shadow(0 0 1px var(--neon-pink))
        drop-shadow(0 0 6px var(--neon-pink))
        drop-shadow(0 0 18px color-mix(in srgb, var(--neon-pink) 85%, transparent))
        drop-shadow(0 0 42px color-mix(in srgb, var(--neon-pink) 55%, transparent));
    animation: neon-flicker 7.3s linear infinite;
}

.sign__line--b {
    font-size: 33px;
    stroke: #ECFFE4;
    filter:
        drop-shadow(0 0 1px var(--neon-lime))
        drop-shadow(0 0 6px var(--neon-lime))
        drop-shadow(0 0 18px color-mix(in srgb, var(--neon-lime) 80%, transparent))
        drop-shadow(0 0 40px color-mix(in srgb, var(--neon-lime) 45%, transparent));
    animation: neon-flicker 9.1s linear infinite 0.8s;
}

/* Deliberately irregular. An even pulse reads as an animation; real tubes
   stutter briefly and then hold steady for a while. */
@keyframes neon-flicker {
    0%, 38%, 44%, 76%, 100% { opacity: 1; }
    39%  { opacity: 0.28; }
    40%  { opacity: 1; }
    41%  { opacity: 0.42; }
    42.5%{ opacity: 0.95; }
    43%  { opacity: 0.3; }
    77%  { opacity: 0.35; }
    78%  { opacity: 1; }
    78.6%{ opacity: 0.5; }
}

/* --- Jack-o'-lantern ------------------------------------------------------ */

.spooky__jack {
    position: absolute;
    left: 1.6vw;
    bottom: 3vh;
    width: clamp(95px, 9vw, 134px);
    filter: drop-shadow(0 0 20px color-mix(in srgb, #FF7A18 55%, transparent));
}

/* The candle inside, not a uniform fade. */
.jack__halo {
    transform-origin: 65px 72px;
    animation: jack-candle 3.6s ease-in-out infinite;
}

@keyframes jack-candle {
    0%, 100% { opacity: 0.8;  transform: scale(1); }
    35%      { opacity: 1;    transform: scale(1.07); }
    55%      { opacity: 0.88; transform: scale(1.02); }
    72%      { opacity: 1;    transform: scale(1.05); }
}

/* Both sit in the page gutters. Below this width there are no gutters, so
   they would cover the content rather than frame it. */
@media (max-width: 1400px) {
    .spooky__jack, .spooky__sign { display: none; }
}

/* --- Neon headline -------------------------------------------------------- */

body.season-halloween .hero__title {
    background: none;
    color: #FFF1DC;
    -webkit-text-fill-color: #FFF1DC;
    text-shadow:
        0 0 4px #FFC88A,
        0 0 16px var(--brand),
        0 0 38px color-mix(in srgb, var(--brand) 78%, transparent),
        0 0 76px color-mix(in srgb, var(--brand-alt) 60%, transparent);
    animation: neon-flicker 11.4s linear infinite 1.6s;
}

/* --- Candy corn ----------------------------------------------------------- */

body.season-halloween .badge {
    background: linear-gradient(180deg,
        var(--candy-cream) 0 32%,
        var(--candy-orange) 32% 68%,
        var(--candy-yellow) 68% 100%);
    color: #2A1403;
    border: 1px solid rgb(0 0 0 / 0.28);
}

/* A candy-corn rule under each section heading. */
body.season-halloween .section__title::after,
body.season-halloween .pagehead__title::after {
    content: "";
    display: block;
    width: 72px;
    height: 5px;
    margin-top: 12px;
    border-radius: 2px;
    background: linear-gradient(90deg,
        var(--candy-cream) 0 33%,
        var(--candy-orange) 33% 66%,
        var(--candy-yellow) 66% 100%);
}

@media (prefers-reduced-motion: reduce) {
    .sign__line, .jack__halo, body.season-halloween .hero__title { animation: none; }
}