/* ==========================================================================
   TerraVenti Construction - static site stylesheet
   Mobile-first. Single stylesheet, no framework: the design is bespoke, so a
   grid framework would be overridden more than used.

   Order: tokens -> reset -> layout primitives -> header -> components ->
          footer -> utilities -> motion/print.
   ========================================================================== */

/* --- Design tokens -------------------------------------------------------
   Palette and type are taken from the live Elementor global kit so the
   rebuild keeps the brand exactly. */
:root {
    --accent: #B54539;
    --accent-dark: #8E3529;
    /* Terracotta at 2.0:1 on charcoal fails AA, so the footer uses a lighter
       tint of the same hue (4.8:1) for headings and icons on dark ground. */
    --accent-on-dark: #E9A08F;
    --cta: #B13906;
    --gold: #FCBB01;

    --ink: #1C1C1C;
    --charcoal: #3D3D3D;
    --slate: #54595F;
    --muted: #6E6E6E;      /* WCAG AA on white and cream; #7A7A7A was 4.29:1 */
    --line: #E4E0DD;
    --cream: #FBF7F5;
    --white: #FFFFFF;

    --font-heading: 'Montserrat', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --font-body: 'Roboto', system-ui, -apple-system, 'Segoe UI', sans-serif;

    /* Fluid type: scales between the mobile and desktop bounds with no
       breakpoint jumps. */
    --step-lede: clamp(1.05rem, 0.95rem + 0.5vw, 1.3rem);
    --step-h3: clamp(1.15rem, 1.05rem + 0.5vw, 1.4rem);
    --step-h2: clamp(1.6rem, 1.3rem + 1.4vw, 2.5rem);
    --step-h1: clamp(2rem, 1.5rem + 2.6vw, 3.6rem);

    --shell: 1200px;          /* max content width */
    --gutter: clamp(1.15rem, 4vw, 2.5rem);
    --section-y: clamp(3rem, 7vw, 6rem);

    --radius: 4px;
    --radius-lg: 10px;
    --shadow: 0 2px 8px rgba(0, 0, 0, .07), 0 12px 32px rgba(0, 0, 0, .09);
    --header-h: 72px;
}

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

html {
    /* scroll-padding keeps anchored headings clear of the sticky header. */
    scroll-padding-top: calc(var(--header-h) + 1rem);
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--white);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 1rem;
    line-height: 1.7;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-heading);
    line-height: 1.18;
    margin: 0 0 .6em;
    font-weight: 700;
    letter-spacing: -.01em;
}

h1 { font-size: var(--step-h1); }
h2 { font-size: var(--step-h2); }
h3 { font-size: var(--step-h3); }

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

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--accent-dark); }

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

ul { margin: 0; padding: 0; }

/* Visible keyboard focus everywhere - never removed, only restyled. */
:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 2px;
    border-radius: 2px;
}

/* --- Layout primitives --------------------------------------------------- */
.shell {
    width: 100%;
    max-width: var(--shell);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.section { padding-block: var(--section-y); }
.section--cream { background: var(--cream); }
.section--dark { background: var(--charcoal); color: var(--white); }
.section--dark h1, .section--dark h2, .section--dark h3 { color: var(--white); }

.section-eyebrow {
    font-family: var(--font-heading);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--accent);
    margin: 0 0 .5rem;
}

.section-head { margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }
.section-head p { color: var(--muted); max-width: 62ch; }

/* Skip link: offscreen until focused. */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 200;
    background: var(--accent);
    color: var(--white);
    padding: .75rem 1.25rem;
    font-weight: 600;
}
.skip-link:focus { left: .5rem; top: .5rem; color: var(--white); }

/* --- Buttons ------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .8rem 1.6rem;
    border: 2px solid transparent;
    border-radius: var(--radius);
    font-family: var(--font-heading);
    font-size: .82rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    transition: background-color .18s ease, color .18s ease, transform .18s ease;
}
.btn:hover { transform: translateY(-1px); }

.btn--primary { background: var(--cta); color: var(--white); }
.btn--primary:hover { background: var(--accent-dark); color: var(--white); }

.btn--ghost { background: transparent; color: var(--white); border-color: rgba(255,255,255,.65); }
.btn--ghost:hover { background: var(--white); color: var(--ink); }

.btn--outline { background: transparent; color: var(--accent); border-color: var(--accent); }
.btn--outline:hover { background: var(--accent); color: var(--white); }
/* Large button variant, and the arrow that ships with it. */
.btn--lg { padding: 1.05rem 2.1rem; font-size: .9rem; }

