/*
Theme Name: What's Up Summerland
Theme URI: https://whatsupsummerland.ca
Author: Morrison Sites
Description: What's Up Summerland Community Website. Designed by Morrison Sites.
Version: 1.0
Text Domain: wus
*/

/* This is the theme's single main stylesheet — base tokens, type, layout, and Gutenberg */
/* element styling all live here (formerly split out into css/site.css, now merged in). */
/* css/blocks.css stays separate for shortcode/component-specific styling (calendar, */
/* live-conditions, hero) so this file doesn't grow without bound as those are added to. */

/* Fonts */
@font-face {
    font-family: "Gotham";
    src: url("./fonts/book.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Gotham";
    src: url("./fonts/medium.woff2") format("woff2");
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Gotham";
    src: url("./fonts/bold.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Gotham";
    src: url("./fonts/black.woff2") format("woff2");
    font-weight: 900;
    font-style: normal;
    font-display: swap;
}

/* Design tokens — StyleGuide v1 (see CLAUDE.md "Visual identity (v1 — per StyleGuide)"). */
/* Pivoted off the old Carlin-Residence-Club reference system (oxblood ink, Fraunces serif, */
/* no-radius) — this is the current, live token set; don't reintroduce the serif pairing. */
:root {
    /* No beige/cream — page background is plain white, same as card surfaces; the two */
    /* only separate visually via hairline borders now (see .wus-section, card rules below). */
    --wus-color-paper: #ffffff;
    --wus-color-white: #ffffff;
    --wus-color-ink: #211c18;
    --wus-color-ink-soft: rgba(33, 28, 24, 0.72);
    --wus-color-line: #e7dece;
    --wus-color-pink: #fbb2c6;
    --wus-color-pink-deep: #e86d90;
    --wus-color-yellow: #fffde9;
    --wus-color-yellow-deep: #ebc94a;
    /* Aliases used throughout the rest of this file/blocks.css — both resolve to white now. */
    --wus-color-bg: var(--wus-color-paper);
    --wus-color-bg-alt: var(--wus-color-white);
    --wus-color-cream-text: var(--wus-color-paper);
    /* Body/UI — system-ui stack, zero cost, no webfont load. No serif anywhere (deliberate). */
    --wus-font-sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    /* Display — headings, CTAs, chips, dates. Gotham is licensed and already self-hosted */
    /* (fonts/*.woff2); Montserrat (Google Fonts) is the documented free stand-in if the */
    /* Gotham license lapses — swap the family list, not the token name. */
    --wus-font-display: "Gotham", "Montserrat", -apple-system, BlinkMacSystemFont, sans-serif;
    /* Postcard script — wordmark flourishes only ("What's Up" / "British Columbia" in the */
    /* hero, see css/blocks.css ".hero"); never body or UI. Placeholder pending Daniel's */
    /* locked selection — record the real family here once chosen (see CLAUDE.md wordmark §). */
    --wus-font-script: "Alex Brush", "Snell Roundhand", "Segoe Script", cursive;
    --wus-radius: 2px;
    /* .site-header__inner's own box height (0.6rem padding top+bottom + 3rem min-height) — */
    /* the sticky header is in normal flow, not fixed, so it pushes .hero (css/blocks.css) */
    /* down by exactly this much. Used to size the hero against the *visible* viewport left */
    /* after that push, rather than the full 100svh, so its content lands truly centred */
    /* instead of sitting low. Constant across breakpoints (no wrapping at this min-height). */
    --wus-header-h: 4.2rem;
}

/* Base type + colour. Ink on paper by default; sections can opt into .has-bg-alt for the */
/* white "raised surface" fill. Ink does all the reading — pastels are fills only, never text. */
body {
    background: var(--wus-color-bg);
    color: var(--wus-color-ink);
    font-family: var(--wus-font-sans);
}

.has-bg-alt {
    background: var(--wus-color-bg-alt);
}

/* Headings — the display half of the type system: Gotham Bold, uppercase, tight tracking. */
/* Used both by template markup (h1/h2/etc.) and by Gutenberg's own heading block class. */
/* A fluid scale (clamp) so big display headings don't need a separate display class — H1 is */
/* the hero title, H2 is the standard section divider, H3+ step down for sub-sections. */
h1, h2, h3, h4, h5, h6,
.wp-block-heading {
    font-family: var(--wus-font-display);
    color: var(--wus-color-ink);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: -0.01em;
    line-height: 1.1;
}

h1 { font-size: clamp(2.5rem, 5vw + 1rem, 4.5rem); }
h2 { font-size: clamp(1.85rem, 2.5vw + 1rem, 2.75rem); }
h3 { font-size: clamp(1.4rem, 1.2vw + 1rem, 1.75rem); }
h4, h5, h6 { font-size: 1.1rem; }

/* Squared-off corners everywhere by default — see CLAUDE.md. */
img {
    border-radius: var(--wus-radius);
    max-width: 100%;
    height: auto;
    display: block;
}

/* Page title — the h1 page.php prints above the_content(). Centred over the reading column */
/* so an interior page opens the same way the homepage does (the hero wordmark is centred */
/* too), rather than the title being the one flush-left thing on an otherwise centred site. */
.page-title {
    text-align: center;
}

/* Content column for page-home.php and similar simple templates. */
.page-xl {
    max-width: 1200px;
    margin: 0 auto;
    padding: 3rem 1.5rem;
}

.page-xl > * + * {
    margin-top: 1.25rem;
}

/* Section rhythm — alternating paper/white bands with a hairline seam between them, per */
/* CLAUDE.md "Visual identity (v1 — per StyleGuide)". Applied by wrapping a homepage/page */
/* section in a wp:group with class "wus-section" (every seam) and "has-bg-alt" (the white */
/* "raised surface" ones). The white fill stays within the page-xl reading column rather */
/* than bleeding to the viewport edge — simpler to keep reliable in a classic */
/* (non-block-theme) template than a 100vw hack. */
.wus-section {
    padding: 2.5rem 0;
    border-bottom: 1px solid var(--wus-color-line);
}

.wus-section:last-child {
    border-bottom: none;
}

.wus-section.has-bg-alt {
    padding: 2.5rem 1.5rem;
    margin-left: -1.5rem;
    margin-right: -1.5rem;
}

/* Full-bleed breather photos — a single wide/full-aligned image block with no text over */
/* it, breaking out to the true viewport edge (unlike .wus-section above). Needs */
/* add_theme_support('align-wide') in functions.php, which this theme now declares. */
.wp-block-image.alignfull {
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    width: 100vw;
    max-width: 100vw;
}

.wp-block-image.alignfull img {
    width: 100%;
    height: 60svh;
    object-fit: cover;
}

/* Two-column image+copy pairing — core's media-text block, restyled onto our tokens rather */
/* than custom markup (see CLAUDE.md "Two-column media+text pattern"). */
.wp-block-media-text {
    margin: 0;
}

.wp-block-media-text .wp-block-media-text__content {
    padding: 2rem 1.5rem;
}

.wp-block-media-text__media img {
    height: 100%;
    object-fit: cover;
}

/* --- Gutenberg content elements --- */
/* Styling for what editors actually produce in the block editor: headings (above), */
/* paragraphs, buttons, and images/captions. */

.wp-block-paragraph {
    color: var(--wus-color-ink);
    line-height: 1.6;
}

.wp-block-image img,
.wp-block-cover,
.wp-block-media-text__media img,
.wp-block-gallery img {
    border-radius: var(--wus-radius);
}

.wp-block-image figcaption {
    font-family: var(--wus-font-sans);
    font-size: 0.85rem;
    color: var(--wus-color-ink-soft);
    margin-top: 0.5rem;
}

/* Buttons — see CLAUDE.md "UI style > Buttons". Gotham Bold caps, 2px ink border, hard */
/* square corners (0-radius, deliberately not --wus-radius — buttons get zero rounding, */
/* full stop), offset-shadow hover (the one place the UI raises its voice). .btn is the */
/* plain-markup equivalent for shortcode-authored buttons that never pass through the block */
/* editor — same look as a Gutenberg button, which defaults to the primary (ink-fill) */
/* variant below. */
.btn,
.wp-block-button__link.wp-element-button {
    display: inline-block;
    padding: 0.85em 1.75em;
    border: 2px solid var(--wus-color-ink);
    /* !important: Gutenberg's button-block corner-radius control writes an inline */
    /* style="border-radius:…" straight onto the element, which would otherwise beat this. */
    border-radius: 0 !important;
    background: var(--wus-color-ink);
    color: var(--wus-color-paper);
    font-family: var(--wus-font-display);
    font-weight: 700;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-decoration: none;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

/* Hard offset shadow, no blur — a sticker/postcard nod, not a soft elevation shadow. */
.btn:hover,
.btn:focus-visible,
.wp-block-button__link.wp-element-button:hover,
.wp-block-button__link.wp-element-button:focus-visible {
    transform: translate(-2px, -2px);
    box-shadow: 4px 4px 0 var(--wus-color-pink-deep);
}

@media (prefers-reduced-motion: reduce) {
    .btn,
    .wp-block-button__link.wp-element-button {
        transition: none;
    }

    .btn:hover,
    .btn:focus-visible,
    .wp-block-button__link.wp-element-button:hover,
    .wp-block-button__link.wp-element-button:focus-visible {
        transform: none;
    }
}

/* Secondary — white fill, ink text, ink border. */
.btn--secondary {
    background: var(--wus-color-white);
    color: var(--wus-color-ink);
}

/* Accent — pastel fill, ink text; each gets the *other* pastel as its offset shadow so the */
/* hover motif still reads against a same-hue fill. */
.btn--accent-pink {
    background: var(--wus-color-pink);
    color: var(--wus-color-ink);
}

.btn--accent-pink:hover,
.btn--accent-pink:focus-visible {
    box-shadow: 4px 4px 0 var(--wus-color-yellow-deep);
}

.btn--accent-yellow {
    background: var(--wus-color-yellow);
    color: var(--wus-color-ink);
}

.btn--accent-yellow:hover,
.btn--accent-yellow:focus-visible {
    box-shadow: 4px 4px 0 var(--wus-color-pink-deep);
}

/* Accordion (core/accordion) — the FAQ pattern Daniel builds in the block editor. */
/* Core ships the markup, the interactivity-API behaviour (aria-expanded, hidden= */
/* "until-found", the .is-open class on the item) AND a small base stylesheet — see the */
/* style.min.css files under wp-includes/blocks/accordion-heading, -item and -panel. Two */
/* things core already does that are deliberately NOT repeated here: the +/× icon rotation */
/* on .is-open, and its transitions (which core correctly wraps in prefers-reduced-motion: */
/* no-preference). Everything below is only our skin on top. */
/* Theme styles load after core's block styles (see wus_enqueue_assets(), functions.php), */
/* so same-specificity overrides below win on source order — the normal theming contract. */
/* Two deliberate departures from the theme's usual heading treatment: */
/*   1. Smaller. Core's toggle inherits font-size from its <h3> wrapper, which was picking */
/*      up our global h1–h6 clamp and rendering these questions at up to 1.75rem. An FAQ */
/*      heading is a row label you scan, not a section divider, so it sits just above body */
/*      size instead. */
/*   2. Not uppercase. These are questions in sentence case ("Can I list my event?"); */
/*      forcing the display font's usual caps onto a question mark reads as shouting. */
/*      Same exception, same reasoning, as .site-header__menu a above. */
.wp-block-accordion {
    /* Questions are a reading task — cap the measure rather than letting a one-line */
    /* question stretch the full width of a desktop viewport. */
    max-width: 46rem;
}

/* Hairline-separated rows, no cards or boxes: squared and honest, and it keeps the block */
/* quiet next to the calendar, which is where the page's boldness is supposed to go. */
.wp-block-accordion-item {
    border-bottom: 1px solid var(--wus-color-line);
}

.wp-block-accordion-item:first-child {
    border-top: 1px solid var(--wus-color-line);
}

/* Collapse the block-gap core's is-layout-flow adds between items, so the hairlines above */
/* stack into one continuous ruled list instead of floating apart. Both selectors are */
/* listed because the gap rule core generates is scoped to the parent wrapper — matching it */
/* on specificity alone would leave this dependent on stylesheet order. */
.wp-block-accordion-item + .wp-block-accordion-item,
.wp-block-accordion > .wp-block-accordion-item + .wp-block-accordion-item {
    margin-top: 0;
}

/* The <h3> wrapper carries no visual weight of its own — it exists for the document */
/* outline. Resetting it to inherit is what actually defuses the global heading clamp, */
/* since core's toggle takes its own font-size from here. */
.wp-block-accordion-heading {
    margin: 0;
    font-size: inherit;
    letter-spacing: normal;
}

/* Core already sets display:flex, width:100%, background:none, border:none and font-* */
/* inherit on this button — restated here only where our value differs from core's. */
.wp-block-accordion-heading__toggle {
    gap: 1.5rem;
    padding: 0.95rem 1rem;
    border-radius: 0;
    color: var(--wus-color-ink);
    font-family: var(--wus-font-display);
    font-weight: 700;
    font-size: 1.05rem;
    line-height: 1.35;
    letter-spacing: -0.01em;
    text-align: left;
    text-transform: none;
    transition: background-color 0.15s ease;
}

/* Pink on hover, per Daniel — as a *fill* behind the ink text, not pink text. Pastel-on- */
/* white text fails contrast and CLAUDE.md forbids it outright ("ink does all the reading; */
/* pastels appear only as fills behind ink text"), so the row itself turns pink and the */
/* question stays ink. Same instinct as the chips and the menu overlay. */
.wp-block-accordion-heading__toggle:hover,
.wp-block-accordion-heading__toggle:focus-visible {
    background-color: var(--wus-color-pink);
}

/* Core underlines the title on hover as *its* affordance. With the pink fill doing that */
/* job, the underline is one signal too many — and it collides with the site-wide yellow */
/* link underline vocabulary, where an underline means "this is a link". Scoped one level */
/* deeper than core's own rule so this doesn't hinge on stylesheet order. */
.wp-block-accordion-heading .wp-block-accordion-heading__toggle:hover .wp-block-accordion-heading__toggle-title {
    text-decoration: none;
}

.wp-block-accordion-heading__toggle:focus-visible {
    outline: 2px solid var(--wus-color-ink);
    outline-offset: -2px;
}

/* Core sizes this box in em (1.2em square) and owns the rotation — this just scales the */
/* "+" glyph up off the question's 1.05rem so it reads as a control rather than punctuation. */
.wp-block-accordion-heading__toggle-icon {
    flex-shrink: 0;
    font-size: 1.4rem;
    font-weight: 400;
    line-height: 1;
}

/* Open marker — a pink-deep rule down the left edge, drawn as an inset box-shadow rather */
/* than a real border so opening a row doesn't shove its text sideways by 3px. Deliberately */
/* not the hover fill: with several rows open at once a stack of solid pink blocks would */
/* swamp the page, where a thin marker still reads clearly at a glance. */
.wp-block-accordion-item.is-open > .wp-block-accordion-heading .wp-block-accordion-heading__toggle {
    box-shadow: inset 3px 0 0 var(--wus-color-pink-deep);
}

/* Body copy, not display type — the answer is the one thing here that's actually read at */
/* length. Left padding matches the toggle's so question and answer share a left edge; the */
/* wider right inset keeps the answer clear of the icon column above it. */
.wp-block-accordion-panel {
    padding: 0 3rem 1.25rem 1rem;
    font-size: 0.95rem;
    line-height: 1.65;
    color: var(--wus-color-ink-soft);
}

.wp-block-accordion-panel > :first-child {
    margin-top: 0;
}

.wp-block-accordion-panel > :last-child {
    margin-bottom: 0;
}

@media (prefers-reduced-motion: reduce) {
    .wp-block-accordion-heading__toggle {
        transition: none;
    }
}

/* Links — ink text, thick yellow underline. Pink is reserved for CTAs (buttons, header */
/* hover — see .btn and .site-header__menu a below); yellow marks secondary CTAs/links. */
/* Uses the -deep gold rather than the pale --wus-color-yellow swatch — the pale tone all but */
/* disappears against the white page background, so the resting underline needs the same */
/* saturated gold as the hover state (below) to actually read as an underline. */
a {
    color: var(--wus-color-ink);
    text-decoration-color: var(--wus-color-yellow-deep);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.15em;
}

a:hover,
a:focus-visible {
    text-decoration-color: var(--wus-color-yellow-deep);
    /* 2/3 of the old 4px hover thickness. */
    text-decoration-thickness: 2.67px;
}

/* Site header. Sticky at the top of every page — .site-header__brand ("Summerland") is the */
/* permanent landing target the homepage hero scrubs itself into on scroll (see CLAUDE.md */
/* "1. Scroll-animation system" > hero notes). On interior pages (no hero, no JS dependency) */
/* it just renders at this resting state, centred, from first paint — see js/scroll-system.js */
/* postcard-hero scene, which only touches .site-header__brand when a hero exists on the page. */
/* Thin, borderless, single row at every width: a 3-column grid (weather / brand / nav+toggle) */
/* keeps the brand mathematically centred and the other two flush to their edges — and every */
/* column shares one align-items:center, so nothing needs its own vertical nudge. */
.site-header {
    position: sticky;
    top: 0;
    /* Above .site-menu-overlay's z-index:100 — the header (incl. the toggle that closes it) */
    /* stays fully visible and un-blurred while the full-screen menu is open. */
    z-index: 110;
    background: var(--wus-color-bg);
    transition: background-color 0.25s ease;
}

/* Fades to transparent while the full-screen menu is open, so the header strip blends into */
/* the blurred overlay below it instead of sitting on top as a solid white bar. The nav */
/* content itself stays put — .site-header's z-index keeps it above the overlay, so it's */
/* still fully visible and un-blurred, just without an opaque backing. */
body.site-menu-open .site-header {
    background: transparent;
}

@media (prefers-reduced-motion: reduce) {
    .site-header {
        transition: none;
    }
}

.site-header__inner {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 1rem;
    padding: 0.6rem 1.5rem;
    min-height: 3rem;
}

.site-header__brand {
    grid-column: 2;
    justify-self: center;
    margin: 0;
    /* No more inline text descender gap to absorb now that this is an image. */
    line-height: 0;
}

.site-header__brand a {
    display: inline-block;
    transition: opacity 0.15s ease;
}

/* Intrinsic 1733x562 (viewBox) — height-driven so it sits at roughly the old text's cap */
/* height, width follows from the wordmark's own ~3:1 aspect ratio. */
.site-header__logo {
    display: block;
    height: 1.35rem;
    width: auto;
    user-select: none;
}

/* Opacity dip on hover — was a pink text-colour swap (matching the hamburger icon's pink */
/* hover) back when this was live "SUMMERLAND" type; an <img> ignores `color`, so that */
/* treatment doesn't carry over to the logo mark. Suppressed while the full-screen menu is */
/* open (body.site-menu-open, set in app.js) for the same reason the old rule was: */
/* .site-header goes transparent then, and this sits over the blurred/tinted overlay. */
body:not(.site-menu-open) .site-header__brand a:hover,
body:not(.site-menu-open) .site-header__brand a:focus-visible {
    opacity: 0.7;
}

/* Right-hand cluster: inline nav sits directly beside the hamburger, both flush right. */
.site-header__right {
    grid-column: 3;
    justify-self: end;
    display: flex;
    align-items: center;
    gap: 1.5rem;
}

/* Hidden below the breakpoint where it'd crowd the centred brand — the hamburger's */
/* full-screen overlay (below) is the only nav access on narrow viewports. */
.site-header__nav {
    display: none;
}

.site-header__menu {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.site-header__menu a {
    color: var(--wus-color-ink);
    text-decoration: none;
    font-family: var(--wus-font-display);
    font-weight: 700;
    font-size: 0.85rem;
    /* Not capitalized, per Kent — the one deliberate exception to the display font's */
    /* usual uppercase treatment (see CLAUDE.md "Typography"). */
    text-transform: none;
    transition: color 0.15s ease;
}

/* Text turns pink on hover, same treatment/rationale as .site-header__brand a above — */
/* matches the hamburger icon exactly, suppressed while the full-screen menu is open since */
/* .site-header itself is transparent then and already shows the overlay's own pink tint */
/* through it (see body.site-menu-open above). :focus-visible always keeps its own plain */
/* outline too, so keyboard navigation has a visible indicator either way. */
body:not(.site-menu-open) .site-header__menu a:hover,
body:not(.site-menu-open) .site-header__menu a:focus-visible {
    color: var(--wus-color-pink);
}

.site-header__menu a:focus-visible {
    outline: 2px solid var(--wus-color-ink);
    outline-offset: 3px;
}

@media (min-width: 700px) {
    .site-header__nav {
        display: flex;
    }
}

/* Header temperature readout — far-left grid column, a compact echo of .wus-conditions__temp */
/* (see css/blocks.css) rather than the full place-and-reading band. Server-rendered by */
/* wus_render_header_weather() (inc/blocks.php); renders nothing if the reading is unavailable, */
/* which just leaves this grid column empty without breaking the brand's centring. */
.site-header__weather {
    grid-column: 1;
    justify-self: start;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-family: var(--wus-font-display);
    font-weight: 700;
    font-size: 0.85rem;
    color: var(--wus-color-ink);
    white-space: nowrap;
}

.site-header__weather-dot {
    width: 0.5rem;
    height: 0.5rem;
    background: var(--wus-color-yellow-deep);
    border: 1px solid var(--wus-color-ink);
    border-radius: 50%;
}

/* Hamburger toggle — Lottie-driven bar→X (animations/menu/bar.json), wired up in app.js. */
/* The SVG's fill is rewritten to currentColor on load, so colour is just this button's */
/* `color`: ink normally, pastel-pink on hover/focus — the one hover accent per CLAUDE.md's */
/* "ink does all the reading" rule doesn't apply here since this is an icon glyph, not text. */
.site-header__toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Hit area stays a full 2rem for tap accuracy — only the icon glyph inside (below) */
    /* is scaled down, so shrinking it doesn't also shrink the clickable target. */
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: none;
    background: none;
    color: var(--wus-color-ink);
    cursor: pointer;
    transition: color 0.15s ease;
}

/* Suppressed while the full-screen menu is open (body.site-menu-open, set in app.js) — */
/* .site-header goes transparent then and the pink menu-overlay tint shows straight */
/* through it (see body.site-menu-open above), so a pink icon would vanish into that */
/* background instead of standing out. Same rationale as the nav/brand hover chips below. */
body:not(.site-menu-open) .site-header__toggle:hover,
body:not(.site-menu-open) .site-header__toggle:focus-visible {
    color: var(--wus-color-pink);
}

.site-header__toggle-icon {
    display: block;
    /* About half the old 2rem icon, then bumped ~1/3 larger again. */
    width: 1.33rem;
    height: 1.33rem;
}

.site-header__toggle-icon svg {
    display: block;
    width: 100%;
    height: 100%;
}

@media (prefers-reduced-motion: reduce) {
    .site-header__toggle {
        transition: none;
    }
}

/* Full-screen menu overlay — opened by .site-header__toggle. Blurred backdrop over the */
/* current page, the header-menu location repeated bold/large and centred (see header.php); */
/* app.js toggles .is-open and locks body scroll via body.site-menu-open. */
.site-menu-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    /* Pastel pink (--wus-color-pink, #fbb2c6) rather than a plain white scrim — a fun, */
    /* on-brand tint for the one full-bleed moment in the UI. Ink text over a pastel fill */
    /* passes contrast per CLAUDE.md's accessibility rule, same as chips/buttons. */
    background: rgba(251, 178, 198, 0.6);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s ease;
}

.site-menu-overlay.is-open {
    opacity: 1;
    visibility: visible;
}

.site-menu-overlay__menu {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    margin: 0;
    padding: 0;
    list-style: none;
    text-align: center;
}

.site-menu-overlay__menu a {
    font-family: var(--wus-font-display);
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.01em;
    font-size: clamp(2rem, 6vw, 4.5rem);
    line-height: 1.1;
    color: var(--wus-color-ink);
    text-decoration: none;
}

/* No hover underline — pink-deep against the overlay's own pink tint (see .site-menu-overlay */
/* above) read as pink-on-pink. :focus-visible gets a plain outline instead, so keyboard */
/* navigation through the overlay still has a visible indicator. */
.site-menu-overlay__menu a:focus-visible {
    outline: 3px solid var(--wus-color-ink);
    outline-offset: 6px;
}

body.site-menu-open {
    overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
    .site-menu-overlay {
        transition: none;
    }
}

/* Site footer. Labelled columns, one per nav location, stacked on mobile. */
.site-footer {
    background: var(--wus-color-yellow);
    color: var(--wus-color-ink);
    padding: 2rem 1.5rem;
}

/* Caps the columns/legal bar at the same reading width as .page-xl, so footer content and */
/* links stay a sane line length instead of stretching edge-to-edge on wide desktop viewports. */
.site-footer__inner {
    max-width: 1200px;
    margin: 0 auto;
}

.site-footer__columns {
    display: flex;
    flex-direction: column;
    gap: 2rem;
}

/* No underline here — the footer's yellow background is the same family as the site-wide */
/* underline colour, so an underline on these headings would all but disappear against it. */
.site-footer__heading {
    display: inline-block;
    margin: 0 0 0.75rem;
    font-family: var(--wus-font-display);
    font-size: 0.9rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.site-footer__menu {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.site-footer__menu a {
    color: var(--wus-color-ink);
    text-decoration: none;
}

.site-footer__menu a:hover,
.site-footer__menu a:focus-visible {
    /* Ink, not the site-wide yellow — a yellow underline would vanish against the footer's */
    /* yellow background. */
    text-decoration: underline;
    text-decoration-color: var(--wus-color-ink);
    /* 2/3 of the old 4px hover thickness, matching the site-wide `a:hover` above. */
    text-decoration-thickness: 2.67px;
    text-underline-offset: 0.2em;
}

@media (min-width: 600px) {
    .site-footer__columns {
        flex-direction: row;
        gap: 3rem;
    }
}

/* Bottom legal bar — copyright + hosting line on the left, agency brandmark pinned to the */
/* bottom right (per CLAUDE.md's own footer, wraps to a second line under the text on narrow */
/* viewports rather than overlapping it). */
.site-footer__bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 2rem;
    padding-top: 1.5rem;
}

.site-footer__legal {
    margin: 0;
    font-size: 0.8rem;
    color: var(--wus-color-ink-soft);
}

.site-footer__brandmark {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
}

/* Rendered as a CSS mask rather than an <img> so the brandmark can be recoloured on hover — */
/* the SVG itself (images/msites.svg) is a single hardcoded-black fill, so masking a background */
/* colour through it is what lets us swap ink for pink without touching the source file. */
.site-footer__brandmark-icon {
    display: block;
    /* ~25% smaller than the original 280px. */
    width: 210px;
    aspect-ratio: 620 / 51;
    background-color: var(--wus-color-ink);
    -webkit-mask: url('./images/msites.svg') no-repeat center / contain;
    mask: url('./images/msites.svg') no-repeat center / contain;
    transition: background-color 0.15s ease;
}

.site-footer__brandmark:hover .site-footer__brandmark-icon,
.site-footer__brandmark:focus-visible .site-footer__brandmark-icon {
    background-color: var(--wus-color-pink-deep);
}
