/*
Theme Name: Sutton Maths Tuition
Theme URI: https://www.suttonmathstutor.co.uk/
Author: Senura / Digit44
Description: Bespoke theme generated from the approved static prototype. Crimson + gold editorial design, dark/light themes, no builders.
Version: 1.0.0
License: Proprietary — client use only.
Text Domain: smt
*/

/* ==========================================================================
   SUTTON MATHS TUITION — STATIC PROTOTYPE
   Design system + components.

   PROTOTYPE ONLY. Nothing here touches WordPress or the live site. This is a
   standalone static build so the visual direction can be judged before any
   decision is made about how (or whether) it ports back into Bridge.

   PALETTE: warm ivory + white two-tone, brand crimson + gold.
   Taken from the client's own logo (crimson figure, gold books). Crimson
   carries action — CTAs, links, current page. Gold is decorative only
   (rules, keylines). Body surfaces stay warm neutrals, because colour used
   everywhere stops reading as design and starts reading as noise.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Crimson+Pro:ital,wght@0,500;0,600;0,700;1,500&family=Inter:wght@400;500;600;700&display=swap');


/* ==========================================================================
   1. TOKENS — LIGHT (default)
   --------------------------------------------------------------------------
   Contrast ratios below are computed WCAG 2.1 values against --bg.
   ========================================================================== */