/* --- Header / navigation -------------------------------------------------
   Mobile/tablet (<1100px): an off-canvas drawer that slides in from the right
   over a dimmed backdrop. Desktop (>=1100px): a plain inline row.

   1100px is not arbitrary - the full row (logo + page links + three branch
   links + CTA) overflows below it, so tablets keep the drawer. This literal is
   duplicated in site.js and the two MUST stay in sync.

   Progressive enhancement: the drawer styles are scoped to .js, which site.js
   sets on <html>. With JavaScript off the nav renders as an ordinary stacked
   block that is still fully reachable, rather than a panel stuck off-screen. */
.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    /* NOTE: no backdrop-filter here. It would make .site-header the containing
       block for its position:fixed descendants, clamping the nav drawer and its
       backdrop to the 72px header box instead of the viewport. A solid
       background gives the same look without that side effect. */
    background: var(--white);
    border-bottom: 1px solid var(--line);
}

.site-header__bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-height: var(--header-h);
}

.site-logo { display: inline-flex; align-items: center; flex: 0 0 auto; }
.site-logo img { width: min(190px, 46vw); height: auto; }

/* --- Hamburger button --- */
.nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;                 /* 44px minimum touch target */
    height: 44px;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--white);
    cursor: pointer;
    flex: 0 0 auto;
}
.nav-toggle__bars, .nav-toggle__bars::before, .nav-toggle__bars::after {
    display: block;
    width: 20px;
    height: 2px;
    background: var(--ink);
    border-radius: 2px;
}
.nav-toggle__bars { position: relative; }
.nav-toggle__bars::before, .nav-toggle__bars::after { content: ""; position: absolute; left: 0; }
.nav-toggle__bars::before { top: -6px; }
.nav-toggle__bars::after { top: 6px; }

/* --- Backdrop --- */
.nav-backdrop {
    position: fixed;
    inset: 0;
    z-index: 110;
    background: rgba(0, 0, 0, .55);
    opacity: 0;
    visibility: hidden;
    transition: opacity .28s ease, visibility .28s ease;
    cursor: pointer;
}
.nav-backdrop.is-open { opacity: 1; visibility: visible; }

/* --- Drawer close button (inside the panel) --- */
.nav-close {
    position: absolute;
    top: 1rem;
    right: 1rem;
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--white);
    cursor: pointer;
}
.nav-close svg { width: 16px; height: 16px; fill: var(--ink); }

/* --- Shared list styling (both drawer and desktop row) --- */
.site-nav__list { list-style: none; display: flex; flex-direction: column; gap: .1rem; }

.site-nav__link {
    display: block;
    padding: .85rem .25rem;
    font-family: var(--font-heading);
    font-size: .95rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ink);
    text-decoration: none;
    border-bottom: 1px solid var(--line);
}
.site-nav__link:hover { color: var(--accent); }
/* aria-current marks the active page for sighted users and AT alike. */
.site-nav__link[aria-current="page"] { color: var(--accent); }

.site-nav__group-label {
    margin: 1.75rem 0 .5rem;
    font-family: var(--font-heading);
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--muted);
}

.site-nav__branches { list-style: none; display: flex; flex-direction: column; gap: .1rem; }
.site-nav__branches a {
    display: block;
    padding: .7rem .25rem;
    font-family: var(--font-heading);
    font-size: .85rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--slate);
    text-decoration: none;
    border-bottom: 1px solid var(--line);
}
.site-nav__branches a:hover { color: var(--accent); }
.site-nav__branches a[aria-current="page"] { color: var(--accent); }

/* --- "Locations" disclosure ----------------------------------------------
   One component, two presentations: an accordion inside the mobile drawer and
   an absolutely-positioned dropdown on desktop. site.js only toggles
   aria-expanded + .is-open; everything visual is here. */
.nav-dropdown { position: relative; }

.nav-dropdown__toggle {
    display: flex;
    align-items: center;
    gap: .5rem;
    width: 100%;
    padding: .85rem .25rem;
    border: 0;
    border-bottom: 1px solid var(--line);
    background: none;
    font-family: var(--font-heading);
    font-size: .95rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ink);
    cursor: pointer;
    text-align: left;
}
.nav-dropdown__toggle:hover { color: var(--accent); }

/* The active branch, shown next to the label so the current location is
   obvious without opening the menu. */
.nav-dropdown__current {
    margin-left: auto;
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .04em;
    color: var(--accent);
    text-transform: none;
}

.nav-dropdown__caret {
    width: 18px;
    height: 18px;
    fill: currentColor;
    flex: 0 0 auto;
    transition: transform .2s ease;
}
.nav-dropdown__toggle[aria-expanded="true"] .nav-dropdown__caret { transform: rotate(180deg); }

/* Split control: label is a link to the hub, caret is a separate toggle. */
.nav-dropdown--split { display: flex; align-items: center; }

.nav-dropdown__link {
    flex: 1 1 auto;
    display: block;
    padding: .85rem .25rem;
    font-family: var(--font-heading);
    font-size: .95rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ink);
    text-decoration: none;
}
.nav-dropdown__link:hover { color: var(--accent); }
.nav-dropdown__link[aria-current="page"] { color: var(--accent); }

.nav-dropdown__caret-btn {
    flex: 0 0 auto;
    width: 44px;               /* full touch target in the drawer */
    height: 44px;
    display: grid;
    place-items: center;
    border: 0;
    background: none;
    cursor: pointer;
    color: var(--ink);
}
.nav-dropdown__caret-btn:hover { color: var(--accent); }
.nav-dropdown__caret-btn[aria-expanded="true"] .nav-dropdown__caret { transform: rotate(180deg); }

/* The split control sits on its own row in the drawer, with the menu beneath. */
.nav-dropdown--split { flex-wrap: wrap; border-bottom: 1px solid var(--line); }
.nav-dropdown--split .nav-dropdown__menu { flex: 1 0 100%; }

.nav-dropdown__menu {
    list-style: none;
    display: none;
    padding-left: .9rem;
    border-left: 2px solid var(--line);
    margin: .35rem 0 .35rem .25rem;
}
.nav-dropdown__menu.is-open { display: block; }

.nav-dropdown__menu a {
    display: block;
    padding: .7rem .25rem;
    font-family: var(--font-heading);
    font-size: .85rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--slate);
    text-decoration: none;
}
.nav-dropdown__menu a:hover { color: var(--accent); }
.nav-dropdown__menu a[aria-current="page"] { color: var(--accent); }

.site-nav__cta { margin-top: auto; padding-top: 1.75rem; }
.site-nav__cta .btn { width: 100%; justify-content: center; }

/* --- Drawer (JS enabled, below the desktop breakpoint) --- */
.js .site-nav {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 120;
    /* 82vw leaves a comfortable strip of backdrop to tap out on even on a
       small phone (~70px at 390px wide). */
    width: min(82vw, 340px);
    display: flex;
    flex-direction: column;
    padding: 4.75rem 1.5rem 2rem;
    background: var(--white);
    box-shadow: -10px 0 34px rgba(0, 0, 0, .2);
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateX(101%);
    transition: transform .28s cubic-bezier(.4, 0, .2, 1);
}
.js .site-nav.is-open { transform: translateX(0); }

/* Without JS the nav is a normal block under the header. */
html:not(.js) .nav-close, html:not(.js) .nav-backdrop, html:not(.js) .nav-toggle { display: none; }
html:not(.js) .site-nav { width: 100%; border-top: 1px solid var(--line); padding: 1rem 0 1.5rem; }

/* Lock the page behind the open drawer. */
body.nav-open { overflow: hidden; }

/* --- Desktop --- */
@media (min-width: 1100px) {
    .nav-toggle, .nav-close, .nav-backdrop { display: none; }

    /* Reset every drawer property; the panel becomes an inline row again. */
    .js .site-nav, .site-nav {
        position: static;
        width: auto;
        padding: 0;
        background: none;
        box-shadow: none;
        overflow: visible;
        transform: none;
        transition: none;
        flex-direction: row;
        align-items: center;
        gap: 1.75rem;
    }

    .site-nav__list { flex-direction: row; align-items: center; gap: 1.6rem; }
    .site-nav__link {
        padding: .35rem 0;
        font-size: .85rem;
        letter-spacing: .07em;
        border-bottom: 2px solid transparent;
    }
    .site-nav__link[aria-current="page"] { border-bottom-color: var(--accent); }

    .site-nav__group-label { display: none; }

    .site-nav__branches {
        flex-direction: row;
        gap: 1.1rem;
        padding-left: 1.6rem;
        border-left: 1px solid var(--line);
    }
    .site-nav__branches a { padding: 0; font-size: .74rem; letter-spacing: .08em; border-bottom: 0; }

    /* Locations becomes a real dropdown: inline trigger, floating panel. */
    .nav-dropdown--split { border-bottom: 0; }
    .nav-dropdown__link {
        padding: .35rem 0;
        font-size: .85rem;
        letter-spacing: .07em;
        border-bottom: 2px solid transparent;
    }
    .nav-dropdown__link[aria-current="page"] { border-bottom-color: var(--accent); }
    .nav-dropdown__caret-btn { width: 26px; height: 26px; }

    .nav-dropdown__toggle {
        width: auto;
        padding: .35rem 0;
        font-size: .85rem;
        letter-spacing: .07em;
        border-bottom: 2px solid transparent;
        gap: .35rem;
    }
    .nav-dropdown__current { display: none; }

    .nav-dropdown__menu {
        position: absolute;
        top: calc(100% + .85rem);
        right: 0;
        min-width: 220px;
        padding: .4rem 0;
        margin: 0;
        background: var(--white);
        border: 1px solid var(--line);
        border-left-width: 1px;
        border-radius: var(--radius);
        box-shadow: var(--shadow);
        z-index: 130;
    }
    .nav-dropdown__menu a { padding: .6rem 1.1rem; font-size: .78rem; }
    .nav-dropdown__menu a:hover { background: var(--cream); }

    .site-nav__cta { margin: 0; padding: 0; }
    .site-nav__cta .btn { width: auto; }

    body.nav-open { overflow: visible; }
}