:root {
    /* --- Brand -------------------------------------------------------------
       The client's own identity, taken from the logo file (mathlogo-1.png):
       crimson figure/wordmark + warm gold books. Crimson carries action
       (buttons, links, current page); gold is decorative only — at ~2.2:1 it
       fails WCAG for text, so it never carries meaning, only rules and edges.
       Surfaces are a two-tone warm pair: ivory base, white alt bands. */
    --crimson:      #B10025;   /* 7.1:1 on ivory — PASS */
    --crimson-deep: #8E001E;   /* hover end-stop; white 9.9:1 — PASS */
    --crimson-bright: #C20029; /* ramp start; white 6.3:1 — PASS */
    --gold:         #C0AC79;   /* decorative only — 2.2:1, never text */
    --gold-deep:    #8A6D2F;   /* darkest gold that still reads as gold */
    --espresso:     #2A1A12;   /* warm near-black for footer + scrims */

    /* --- Gradients ----------------------------------------------------------
       Three separate ramps, because they have three different contrast jobs:

       --grad-cta   has WHITE TEXT on top of it. Every stop must clear 4.5:1
                    against white, so it stays deep crimson throughout.
       --grad-text  is used as CLIPPED TEXT (background-clip: text), so it must
                    clear 4.5:1 / 3:1 against the surface behind it instead.
       --grad-deco  is pure decoration — rules, bullets, underlines. No
                    contrast requirement, so this is where the gold goes.
       --------------------------------------------------------------------- */
    --grad-brand:   linear-gradient(150deg, #2A1A12 0%, #471A20 55%, #5E1E28 100%);
    --grad-cta:     linear-gradient(135deg, #C20029 0%, #B10025 52%, #8E001E 100%);  /* white 6.3:1+ */
    --grad-cta-hover: linear-gradient(135deg, #D4002D 0%, #C20029 55%, #A50022 100%); /* white 5.4:1+ */
    --grad-text:    linear-gradient(135deg, #B10025 0%, #8E001E 100%);  /* on ivory 7:1+ */
    --grad-deco:    linear-gradient(90deg, #B10025 0%, #8E001E 45%, #C0AC79 100%);
    --grad-soft:    linear-gradient(135deg, rgba(177,0,37,.07) 0%, rgba(192,172,121,.14) 100%);
    --grad-line:    linear-gradient(90deg, #B10025 0%, #8E001E 45%, #C0AC79 100%);

    /* --- Surfaces: the two-tone pair ----------------------------------------
       Warm ivory base, true-white alt bands. Sections alternate between the
       two so the page has rhythm without any coloured chrome. */
    --bg:           #FBF6EE;
    --bg-alt:       #FFFFFF;
    --surface:      #FFFFFF;
    --surface-2:    #F5EDDF;

    /* Glass. Tuned against photographic backgrounds (hero, photo band), where
       there is genuinely something behind the panel to blur. */
    --glass-bg:     rgba(255, 253, 248, .78);
    --glass-brd:    rgba(255, 255, 255, .80);
    --glass-shadow: 0 8px 32px rgba(59, 30, 20, .12);

    /* --- Text ------------------------------------------------------------- */
    --fg:           #2B2320;   /* 13.5:1 on ivory — PASS */
    --fg-muted:     #6B5E55;   /*  5.9:1 on ivory — PASS */
    --fg-invert:    #FFFFFF;

    /* --- Borders ----------------------------------------------------------
       --brd is decorative. --brd-strong is for UI boundaries, where WCAG
       1.4.11 requires 3:1. Warm-tinted so hairlines don't read blue-grey. */
    --brd:          rgba(59, 30, 20, .12);
    --brd-strong:   rgba(59, 30, 20, .32);

    /* --- Geometry --------------------------------------------------------- */
    --r-sm: 8px;
    --r-md: 14px;
    --r-lg: 22px;
    --r-xl: 30px;
    --r-pill: 999px;

    /* --- Motion ----------------------------------------------------------- */
    --t-fast: 160ms;
    --t-base: 260ms;
    --t-slow: 620ms;
    --ease: cubic-bezier(.22, 1, .36, 1);

    /* --- Layout ----------------------------------------------------------- */
    --wrap: 1180px;
    --gutter: clamp(1.25rem, 5vw, 2.5rem);
    --sec-y: clamp(4rem, 9vw, 7.5rem);
}


/* ==========================================================================
   2. TOKENS — DARK (warm)
   --------------------------------------------------------------------------
   Not an inversion. Inverted UIs look flat and the shadows stop working, so
   borders and surfaces are re-picked rather than flipped: the dark theme is
   a deep espresso ground with crimson pushed brighter so it still reads as
   the accent rather than receding.
   ========================================================================== */

[data-theme="dark"] {
    --crimson:      #E5485D;   /* 5.6:1 on --bg — PASS for links */
    --crimson-deep: #B10025;
    --crimson-bright: #D4002D;
    --gold:         #C0AC79;
    --gold-deep:    #D6C294;
    --espresso:     #120B08;

    --grad-brand:   linear-gradient(150deg, #120B08 0%, #2A1215 55%, #3D1620 100%);
    --grad-cta:     linear-gradient(135deg, #C20029 0%, #A50022 100%);  /* white 5.9:1+ */
    --grad-cta-hover: linear-gradient(135deg, #D4002D 0%, #B10025 100%); /* white 5.4:1+ */
    /* Text can go brighter here than it can on ivory — the surface is dark. */
    --grad-text:    linear-gradient(135deg, #E5485D 0%, #E88A7B 100%);  /* on espresso 6+:1 */
    --grad-deco:    linear-gradient(90deg, #E5485D 0%, #B10025 45%, #C0AC79 100%);
    --grad-soft:    linear-gradient(135deg, rgba(229,72,93,.14) 0%, rgba(192,172,121,.14) 100%);
    --grad-line:    linear-gradient(90deg, #E5485D 0%, #B10025 45%, #C0AC79 100%);

    --bg:           #1A1310;
    --bg-alt:       #221915;
    --surface:      #241B16;
    --surface-2:    #2E2119;

    --glass-bg:     rgba(36, 27, 22, .72);
    --glass-brd:    rgba(255, 255, 255, .12);
    --glass-shadow: 0 8px 32px rgba(0, 0, 0, .45);

    --fg:           #F5EDE3;   /* 14+:1 — PASS */
    --fg-muted:     #C4B4A6;   /*  7+:1 — PASS */
    --fg-invert:    #2B2320;

    --brd:          rgba(245, 237, 227, .13);
    --brd-strong:   rgba(245, 237, 227, .34);
}


/* ==========================================================================
   3. RESET + BASE
   ========================================================================== */

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

html {
    /* Requirement: smooth scrolling site-wide. */
    scroll-behavior: smooth;
    /* Offset anchor jumps so the sticky header doesn't cover the target. */
    scroll-padding-top: 96px;
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--fg);
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-size: 1rem;
    line-height: 1.7;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
    /* Theme swap is a colour crossfade, not a flash. */
    transition: background-color var(--t-base) var(--ease), color var(--t-base) var(--ease);
}

h1, h2, h3, h4 {
    font-family: 'Crimson Pro', Georgia, 'Times New Roman', serif;
    font-weight: 700;
    line-height: 1.12;
    letter-spacing: .002em;
    color: var(--fg);
    margin: 0 0 .6em;
    text-wrap: balance;
}

h1 { font-size: clamp(2.25rem, 1.4rem + 3.4vw, 4rem); }
h2 { font-size: clamp(1.75rem, 1.2rem + 2.1vw, 2.75rem); }
h3 { font-size: clamp(1.15rem, 1rem + .7vw, 1.5rem); }
h4 { font-size: 1.0625rem; }

p { margin: 0 0 1.15em; }
p:last-child { margin-bottom: 0; }

a { color: var(--crimson); text-decoration: none; }

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

::selection { background: var(--crimson); color: #fff; }

/* Visible keyboard focus everywhere. Non-negotiable. */
:focus-visible {
    outline: 3px solid var(--crimson);
    outline-offset: 3px;
    border-radius: var(--r-sm);
}


/* ==========================================================================
   4. LAYOUT
   ========================================================================== */

.wrap {
    width: 100%;
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.section { padding-block: var(--sec-y); position: relative; }

.section--tight { padding-block: clamp(2.5rem, 6vw, 4.5rem); }

/* Alternate ground so sections separate without hard rules. */
.section--alt { background: var(--bg-alt); }

.section-head {
    max-width: 46rem;
    margin: 0 auto clamp(2.5rem, 5vw, 4rem);
    text-align: center;
}
.section-head p {
    color: var(--fg-muted);
    font-size: 1.0625rem;
    margin: 0;
}

/* The short gradient rule under centred headings. */
.rule {
    width: 84px;
    height: 4px;
    border-radius: var(--r-pill);
    background: var(--grad-line);
    margin: 1.25rem auto 0;
}
.section-head--left { margin-inline: 0; text-align: left; }
.section-head--left .rule { margin-inline: 0; }

.eyebrow {
    display: inline-block;
    font-family: 'Inter', sans-serif;
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--crimson);
    margin-bottom: .85rem;
}

.grid { display: grid; gap: clamp(1.25rem, 2.5vw, 2rem); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); }

.center { text-align: center; }

/* Qualification list (About section). Custom crimson markers instead of
   default discs — discs would read generic next to the brand system. */
.quals {
    list-style: none;
    padding: 0;
    margin: 1.75rem 0 0;
}
.quals li {
    position: relative;
    padding-left: 1.7rem;
    margin-bottom: .8rem;
    font-size: .9688rem;
    line-height: 1.6;
    color: var(--fg);
}
.quals li:last-child { margin-bottom: 0; }
.quals li::before {
    content: "";
    position: absolute;
    left: 0;
    top: .58em;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--grad-cta);
}


/* ==========================================================================
   5. BUTTONS
   ========================================================================== */

.btn {
    --btn-py: .875rem;
    --btn-px: 1.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .55rem;
    min-height: 48px;              /* comfortable touch target */
    padding: var(--btn-py) var(--btn-px);
    border: 1px solid transparent;
    border-radius: var(--r-pill);
    font-family: 'Inter', sans-serif;
    font-size: .9375rem;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    text-align: center;
    transition: transform var(--t-fast) var(--ease),
                box-shadow var(--t-base) var(--ease),
                background var(--t-base) var(--ease),
                border-color var(--t-base) var(--ease),
                color var(--t-base) var(--ease);
}

/* Primary — the gradient CTA. */
.btn--primary {
    background-image: var(--grad-cta);
    color: #FFFFFF;
    box-shadow: 0 1px 2px rgba(59,30,20,.14),
                0 10px 24px -10px rgba(177,0,37,.60);
}
.btn--primary:hover {
    background-image: var(--grad-cta-hover);
    transform: translateY(-2px);
    box-shadow: 0 2px 4px rgba(59,30,20,.16),
                0 18px 34px -12px rgba(177,0,37,.70);
    color: #FFFFFF;
}
.btn--primary:active { transform: translateY(0); }

/* Secondary — quiet outline that fills on hover. */
.btn--ghost {
    background: transparent;
    color: var(--fg);
    border-color: var(--brd-strong);
}
.btn--ghost:hover {
    background: var(--grad-cta);
    border-color: transparent;
    color: #FFFFFF;
    transform: translateY(-2px);
}

/* On a dark gradient ground. */
.btn--onDark {
    background: rgba(255,255,255,.10);
    color: #FFFFFF;
    border-color: rgba(255,255,255,.55);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}
.btn--onDark:hover {
    background: #FFFFFF;
    color: var(--espresso);
    border-color: #FFFFFF;
    transform: translateY(-2px);
}

.btn--block { width: 100%; }
.btn--sm { --btn-py: .65rem; --btn-px: 1.25rem; min-height: 42px; font-size: .875rem; }

.btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: .875rem;
}
.btn-row--center { justify-content: center; }


/* ==========================================================================
   6. NAVBAR — transparent over hero, glass once scrolled
   ========================================================================== */

.nav {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 200;
    padding-block: 1rem;
    background: transparent;
    border-bottom: 1px solid transparent;
    transition: background var(--t-base) var(--ease),
                box-shadow var(--t-base) var(--ease),
                border-color var(--t-base) var(--ease),
                padding var(--t-base) var(--ease);
}

/* The scrolled state. backdrop-filter is the effect; the translucent fill is
   what keeps the links readable — blur alone over a busy hero is not enough. */
.nav.is-scrolled {
    padding-block: .6rem;
    background: var(--glass-bg);
    -webkit-backdrop-filter: saturate(180%) blur(16px);
    backdrop-filter: saturate(180%) blur(16px);
    border-bottom-color: var(--brd);
    box-shadow: var(--glass-shadow);
}

/* On pages with no hero, the nav starts solid. */
.nav--solid {
    background: var(--glass-bg);
    -webkit-backdrop-filter: saturate(180%) blur(16px);
    backdrop-filter: saturate(180%) blur(16px);
    border-bottom-color: var(--brd);
}

.nav__inner {
    display: flex;
    align-items: center;
    gap: 1.25rem;
}

/* The logo file has a white background baked in, so it sits in a white
   badge — legible over the photo hero and over the scrolled bar alike.
   Without the badge it would be a floating white rectangle. */
.nav__logo {
    display: flex;
    align-items: center;
    gap: .7rem;
    flex-shrink: 0;
    background: #FFFFFF;
    padding: .35rem .9rem;
    border-radius: 12px;
    box-shadow: 0 2px 12px rgba(26,12,10,.18);
}
.nav__logo img { height: 48px; width: auto; }

/* Links take the middle and centre themselves; the actions (theme toggle +
   CTA) are pinned to the right edge. */
.nav__inner nav { flex: 1 1 auto; min-width: 0; }
.nav__links {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .35rem;
    margin: 0;
    list-style: none;
    padding: 0;
}

.nav__link {
    position: relative;
    display: block;
    padding: .55rem .8rem;
    border-radius: var(--r-sm);
    font-size: .9375rem;
    font-weight: 500;
    color: var(--fg);
    white-space: nowrap;
    transition: color var(--t-fast) var(--ease);
}

/* Animated underline: a gradient bar that wipes in from the left. */
.nav__link::after {
    content: "";
    position: absolute;
    left: .8rem;
    right: .8rem;
    bottom: .3rem;
    height: 2px;
    border-radius: var(--r-pill);
    background: var(--grad-line);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--t-base) var(--ease);
}
.nav__link:hover::after,
.nav__link[aria-current="page"]::after { transform: scaleX(1); }
.nav__link:hover { color: var(--crimson); }
.nav__link[aria-current="page"] { color: var(--crimson); font-weight: 600; }

/* Over the hero the nav sits on a dark image, so it needs light links. */
.nav--overHero .nav__link { color: rgba(255,255,255,.92); }
.nav--overHero .nav__link:hover,
.nav--overHero .nav__link[aria-current="page"] { color: #FFFFFF; }
.nav--overHero .nav__link::after { background: #FFFFFF; }
.nav--overHero .nav__toggle { color: #FFFFFF; border-color: rgba(255,255,255,.5); }

/* The theme switch lives in the same bar, so it needs the same inversion.
   Without it the switch stays --fg ink with a --brd-strong ring while the
   links beside it turn white — about 1.05:1 against the hero scrim and the
   pagehead gradient, well under the 3:1 WCAG 1.4.11 wants for a control
   boundary. It read as a ghost circle in the top-right of every interior
   page. The :hover rules below the base definition are (0,2,0), so these
   need the extra class to win. */
.nav--overHero .theme-toggle { color: #FFFFFF; border-color: rgba(255,255,255,.5); }
.nav--overHero .theme-toggle:hover { border-color: #FFFFFF; background: rgba(255,255,255,.10); }

/* Scrolled, the bar is light ivory glass (dark espresso glass in dark mode),
   so the white over-hero links must step down to normal ink. Using --fg keeps
   this correct in both themes. Without this the links stay white on ivory. */
.nav--overHero.is-scrolled .nav__link { color: var(--fg); }
.nav--overHero.is-scrolled .nav__link:hover,
.nav--overHero.is-scrolled .nav__link[aria-current="page"] { color: var(--crimson); }
.nav--overHero.is-scrolled .nav__link::after { background: var(--grad-line); }
.nav--overHero.is-scrolled .nav__toggle { color: var(--fg); border-color: var(--brd-strong); }
.nav--overHero.is-scrolled .theme-toggle { color: var(--fg); border-color: var(--brd-strong); }
.nav--overHero.is-scrolled .theme-toggle:hover { border-color: var(--crimson); background: transparent; }

.nav__actions { display: flex; align-items: center; gap: .6rem; margin-left: auto; flex-shrink: 0; }

/* Theme switch. */
.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    flex-shrink: 0;
    border: 1px solid var(--brd-strong);
    border-radius: var(--r-pill);
    background: transparent;
    color: inherit;
    cursor: pointer;
    transition: background var(--t-fast) var(--ease),
                border-color var(--t-fast) var(--ease),
                transform var(--t-fast) var(--ease);
}
.theme-toggle:hover { transform: translateY(-1px); border-color: var(--crimson); }
.theme-toggle svg { width: 19px; height: 19px; }

/* Only one icon shows at a time. */
.theme-toggle .icon-moon { display: none; }
[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
[data-theme="dark"] .theme-toggle .icon-moon { display: block; }

.nav__toggle {
    display: none;
    width: 44px; height: 44px;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--brd-strong);
    border-radius: var(--r-sm);
    background: transparent;
    color: inherit;
    cursor: pointer;
}

/* Hamburger becomes an X while the panel is open. Driven purely by the
   aria-expanded state the JS already maintains — no extra classes. */
.nav__toggle .icon-close { display: none; }
.nav__toggle[aria-expanded="true"] .icon-close { display: block; }
.nav__toggle[aria-expanded="true"] .icon-menu { display: none; }

@media (max-width: 960px) {
    .nav__toggle { display: inline-flex; }
    .nav__links {
        position: fixed;
        inset: 0 0 auto 0;
        top: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        margin: 0;
        padding: 5.5rem var(--gutter) 2rem;
        background: var(--surface);
        border-bottom: 1px solid var(--brd);
        box-shadow: var(--glass-shadow);
        transform: translateY(-100%);
        transition: transform var(--t-base) var(--ease);
        max-height: 100dvh;
        overflow-y: auto;
    }
    .nav__links.is-open { transform: translateY(0); }
    .nav__link {
        padding: 1rem .25rem;
        font-size: 1.0625rem;
        border-bottom: 1px solid var(--brd);
        color: var(--fg);
    }
    .nav--overHero .nav__link { color: var(--fg); }
    .nav__link::after { display: none; }
    .nav__cta { display: none; }
}


/* ==========================================================================
   7. HERO — static, no slider
   ========================================================================== */

.hero {
    position: relative;
    isolation: isolate;
    display: flex;
    align-items: center;
    min-height: min(92vh, 780px);
    padding-block: clamp(7rem, 14vh, 10rem) clamp(4rem, 9vh, 7rem);
    /* The client's own photograph: the exam-textbook pile from the live
       slider. Warm espresso fallback while it loads or if it is missing. */
    background: #2A1A12 url('assets/img/hero-books.jpg') center 35% / cover no-repeat;
    color: #FFFFFF;
    overflow: hidden;
    text-align: center;
}

/* Warm scrim so the white serif headline holds against the bright book
   covers. Darkest at the edges, eased in the middle — the eye lands centre.
   Painted on ::before (z-index 0, content at 2) so it can never cover text. */
.hero::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    background:
        linear-gradient(180deg,
            rgba(26,12,10,.80) 0%,
            rgba(26,12,10,.52) 42%,
            rgba(26,12,10,.60) 68%,
            rgba(26,12,10,.86) 100%);
    pointer-events: none;
}

[data-theme="dark"] .hero::before {
    background:
        linear-gradient(180deg,
            rgba(18,8,6,.86) 0%,
            rgba(18,8,6,.62) 42%,
            rgba(18,8,6,.68) 68%,
            rgba(18,8,6,.90) 100%);
}

.hero__inner { position: relative; z-index: 2; max-width: 50rem; margin-inline: auto; }

.hero h1 {
    color: #FFFFFF;
    margin-bottom: .85rem;
    font-size: clamp(2.5rem, 1.6rem + 3.6vw, 4.25rem);
    text-shadow: 0 2px 30px rgba(26,12,10,.55);
}

.hero__lede {
    font-size: clamp(1.0625rem, .95rem + .5vw, 1.3rem);
    color: rgba(255,255,255,.92);
    max-width: 40rem;
    margin-inline: auto;
    margin-bottom: 2rem;
}

.hero__actions { margin-bottom: 2.75rem; justify-content: center; }

/* The price callout — the client's "ONLINE LESSONS OFFERED" line, promoted
   from a shouted line of red text to a proper piece of information. */
.hero__offer {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .5rem 1rem;
    padding: 1rem 1.5rem;
    border-radius: var(--r-lg);
    background: rgba(255,255,255,.10);
    border: 1px solid rgba(255,255,255,.22);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    font-size: .9375rem;
    color: rgba(255,255,255,.94);
}
.hero__offer strong {
    font-family: 'Inter', sans-serif;
    font-size: 1.25rem;
    font-weight: 700;
    color: #FFFFFF;
}

/* Credential chips under the hero. */
.chips { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 2rem; justify-content: center; list-style: none; padding: 0; }
.chip {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .4rem .85rem;
    border-radius: var(--r-pill);
    background: rgba(255,255,255,.10);
    border: 1px solid rgba(255,255,255,.20);
    font-size: .8125rem;
    color: rgba(255,255,255,.92);
}

/* --- Page header for interior pages (shorter than the hero) -------------- */
.pagehead {
    position: relative;
    isolation: isolate;
    padding-block: clamp(7rem, 16vh, 10rem) clamp(3rem, 7vw, 5rem);
    background: var(--grad-brand);
    color: #FFFFFF;
    overflow: hidden;
}
.pagehead::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: radial-gradient(50rem 26rem at 80% 10%, rgba(192,172,121,.20) 0%, rgba(192,172,121,0) 64%);
}
.pagehead h1 { color: #FFFFFF; margin-bottom: .5rem; }
.pagehead p { color: rgba(255,255,255,.86); max-width: 44rem; margin: 0; }


/* ==========================================================================
   8. GLASS CARDS
   ========================================================================== */

.card {
    position: relative;
    padding: clamp(1.5rem, 3vw, 2.25rem);
    border-radius: var(--r-lg);
    background: var(--surface);
    border: 1px solid var(--brd);
    box-shadow: 0 1px 2px rgba(59,30,20,.04), 0 12px 28px -20px rgba(59,30,20,.28);
    transition: transform var(--t-base) var(--ease),
                box-shadow var(--t-base) var(--ease),
                border-color var(--t-base) var(--ease);
}

/* Hover lift — a named requirement (hover scale/shadow on cards). */
.card--lift:hover {
    transform: translateY(-6px);
    border-color: rgba(177,0,37,.35);
    box-shadow: 0 2px 4px rgba(59,30,20,.05), 0 26px 50px -24px rgba(142,0,30,.42);
}

/* Gradient hairline across the top edge. Painted with background-size so it
   can never escape the card's rounded box. */
.card--accent {
    background-image: var(--grad-line), linear-gradient(var(--surface), var(--surface));
    background-size: 100% 4px, 100% 100%;
    background-repeat: no-repeat;
    background-position: top left, top left;
}

/* Frosted glass — used only where there is genuinely a gradient behind it to
   blur. Over a flat surface it is invisible and just costs paint time. */
.glass {
    background: var(--glass-bg);
    border: 1px solid var(--glass-brd);
    -webkit-backdrop-filter: saturate(160%) blur(18px);
    backdrop-filter: saturate(160%) blur(18px);
    box-shadow: var(--glass-shadow);
    border-radius: var(--r-lg);
}

.card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 52px; height: 52px;
    margin-bottom: 1.1rem;
    border-radius: var(--r-md);
    background: var(--grad-cta);
    color: #FFFFFF;
    box-shadow: 0 8px 20px -10px rgba(177,0,37,.65);
}
.card__icon svg { width: 25px; height: 25px; }

.card h3 { margin-bottom: .5rem; }
.card p { color: var(--fg-muted); font-size: .9688rem; margin-bottom: 0; }

/* A link that reveals an arrow on hover. */
.card__link {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    margin-top: 1.25rem;
    font-weight: 600;
    font-size: .9375rem;
    color: var(--crimson);
}

/* Cards that carry a link become a vertical stack so the link can be pushed
   to the bottom edge. It used to sit in normal flow right after the
   paragraph, so on equal-height cards the "Read more" links landed at
   different heights depending on how long the copy above them ran — 26px
   apart on the three approach cards. Scoped with :has() so the sixty-odd
   other .card instances keep their existing block layout untouched. */
.card:has(.card__link) { display: flex; flex-direction: column; }

.card:has(.card__link) .card__link {
    margin-top: auto;
    /* margin-top:auto swallows all the free space, which would leave nothing
       between the copy and the link on the tallest card. Padding guarantees a
       floor; align-self keeps the link at its natural width instead of
       stretching to the full card — a flex item defaults to stretch, which
       would strand the arrow at the far right. */
    padding-top: 1.25rem;
    align-self: flex-start;
}
/* Every other inline SVG in this file sets both dimensions. This one set only
   width, so the arrow fell back to the 150px default height for a replaced
   element and stretched the link's box to 170px — the text sat at the top of
   it, leaving a pocket of dead space inside the card. */
.card__link svg { width: 16px; height: 16px; flex: none; transition: transform var(--t-fast) var(--ease); }
.card__link:hover svg { transform: translateX(4px); }


/* ==========================================================================
   9. STATS / COUNTERS
   ========================================================================== */

.stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
    gap: 1px;
    padding: clamp(1.5rem, 4vw, 2.5rem);
    border-radius: var(--r-xl);
    background-image: var(--grad-line), var(--grad-soft);
    background-size: 100% 4px, 100% 100%;
    background-repeat: no-repeat;
    background-position: top left, top left;
    border: 1px solid var(--brd);
    box-shadow: 0 1px 2px rgba(59,30,20,.04), 0 22px 44px -30px rgba(59,30,20,.40);
}

.stat { text-align: center; padding: 1.25rem .75rem; position: relative; }

/* Divider between stats, suppressed on the first of each row. */
.stat + .stat::before {
    content: "";
    position: absolute;
    left: 0; top: 18%; bottom: 18%;
    width: 1px;
    background: var(--brd);
}
@media (max-width: 700px) { .stat + .stat::before { display: none; } }

.stat__num {
    display: block;
    font-family: 'Inter', sans-serif;
    font-size: clamp(2.25rem, 1.6rem + 2.4vw, 3.25rem);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -.03em;
    background-image: var(--grad-text);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    font-variant-numeric: tabular-nums;
}

.stat__label {
    display: block;
    margin-top: .6rem;
    font-size: .875rem;
    font-weight: 500;
    color: var(--fg-muted);
}

/* Unverified figures must be impossible to publish by accident. */
.stat__flag { color: var(--crimson); font-weight: 700; }

.stats__notice {
    grid-column: 1 / -1;
    margin-top: 1rem;
    padding: .875rem 1.1rem;
    border-radius: var(--r-md);
    background: var(--grad-soft);
    border: 1px dashed rgba(177,0,37,.45);
    font-size: .875rem;
    color: var(--fg-muted);
    text-align: center;
}


/* ==========================================================================
   10. RESULTS TIMELINE
   ========================================================================== */

.results { position: relative; padding-left: 2.25rem; }

/* The spine. */
.results::before {
    content: "";
    position: absolute;
    left: 7px; top: .6rem; bottom: .6rem;
    width: 3px;
    border-radius: var(--r-pill);
    background: var(--grad-line);
    opacity: .55;
}

.result { position: relative; padding-bottom: 2.25rem; }
.result:last-child { padding-bottom: 0; }

/* Node on the spine. */
.result::before {
    content: "";
    position: absolute;
    left: -2.25rem;
    top: .35rem;
    width: 17px; height: 17px;
    border-radius: 50%;
    background: var(--surface);
    border: 3px solid var(--crimson);
    box-shadow: 0 0 0 4px var(--bg);
}
.section--alt .result::before { box-shadow: 0 0 0 4px var(--bg-alt); }

.result__year {
    display: inline-block;
    margin-bottom: .5rem;
    padding: .3rem 1rem;
    border-radius: var(--r-pill);
    background: var(--grad-cta);
    color: #FFFFFF;
    font-family: 'Inter', sans-serif;
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.result p { color: var(--fg-muted); margin: 0; max-width: 52rem; }
.result p strong { color: var(--fg); }


/* ==========================================================================
   11. TESTIMONIAL CAROUSEL — swipeable, autoplay, pauses on hover
   ========================================================================== */

.carousel { position: relative; }

.carousel__viewport {
    overflow: hidden;
    /* Room for the card shadows, which would otherwise be clipped. */
    margin-inline: -1rem;
    padding: 1rem;
    cursor: grab;
}
.carousel__viewport.is-dragging { cursor: grabbing; }

.carousel__track {
    display: flex;
    gap: 1.5rem;
    /* JS drives this; CSS only supplies the easing. */
    transition: transform var(--t-slow) var(--ease);
}
.carousel__track.is-instant { transition: none; }

.tcard {
    flex: 0 0 clamp(17rem, 82vw, 25rem);
    display: flex;
    flex-direction: column;
    padding: clamp(1.5rem, 3vw, 2rem);
    border-radius: var(--r-lg);
    background: var(--glass-bg);
    border: 1px solid var(--glass-brd);
    -webkit-backdrop-filter: saturate(160%) blur(18px);
    backdrop-filter: saturate(160%) blur(18px);
    box-shadow: var(--glass-shadow);
    /* Text must not be selectable mid-drag or the swipe fights the highlight. */
    -webkit-user-select: none;
    user-select: none;
}

.tcard__mark {
    font-family: 'Inter', sans-serif;
    font-size: 2.5rem;
    line-height: 1;
    font-weight: 800;
    background-image: var(--grad-text);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    margin-bottom: .5rem;
}

.tcard__quote {
    flex: 1;
    font-size: .9688rem;
    line-height: 1.7;
    color: var(--fg-muted);
    margin-bottom: 1.25rem;
}

.tcard__who {
    padding-top: 1rem;
    border-top: 1px solid var(--brd);
    font-size: .875rem;
    font-weight: 600;
    color: var(--fg);
}

/* Collapsed long quotes: six lines, then an ellipsis. The button is added
   by JS only when the text actually overflows, so short quotes never get
   one and card heights converge without touching a word. */
.tcard__quote--clamp {
    display: -webkit-box;
    -webkit-line-clamp: 6;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.tcard__more {
    align-self: flex-start;
    background: none;
    border: 0;
    padding: .5rem 0 0;
    font: inherit;
    font-size: .875rem;
    font-weight: 600;
    color: var(--crimson);
    cursor: pointer;
}
.tcard__more:hover { text-decoration: underline; }

.carousel__controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .75rem;
    margin-top: 2rem;
}

.cbtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px; height: 48px;
    border-radius: 50%;
    border: 1px solid var(--brd-strong);
    background: var(--surface);
    color: var(--fg);
    cursor: pointer;
    transition: background var(--t-fast) var(--ease),
                color var(--t-fast) var(--ease),
                border-color var(--t-fast) var(--ease),
                transform var(--t-fast) var(--ease);
}
.cbtn:hover {
    background: var(--grad-deco);
    border-color: transparent;
    color: #FFFFFF;
    transform: translateY(-2px);
}
.cbtn svg { width: 18px; height: 18px; }

.carousel__dots { display: flex; gap: .45rem; margin-inline: .5rem; }
.cdot {
    width: 9px; height: 9px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--brd-strong);
    cursor: pointer;
    transition: background var(--t-fast) var(--ease), width var(--t-fast) var(--ease);
}
.cdot.is-active { width: 26px; border-radius: var(--r-pill); background: var(--grad-deco); }


/* ==========================================================================
   12. PRICING CARDS
   ========================================================================== */

.price {
    display: flex;
    flex-direction: column;
    padding: clamp(1.5rem, 3vw, 2.25rem);
    border-radius: var(--r-lg);
    background: var(--surface);
    border: 1px solid var(--brd);
    box-shadow: 0 1px 2px rgba(59,30,20,.04), 0 14px 30px -22px rgba(59,30,20,.30);
    transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease);
}
.price:hover {
    transform: translateY(-6px);
    box-shadow: 0 2px 4px rgba(59,30,20,.05), 0 28px 52px -26px rgba(142,0,30,.40);
}

/* The featured plan is dark, so it reads first without needing a badge. */
.price--featured {
    background: var(--grad-brand);
    border-color: transparent;
    color: #FFFFFF;
}
.price--featured h3,
.price--featured .price__amount { color: #FFFFFF; }
.price--featured .price__meta,
.price--featured .price__list li { color: rgba(255,255,255,.86); }
.price--featured .price__list li::before { background: rgba(255,255,255,.85); }
.price--featured .price__list li { border-color: rgba(255,255,255,.16); }

.price__badge {
    align-self: flex-start;
    margin-bottom: 1rem;
    padding: .3rem .85rem;
    border-radius: var(--r-pill);
    background: rgba(255,255,255,.16);
    border: 1px solid rgba(255,255,255,.28);
    font-family: 'Inter', sans-serif;
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.price__amount {
    font-family: 'Inter', sans-serif;
    font-size: clamp(2.25rem, 1.7rem + 2vw, 3rem);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -.03em;
    color: var(--fg);
    margin-bottom: .35rem;
}
.price__amount span { font-size: .4375em; font-weight: 600; letter-spacing: 0; }

.price__meta { font-size: .875rem; color: var(--fg-muted); margin-bottom: 1.5rem; }

.price__list { list-style: none; padding: 0; margin: 0 0 1.75rem; flex: 1; }
.price__list li {
    position: relative;
    padding: .6rem 0 .6rem 1.6rem;
    font-size: .9375rem;
    color: var(--fg-muted);
    border-bottom: 1px solid var(--brd);
}
.price__list li:last-child { border-bottom: 0; }
.price__list li::before {
    content: "";
    position: absolute;
    left: 0; top: 1.15rem;
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--grad-cta);
}


/* ==========================================================================
   13. FLOATING CTA
   ========================================================================== */

.fab {
    position: fixed;
    right: clamp(1rem, 3vw, 2rem);
    bottom: clamp(1rem, 3vw, 2rem);
    z-index: 180;
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    padding: .9rem 1.4rem;
    border-radius: var(--r-pill);
    background-image: var(--grad-cta);
    color: #FFFFFF;
    font-family: 'Inter', sans-serif;
    font-size: .9375rem;
    font-weight: 600;
    box-shadow: 0 10px 30px -10px rgba(177,0,37,.75);
    /* Hidden until the hero is behind us, so it doesn't fight the hero CTA. */
    opacity: 0;
    visibility: hidden;
    transform: translateY(14px);
    transition: opacity var(--t-base) var(--ease),
                transform var(--t-base) var(--ease),
                visibility var(--t-base),
                box-shadow var(--t-base) var(--ease);
}
.fab.is-visible { opacity: 1; visibility: visible; transform: translateY(0); }
.fab:hover {
    color: #FFFFFF;
    transform: translateY(-3px);
    box-shadow: 0 16px 38px -12px rgba(177,0,37,.85);
}
.fab svg { width: 18px; height: 18px; }

@media (max-width: 560px) {
    .fab { right: 1rem; bottom: 1rem; padding: .85rem 1.1rem; }
    .fab__label { display: none; }
}


/* ==========================================================================
   14. FOOTER
   ========================================================================== */

.footer {
    position: relative;
    padding-block: clamp(3rem, 7vw, 5rem) 2rem;
    background: var(--grad-brand);
    color: rgba(255,255,255,.82);
}
.footer::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 4px;
    background: var(--grad-line);
}

.footer h4 {
    color: #FFFFFF;
    font-size: .8125rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    margin-bottom: 1.1rem;
}

.footer a { color: rgba(255,255,255,.86); }
.footer a:hover { color: #FFFFFF; text-decoration: underline; }

/* The logo file carries a white background, so it gets the same white
   badge as the nav — otherwise it would be a floating white rectangle
   on the dark footer. */
.footer__grid > div:first-child img {
    background: #FFFFFF;
    padding: .4rem 1rem;
    border-radius: 12px;
}

.footer__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
    gap: 2.5rem;
    margin-bottom: 3rem;
}

.footer__list { list-style: none; padding: 0; margin: 0; }
.footer__list li { margin-bottom: .6rem; font-size: .9375rem; }

.footer__bottom {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: center;
    justify-content: space-between;
    padding-top: 1.75rem;
    border-top: 1px solid rgba(255,255,255,.16);
    font-size: .875rem;
    /* Warm ivory text on the deep espresso footer — .82 clears 4.5:1. */
    color: rgba(255,255,255,.82);
}


/* ==========================================================================
   15. CONTACT / FORMS
   ========================================================================== */

.form { display: grid; gap: 1.25rem; }
.form__row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: 1.25rem; }

.field { display: flex; flex-direction: column; gap: .45rem; }
.field label {
    font-size: .875rem;
    font-weight: 600;
    color: var(--fg);
}
.field input,
.field select,
.field textarea {
    width: 100%;
    min-height: 48px;
    padding: .75rem .95rem;
    font: inherit;
    font-size: .9375rem;
    color: var(--fg);
    background: var(--surface);
    border: 1px solid var(--brd-strong);
    border-radius: var(--r-md);
    transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.field textarea { min-height: 150px; resize: vertical; }
.field input:focus,
.field select:focus,
.field textarea:focus {
    outline: none;
    border-color: var(--crimson);
    box-shadow: 0 0 0 4px rgba(177,0,37,.18);
}

/* Radio pairs, matching the client's existing "Yes / No" style questions. */
.radios { display: flex; flex-wrap: wrap; gap: .6rem; }
.radio {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    min-height: 42px;
    padding: .5rem 1rem;
    border: 1px solid var(--brd-strong);
    border-radius: var(--r-md);
    font-size: .875rem;
    cursor: pointer;
    transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.radio:hover { border-color: var(--crimson); }
.radio input { accent-color: var(--crimson); width: 15px; height: 15px; margin: 0; }
.radio:has(input:checked) { border-color: var(--crimson); background: var(--grad-soft); }

/* CF7-rendered radios mirror .radio (CF7 emits its own list-item markup,
   so these duplicate the geometry deliberately). The .wpcf7 prefix outranks
   the plugin's own .wpcf7-list-item rule (margin-left indent). */
.wpcf7 .wpcf7-list-item {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    min-height: 42px;
    padding: .5rem 1rem;
    margin: 0 .6rem .6rem 0;
    border: 1px solid var(--brd-strong);
    border-radius: var(--r-md);
    font-size: .875rem;
    cursor: pointer;
    transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.wpcf7 .wpcf7-list-item input { accent-color: var(--crimson); width: 15px; height: 15px; margin: 0; }
.wpcf7 .wpcf7-list-item:has(input:checked) { border-color: var(--crimson); background: var(--grad-soft); }
.wpcf7-form-control-wrap { display: block; }
.wpcf7-response-output { border-radius: var(--r-md) !important; }
/* Consent row (feedback form): a real label wrapping the CF7 acceptance
   checkbox, since CF7 4.x drops the tag's inner content. */
.consent {
    display: flex;
    gap: .65rem;
    align-items: flex-start;
    font-size: .875rem;
    line-height: 1.6;
    color: var(--fg-muted);
    cursor: pointer;
}
.consent input[type="checkbox"] {
    width: 18px;
    height: 18px;
    margin-top: .2rem;
    flex-shrink: 0;
    accent-color: var(--crimson);
}

/* Animated success state: light-green circle drawing itself, then the tick.
   Shown by the wpcf7mailsent hook; hidden attribute keeps it out until then. */
.form-success { text-align: center; padding: 2.5rem 1rem; }
.form-success[hidden] { display: none; }
.tick { width: 88px; height: 88px; margin: 0 auto 1.25rem; display: block; }
.tick circle {
    fill: none; stroke: #22c55e; stroke-width: 4;
    stroke-dasharray: 178; stroke-dashoffset: 178;
    animation: tick-circle .6s ease forwards;
}
.tick path {
    fill: none; stroke: #22c55e; stroke-width: 5;
    stroke-linecap: round; stroke-linejoin: round;
    stroke-dasharray: 48; stroke-dashoffset: 48;
    animation: tick-mark .4s ease .5s forwards;
}
@keyframes tick-circle { to { stroke-dashoffset: 0; } }
@keyframes tick-mark { to { stroke-dashoffset: 0; } }
.form-success h3 { font-size: 1.75rem; margin-bottom: .5rem; }
.form-success p { color: var(--fg-muted); margin: 0; }

.notice {
    padding: 1rem 1.25rem;
    border-radius: var(--r-md);
    background: var(--grad-soft);
    border: 1px solid rgba(177,0,37,.30);
    font-size: .9375rem;
    color: var(--fg);
}
.notice strong { color: var(--fg); }

.contact-cards { display: grid; gap: 1rem; }
.contact-card {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1.1rem 1.25rem;
    border-radius: var(--r-md);
    background: var(--surface);
    border: 1px solid var(--brd);
    transition: border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.contact-card:hover { border-color: var(--crimson); transform: translateX(3px); }
.contact-card svg { width: 20px; height: 20px; flex-shrink: 0; color: var(--crimson); }
/* WhatsApp cards: green icon and hover edge so the channel is recognisable
   at a glance. Tapping opens a chat via wa.me, no app install page. */
.contact-card--wa svg { color: #25D366; }
.contact-card--wa:hover { border-color: #25D366; }
.contact-card strong { display: block; font-size: .8125rem; color: var(--fg-muted); font-weight: 500; }
.contact-card span { font-weight: 600; color: var(--fg); }


/* ==========================================================================
   16. SCROLL REVEAL
   --------------------------------------------------------------------------
   Elements start hidden only when JS is present to reveal them — the `.js`
   class is set on <html> by an inline script in <head>, so if scripting is
   off or fails, nothing is ever hidden. That ordering matters: hide first and
   you have built a page that is blank for anyone whose JS breaks.
   ========================================================================== */

.js [data-reveal] {
    opacity: 0;
    transform: translateY(26px);
    transition: opacity 700ms var(--ease), transform 700ms var(--ease);
    transition-delay: var(--reveal-delay, 0ms);
    will-change: opacity, transform;
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

.js [data-reveal="left"]  { transform: translateX(-32px); }
.js [data-reveal="right"] { transform: translateX(32px); }
.js [data-reveal="scale"] { transform: scale(.94); }
.js [data-reveal="left"].is-in,
.js [data-reveal="right"].is-in,
.js [data-reveal="scale"].is-in { transform: none; }


/* ==========================================================================
   17. PHOTOGRAPHY
   --------------------------------------------------------------------------
   Real client photographs, presented plainly: rounded frame, thin gold keyline
   (decorative — the logo's gold is not a text colour), soft warm shadow.
   No filters, no duotone washes. These are documentary images; heavy
   treatment would make them look like stock, which is what we are moving
   away from.
   ========================================================================== */

.photo {
    position: relative;
    margin: 0;
    overflow: hidden;
    border-radius: var(--r-lg);
    border: 1px solid rgba(192,172,121,.55);
    box-shadow: 0 1px 2px rgba(59,30,20,.08), 0 24px 48px -24px rgba(59,30,20,.35);
    background: var(--surface-2);
}
.photo img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 16 / 10; }
.photo__caption {
    position: absolute;
    left: 1rem; right: 1rem; bottom: 1rem;
    padding: .7rem 1rem;
    border-radius: var(--r-md);
    background: rgba(26,12,10,.62);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255,255,255,.16);
    color: #FFFFFF;
    font-size: .8125rem;
    font-weight: 500;
}

/* Embedded location map, in the same framed language as the photographs:
   rounded, gold keyline, warm shadow. The iframe is Google's no-key embed
   of the client's postcode (SM3 9RR), as the live site had. */
.map {
    position: relative;
    margin: 0;
    overflow: hidden;
    border-radius: var(--r-lg);
    border: 1px solid rgba(192,172,121,.55);
    box-shadow: 0 1px 2px rgba(59,30,20,.08), 0 24px 48px -24px rgba(59,30,20,.35);
    background: var(--surface-2);
}
.map iframe {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 10;
    border: 0;
}
/* Taller crop for the narrow contact sidebar, so the map stays usable. */
.map--tall iframe { aspect-ratio: 4 / 3; }
.map__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem 1rem;
    padding: .85rem 1.25rem;
    background: var(--surface);
    border-top: 1px solid var(--brd);
    font-size: .875rem;
}
.map__foot strong { color: var(--fg); font-weight: 600; }
.map__foot a { font-weight: 600; }

/* Portrait variant — narrower than the column so a 3:4 photograph doesn't
   tower over the text beside it, with the crimson-to-gold brand strip across
   the top edge tying it into the card system. */
.photo--portrait { max-width: 22rem; margin-inline: auto; width: 100%; }
.photo--portrait img { aspect-ratio: 3 / 4; object-position: top center; }

/* The portrait is a studio headshot against a pure white sweep. The frame is
   the photograph's own 3:4 ratio, so object-fit: cover crops nothing at all —
   the entire sweep is on show, and the panel reads as a hard white rectangle
   sitting inside the gold keyline. Over ivory that is merely crisp; over the
   dark theme's espresso it is a light source, and it was the brightest thing
   on the page.

   This stays a theme adaptation rather than a grade, because the rule for
   this section is that documentary photographs go untreated. The sweep is
   taken down only as far as it needs to sit as a warm ivory panel: sepia
   warms what brightness removes, and the saturate() that follows puts back
   the colour sepia's desaturation takes out of the skin, hair and navy suit. */
[data-theme="dark"] .photo--portrait img {
    filter: brightness(.72) sepia(.10) saturate(1.20) contrast(1.03);
}
.photo--portrait::after {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 4px;
    background: var(--grad-line);
    z-index: 1;
}

/* Full-bleed photo band with a warm scrim — the closing CTA. The photograph
   does the talking; the scrim keeps the white headline readable. */
.band {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    border-radius: var(--r-xl);
    background: #2A1A12 url('assets/img/campus.jpg') center / cover no-repeat;
    text-align: center;
    padding: clamp(3rem, 7vw, 5rem) clamp(1.5rem, 5vw, 3rem);
}
.band::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    background: linear-gradient(180deg, rgba(26,12,10,.78) 0%, rgba(26,12,10,.62) 55%, rgba(26,12,10,.82) 100%);
}
[data-theme="dark"] .band::before {
    background: linear-gradient(180deg, rgba(18,8,6,.84) 0%, rgba(18,8,6,.70) 55%, rgba(18,8,6,.88) 100%);
}
.band > * { position: relative; z-index: 1; }
.band h2 { color: #FFFFFF; margin-bottom: .5rem; }
.band p { color: rgba(255,255,255,.88); max-width: 34rem; margin-inline: auto; }


/* ==========================================================================
   18. PAGE TRANSITIONS
   --------------------------------------------------------------------------
   View Transitions API where supported. Chrome/Edge/Safari get a cross-fade;
   Firefox simply navigates normally, which is the correct fallback — no
   half-applied animation.
   ========================================================================== */

@view-transition { navigation: auto; }

::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: 320ms;
    animation-timing-function: cubic-bezier(.22, 1, .36, 1);
}

/* The header persists across navigations so it does not flicker. */
.nav { view-transition-name: site-nav; }


/* ==========================================================================
   19. ACCESSIBILITY
   ========================================================================== */

.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;
    top: -100px;
    left: 1rem;
    z-index: 999;
    padding: .8rem 1.25rem;
    border-radius: var(--r-md);
    background: var(--surface);
    color: var(--fg);
    font-weight: 600;
    box-shadow: var(--glass-shadow);
    transition: top var(--t-fast) var(--ease);
}
.skip-link:focus { top: 1rem; }

/* Respect the OS setting. Everything still works; it just stops moving. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }
    .js [data-reveal] { opacity: 1 !important; transform: none !important; }
    .card--lift:hover, .price:hover, .btn:hover, .fab:hover { transform: none !important; }
    ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}

/* Print: drop the decoration, keep the information. */
@media print {
    .nav, .fab, .carousel__controls { display: none !important; }
    body { background: #fff; color: #000; }
    .hero, .pagehead, .footer { background: none !important; color: #000 !important; }
    .hero h1, .pagehead h1 { color: #000 !important; }
}