/* --- Hero ---------------------------------------------------------------- */
.hero {
    position: relative;
    display: grid;
    align-items: end;
    min-height: clamp(420px, 66vh, 660px);
    overflow: hidden;
    background: var(--charcoal);
    color: var(--white);
}

.hero__media {
    position: absolute;
    inset: 0;
    z-index: 0;
}
.hero__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* Background video layer. Sits above the poster image but below the scrim,
   so the poster stays visible until the iframe actually starts playing and the
   text keeps its contrast either way.

   An iframe cannot use object-fit, so the usual cover trick is used instead:
   size it to the larger of 16:9-by-width and 16:9-by-height, then centre it. */
.hero__video {
    position: absolute;
    inset: 0;
    z-index: 1;
    overflow: hidden;
    opacity: 0;
    transition: opacity .6s ease;
    pointer-events: none;      /* the hero stays clickable, the video inert */
}
.hero.has-video .hero__video { opacity: 1; }

.hero__video iframe {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 100vw;
    height: 56.25vw;           /* 16:9 by width */
    min-width: 177.78vh;       /* 16:9 by height */
    min-height: 100%;
    transform: translate(-50%, -50%);
    border: 0;
}

/* The scrim must sit above the video, not just the poster. */
.hero__media::after { z-index: 2; }

/* Dark scrim so white type always clears WCAG contrast over any photo. */
.hero__media::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0,0,0,.28) 0%, rgba(0,0,0,.30) 45%, rgba(0,0,0,.72) 100%);
}

.hero__body {
    position: relative;
    z-index: 1;
    padding-block: clamp(2.5rem, 7vw, 4.5rem);
}
.hero h1 { color: var(--white); max-width: 20ch; text-wrap: balance; }
.hero__sub {
    font-size: var(--step-lede);
    color: rgba(255,255,255,.92);
    max-width: 55ch;
    margin-bottom: 1.6rem;
}

.hero--compact { min-height: clamp(240px, 34vh, 360px); }

/* Plain hero: used where no photograph exists for the service yet. A branded
   band reads as deliberate; an unrelated stock photo does not. */
.hero--plain {
    min-height: 0;
    display: block;
    background: var(--charcoal);
    padding-block: clamp(2.5rem, 6vw, 4.5rem);
}
.hero--plain h1 { color: var(--white); max-width: 20ch; }
.hero--plain .hero__sub { max-width: 60ch; }

/* Product hero: for square, shot-on-white product photography, which looks
   wrong cropped to a full-bleed banner behind a dark scrim. The image is shown
   contained beside the copy on the brand's dark ground instead. */
.hero--product {
    min-height: 0;
    display: block;
    background: var(--charcoal);
    padding-block: clamp(2.5rem, 6vw, 4.5rem);
}
.hero--product__inner {
    display: grid;
    gap: clamp(1.5rem, 4vw, 3rem);
    align-items: center;
}
@media (min-width: 850px) {
    .hero--product__inner { grid-template-columns: 1.15fr .85fr; }
}
.hero--product__copy h1 { color: var(--white); max-width: 18ch; }
.hero--product__media {
    background: var(--white);
    border-radius: var(--radius-lg);
    padding: clamp(1rem, 3vw, 2rem);
}
.hero--product__media img {
    width: 100%;
    height: auto;
    max-height: 380px;
    object-fit: contain;   /* never crop a product shot */
}


/* --- Generic card grid ---------------------------------------------------
   auto-fit + minmax gives a responsive grid with no media queries: cards
   reflow from 1 column to 2 to 3 as space allows. */
.grid {
    display: grid;
    gap: clamp(1rem, 2.5vw, 1.75rem);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 290px), 1fr));
}
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); }

/* Odd counts leave a ragged final row on a strict grid, so this uses flex to
   centre the leftovers. flex-grow is 0 and the basis is an exact column width:
   with grow enabled, a trailing row of one or two cards stretched wider than
   the rows above, and since .card__media is a 4:3 box a wider card is a taller
   card - which pushed the body text down on just those cards. */
.grid--center {
    --card-gap: clamp(1rem, 2.5vw, 1.75rem);
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--card-gap);
}
.grid--center > * { flex: 0 1 100%; }

@media (min-width: 620px) {
    .grid--center > * { flex-basis: calc((100% - var(--card-gap)) / 2); }
}
@media (min-width: 960px) {
    .grid--center > * { flex-basis: calc((100% - 2 * var(--card-gap)) / 3); }
}

/* --- Media card (services, projects, branch chooser) --------------------- */
.card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: transform .2s ease, box-shadow .2s ease;
}
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }

/* The image is absolutely positioned so it cannot contribute to the box
   height. With an in-flow child, `height:100%` against an aspect-ratio box is
   circular, the browser resolves it to auto, and a square source stretches the
   card while a landscape one does not - which left the body text starting at
   different heights from card to card. */
.card__media {
    aspect-ratio: 4 / 3;
    background: var(--cream);
    position: relative;
    overflow: hidden;
}
.card__media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Biased above centre: crops more from the bottom of the frame, which
       keeps the subject high and cuts the generator badge some of the older
       AI-generated images carry in the bottom-right corner. */
    object-position: center 38%;
}

.card__body { padding: 1.25rem 1.35rem 1.5rem; display: flex; flex-direction: column; gap: .5rem; flex: 1; }
.card__title { margin: 0; font-size: var(--step-h3); }
.card__text { margin: 0; color: var(--muted); font-size: .94rem; }

/* Placeholder card media, for services awaiting photography. Branded and
   obviously intentional, rather than a borrowed unrelated image. */
.card__media--placeholder {
    background-color: var(--cream);
    background-image:
        linear-gradient(135deg, rgba(255,255,255,.65) 0%, rgba(241,233,230,.65) 100%),
        url("/assets/img/TerraVenti_trans_logo.webp");
    background-repeat: no-repeat, no-repeat;
    background-position: center, center;
    background-size: cover, 56px auto;
    border-bottom: 3px solid var(--accent);
}

/* Whole-card link: the anchor covers the card without nesting interactive
   elements, which keeps the markup valid and the tap target large. */
.card__link { position: absolute; inset: 0; text-indent: -9999px; }

/* Branch chooser card - image with copy overlaid. */
.branch-card { position: relative; min-height: 380px; border-radius: var(--radius-lg); overflow: hidden; display: flex; }
.branch-card img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.branch-card::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0,0,0,.15) 30%, rgba(0,0,0,.82) 100%);
}
.branch-card__body {
    position: relative;
    z-index: 1;
    margin-top: auto;
    padding: 1.5rem;
    color: var(--white);
}
.branch-card__body h3 { color: var(--white); margin-bottom: .4rem; }
.branch-card__body p { font-size: .93rem; color: rgba(255,255,255,.9); margin-bottom: 1rem; }

/* --- Split (image + copy) ------------------------------------------------ */
.split { display: grid; gap: clamp(1.5rem, 4vw, 3rem); align-items: center; }
@media (min-width: 850px) {
    .split { grid-template-columns: 1fr 1fr; }
    .split--reverse .split__media { order: 2; }
}
.split__media img { width: 100%; border-radius: var(--radius-lg); }

/* --- Project gallery -----------------------------------------------------
   Photographs only, no captions (there is no project data yet). Equal-height
   tiles via a fixed aspect ratio, so the row stays balanced whatever the
   source images measure. */
.gallery {
    display: grid;
    gap: clamp(.75rem, 2vw, 1.25rem);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}

.shot {
    margin: 0;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    border-radius: var(--radius-lg);
    background: var(--line);
}
.shot img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .4s ease;
}
.shot:hover img { transform: scale(1.04); }

/* --- Blog ---------------------------------------------------------------- */
.card__meta {
    margin: 0;
    font-family: var(--font-heading);
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--accent);
}

.post__meta {
    font-family: var(--font-heading);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 2rem;
}

/* Long-form post body: a touch more air than the service pages, since these
   are read start to finish rather than scanned. */
.prose h2 { margin-top: 2.25rem; font-size: clamp(1.25rem, 1rem + 1vw, 1.6rem); }
.prose h2:first-of-type { margin-top: 0; }

.post__figure { margin: 2.25rem 0; }
.post__figure img { width: 100%; border-radius: var(--radius-lg); }

/* Closing takeaway, set apart from the body copy. */
.post__takeaway {
    margin-top: 2.5rem;
    padding: 1.25rem 1.4rem;
    background: var(--cream);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius);
    font-size: 1.02rem;
    color: var(--ink);
}

.footer-col__link { margin: .9rem 0 0; }
.footer-col__link a {
    font-family: var(--font-heading);
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    text-decoration: none;
    border-bottom: 1px solid rgba(255, 255, 255, .35);
    padding-bottom: 2px;
}

/* --- Testimonials -------------------------------------------------------- */
.quote {
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 1.75rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}
.quote__text { font-size: .96rem; color: var(--slate); font-style: italic; margin: 0; }
.quote__person { display: flex; align-items: center; gap: .8rem; margin-top: auto; }
.quote__person img { width: 46px; height: 46px; border-radius: 50%; object-fit: cover; flex: 0 0 auto; }
.quote__name { font-family: var(--font-heading); font-weight: 700; font-size: .92rem; }
.quote__place { color: var(--muted); font-size: .82rem; }
.quote__stars { color: var(--gold); letter-spacing: .12em; font-size: .9rem; }

/* --- Video facade --------------------------------------------------------
   A YouTube iframe costs ~1MB and sets third-party cookies on load. We render
   a poster + play button and only swap in the iframe on click (see video.js),
   so nothing contacts YouTube until the visitor asks for it. */
.video {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--charcoal);
    cursor: pointer;
    border: 0;
    padding: 0;
    width: 100%;
    display: block;
}
.video img { width: 100%; height: 100%; object-fit: cover; }
.video iframe { width: 100%; height: 100%; border: 0; }
.video__play {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    background: rgba(0, 0, 0, .3);
    transition: background-color .2s ease;
}
.video:hover .video__play { background: rgba(0, 0, 0, .45); }
.video__play span {
    width: 68px;
    height: 68px;
    border-radius: 50%;
    background: var(--cta);
    display: grid;
    place-items: center;
}
.video__play svg { width: 26px; height: 26px; fill: var(--white); margin-left: 3px; }

/* --- Service page components --------------------------------------------- */

/* Readable measure for long-form copy. */
.prose { max-width: 68ch; }
.prose h2 { margin-top: 0; }
.prose p { color: var(--slate); }

/* "What's included" checklist. */
.ticks { list-style: none; display: grid; gap: .6rem; }
.ticks li {
    position: relative;
    padding-left: 1.9rem;
    color: var(--slate);
    font-size: .96rem;
}
.ticks li::before {
    content: "";
    position: absolute;
    left: 0;
    top: .55em;
    width: 11px;
    height: 6px;
    border-left: 2px solid var(--accent);
    border-bottom: 2px solid var(--accent);
    transform: rotate(-45deg);
}

/* Numbered process steps - counter, so the numbering survives reordering. */
.steps {
    list-style: none;
    counter-reset: step;
    display: grid;
    gap: clamp(1rem, 2.5vw, 1.5rem);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
.step {
    counter-increment: step;
    position: relative;
    padding: 1.5rem 1.35rem 1.35rem;
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
}
.step::before {
    content: counter(step, decimal-leading-zero);
    display: block;
    font-family: var(--font-heading);
    font-size: .82rem;
    font-weight: 700;
    letter-spacing: .1em;
    color: var(--accent);
    margin-bottom: .5rem;
}
.step__title { font-size: 1.02rem; margin-bottom: .4rem; }
.step__text { margin: 0; color: var(--muted); font-size: .93rem; }

/* Options / types grid. Text-only cards, so an odd count reflows without the
   ragged-row problem a media grid has. */
.options {
    display: grid;
    gap: clamp(1rem, 2.5vw, 1.5rem);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}
.option {
    padding: 1.35rem 1.4rem;
    background: var(--white);
    border: 1px solid var(--line);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius);
}
.option__name { font-size: 1.02rem; margin-bottom: .4rem; }
.option__text { margin: 0; color: var(--muted); font-size: .93rem; }

/* FAQs - plain headings and paragraphs, so the text is always visible to
   crawlers and matches the FAQPage schema exactly. */
.faq { padding-block: 1.15rem; border-bottom: 1px solid var(--line); }
.faq:last-child { border-bottom: 0; }
.faq__q { font-size: 1.02rem; margin-bottom: .45rem; }
.faq__a { margin: 0; color: var(--slate); font-size: .95rem; }

/* Cross-links to sibling services. */
.link-list {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    margin-top: 1.25rem;
}
.link-list a {
    display: inline-block;
    padding: .55rem 1.05rem;
    border: 1px solid var(--line);
    border-radius: 100px;
    background: var(--white);
    color: var(--slate);
    font-family: var(--font-heading);
    font-size: .82rem;
    font-weight: 600;
    text-decoration: none;
}
.link-list a:hover { border-color: var(--accent); color: var(--accent); }

/* --- Contact ------------------------------------------------------------- */
.contact-grid { display: grid; gap: clamp(1.75rem, 4vw, 3rem); }
@media (min-width: 1100px) { .contact-grid { grid-template-columns: 1fr 1fr; } }

.field { display: flex; flex-direction: column; gap: .35rem; margin-bottom: 1rem; }
.field label { font-family: var(--font-heading); font-size: .8rem; font-weight: 600; letter-spacing: .04em; }
.field input, .field textarea {
    font: inherit;
    font-size: 1rem;               /* >=16px stops iOS zooming the form on focus */
    padding: .75rem .9rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--white);
    color: var(--ink);
    width: 100%;
}
.field input:focus, .field textarea:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px rgba(181,69,57,.16); }
.field textarea { min-height: 150px; resize: vertical; }

/* Honeypot: hidden from people, visible to naive bots. */
.hp { position: absolute; left: -9999px; opacity: 0; height: 0; overflow: hidden; }

.info-list { list-style: none; display: flex; flex-direction: column; gap: .9rem; }
.info-list li { display: flex; gap: .7rem; align-items: flex-start; }
.info-list svg { width: 18px; height: 18px; fill: var(--accent); flex: 0 0 auto; margin-top: .28rem; }
.info-list a { color: var(--ink); text-decoration: none; }
.info-list a:hover { color: var(--accent); }

.map-embed { border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--line); }
.map-embed iframe { width: 100%; height: 340px; border: 0; display: block; }

/* --- Map facade ----------------------------------------------------------
   The live site embeds a Google Map in every footer column. Each real embed
   pulls ~0.5-1MB of third-party JS and sets cookies, on every page. This
   draws a map-like panel in pure CSS and only injects the real iframe when
   the visitor clicks it (see site.js), so the footer costs nothing on load.
   Ranking-wise nothing is lost: the Business Profile link lives in the
   LocalBusiness JSON-LD "hasMap" property, not in the iframe. */
.map-facade {
    position: relative;
    display: block;
    width: 100%;
    height: 150px;
    margin-top: 1rem;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, .18);
    border-radius: var(--radius);
    overflow: hidden;
    cursor: pointer;
    background-color: #46484A;
    /* Suggestion of streets: two thin light lines crossing a muted ground. */
    background-image:
        linear-gradient(115deg, transparent 46%, rgba(255,255,255,.13) 46%, rgba(255,255,255,.13) 49%, transparent 49%),
        linear-gradient(28deg,  transparent 62%, rgba(255,255,255,.09) 62%, rgba(255,255,255,.09) 64%, transparent 64%),
        linear-gradient(0deg, rgba(0,0,0,.20), rgba(0,0,0,.20));
    transition: border-color .2s ease;
}
.map-facade:hover { border-color: var(--accent-on-dark); }

.map-facade__pin {
    position: absolute;
    top: 42%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 26px;
    height: 26px;
    fill: var(--accent-on-dark);
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .5));
}

.map-facade__label {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: .5rem .7rem;
    background: rgba(0, 0, 0, .55);
    color: var(--white);
    font-family: var(--font-heading);
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-align: center;
}

/* Once clicked the button is replaced by the iframe, which fills the box. */
.map-facade iframe { width: 100%; height: 100%; border: 0; }

/* --- Callout band -------------------------------------------------------- */
.callout { background: var(--charcoal); color: var(--white); text-align: center; }
.callout h2 { color: var(--white); }
.callout p { color: rgba(255,255,255,.85); max-width: 60ch; margin-inline: auto; }
.callout__actions { display: flex; flex-wrap: wrap; gap: .8rem; justify-content: center; margin-top: 1.5rem; }

/* --- Footer -------------------------------------------------------------- */
.site-footer { background: var(--charcoal); color: rgba(255,255,255,.82); padding-block: clamp(2.5rem, 6vw, 4rem) 0; }
.site-footer a { color: rgba(255,255,255,.82); text-decoration: none; }
.site-footer a:hover { color: var(--white); }

.footer-grid { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }
.footer-brand img { width: 60px; height: auto; margin-bottom: 1rem; }
.footer-col h3 { color: var(--accent-on-dark); font-size: 1.05rem; margin-bottom: .8rem; }
.footer-col .info-list svg { fill: var(--accent-on-dark); }
.footer-col .info-list a { color: rgba(255,255,255,.82); }
.footer-col .info-list a:hover { color: var(--white); }

.footer-social { display: flex; gap: 1rem; justify-content: center; padding-block: 1.75rem; }
.footer-social a {
    width: 42px; height: 42px;
    display: grid; place-items: center;
    border: 1px solid rgba(255,255,255,.25);
    border-radius: 50%;
}
.footer-social svg { width: 19px; height: 19px; fill: currentColor; }
.footer-social a:hover { background: var(--accent); border-color: var(--accent); color: var(--white); }

.footer-bottom {
    border-top: 1px solid rgba(255,255,255,.14);
    padding-block: 1.25rem;
    display: flex;
    flex-wrap: wrap;
    gap: .5rem 1.5rem;
    justify-content: space-between;
    font-size: .82rem;
    color: rgba(255,255,255,.6);
}

/* Scroll lock for the lightbox. Deliberately NOT body.nav-open: that class is
   reset to overflow:visible inside the >=1100px nav media query, so on desktop
   the page would scroll behind an open lightbox. */
body.lightbox-open { overflow: hidden; }

/* --- Lightbox -----------------------------------------------------------
   Gallery tiles are <button>s, so they are keyboard reachable and announce
   themselves; the overlay is a single element reused for every image on the
   page. Without this a gallery of thumbnails is just decoration. */
.shot--zoom {
    padding: 0;
    border: 0;
    cursor: zoom-in;
    display: block;
    width: 100%;
}
.shot--zoom::after {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0);
    transition: background-color .2s ease;
}
.shot--zoom { position: relative; }
.shot--zoom:hover::after { background: rgba(0, 0, 0, .12); }

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    padding: clamp(1rem, 4vw, 3rem);
    background: rgba(12, 12, 12, .94);
}
.lightbox[hidden] { display: none; }

.lightbox__figure {
    margin: 0;
    max-width: min(1100px, 100%);
    max-height: 100%;
    display: flex;
    flex-direction: column;
    gap: .9rem;
    align-items: center;
}
.lightbox__img {
    max-width: 100%;
    /* Leave room for the caption and the padding above/below. */
    max-height: calc(100vh - 10rem);
    width: auto;
    height: auto;
    object-fit: contain;
    background: var(--white);
    border-radius: var(--radius);
}
.lightbox__caption {
    color: rgba(255, 255, 255, .82);
    font-size: .88rem;
    text-align: center;
    max-width: 60ch;
}

.lightbox__close,
.lightbox__nav {
    flex: 0 0 auto;
    width: 48px;
    height: 48px;
    display: grid;
    place-items: center;
    border: 1px solid rgba(255, 255, 255, .3);
    border-radius: 50%;
    background: rgba(255, 255, 255, .08);
    color: var(--white);
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
}
.lightbox__close:hover,
.lightbox__nav:hover { background: rgba(255, 255, 255, .2); }

.lightbox__close {
    position: absolute;
    top: clamp(.75rem, 3vw, 1.5rem);
    right: clamp(.75rem, 3vw, 1.5rem);
    font-size: 1.9rem;
}

/* On narrow screens the arrows sit over the image rather than beside it. */
@media (max-width: 700px) {
    .lightbox__nav { position: absolute; top: 50%; transform: translateY(-50%); }
    .lightbox__nav--prev { left: .5rem; }
    .lightbox__nav--next { right: .5rem; }
}

/* --- Utilities ----------------------------------------------------------- */
.visually-hidden {
    position: absolute !important;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}
.text-center { text-align: center; }
.stack > * + * { margin-top: 1rem; }
.lede { font-size: var(--step-lede); color: var(--muted); }

/* --- Motion / print ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

@media print {
    .site-header, .footer-social, .video, .map-embed { display: none; }
    body { color: #000; }
}
