/* =========================================================================
   GM Concept — design system
   Single hand-written stylesheet. No framework, no build step.
   The brand palette is unchanged from the previous site; everything else
   (layout, type, components, motion) is new.
   ---------------------------------------------------------------------
   1. Tokens          5. Header / nav
   2. Reset & base    6. Sections & components
   3. Layout          7. Forms
   4. Typography      8. Footer & floating actions
   ========================================================================= */

/* =========================================================================
   1. TOKENS
   ========================================================================= */
:root {
    /* --- Brand palette (unchanged) ------------------------------------- */
    --champagne:      #CDB489;   /* primary accent / fills */
    --champagne-dark: #B89A62;   /* fill hover */
    --champagne-ink:  #8C6E2C;   /* accent as TEXT on light backgrounds */
    --on-champagne:   #241C0C;   /* text sitting on a champagne fill */
    --charcoal:       #2b2b2b;   /* body copy */
    --ink:            #20242C;   /* dark surface: header, footer, dark bands */
    --ink-deep:       #1a1d23;   /* deepest surface: subfooter, topbar */
    --sand:           #F2EEE9;   /* soft beige panels */

    /* --- Derived neutrals (same hue family) ---------------------------- */
    --sand-deep:  #E8E0D4;
    --line:       #E7E1D8;   /* hairline on light */
    --line-dark:  rgba(255, 255, 255, .12);
    --muted:      #62666E;   /* secondary text on light */
    --muted-dark: rgba(255, 255, 255, .68);
    --white:      #FFFFFF;
    --canvas:     #FCFBF9;   /* page background — a whisper of the sand */

    /* The accent as raw channels, so alphas and shadows can be derived from it
       rather than hardcoded. Re-theming then needs only the tokens above. */
    --champagne-rgb:      205, 180, 137;
    --champagne-dark-rgb: 184, 154, 98;

    --champagne-a12: rgba(var(--champagne-rgb), .12);
    --champagne-a24: rgba(var(--champagne-rgb), .24);
    --champagne-a40: rgba(var(--champagne-rgb), .40);

    /* Review stars — Google's own review gold, which is what people are
       conditioned to read as a rating. Deliberately its own token rather than
       the accent, so the stars keep this colour whichever accent the site
       ends up with. */
    --star: #FBBC04;

    /* --- Type ---------------------------------------------------------- */
    --font: "Segoe UI Variable Display", "Segoe UI", -apple-system,
            BlinkMacSystemFont, "SF Pro Text", Roboto, "Helvetica Neue",
            Arial, sans-serif;

    --fs-xs:   0.75rem;
    --fs-sm:   0.8125rem;
    --fs-md:   0.9375rem;
    --fs-base: clamp(1rem, 0.97rem + 0.14vw, 1.0625rem);
    --fs-lead: clamp(1.0625rem, 1rem + 0.32vw, 1.1875rem);
    --fs-h4:   clamp(1.125rem, 1.06rem + 0.32vw, 1.3125rem);
    --fs-h3:   clamp(1.3125rem, 1.18rem + 0.62vw, 1.625rem);
    --fs-h2:   clamp(1.75rem, 1.42rem + 1.45vw, 2.625rem);
    --fs-h1:   clamp(2.125rem, 1.6rem + 2.3vw, 3.5rem);
    --fs-display: clamp(2.5rem, 1.7rem + 3.4vw, 4.25rem);

    /* --- Space --------------------------------------------------------- */
    --sp-1: .25rem;  --sp-2: .5rem;   --sp-3: .75rem;  --sp-4: 1rem;
    --sp-5: 1.5rem;  --sp-6: 2rem;    --sp-7: 2.5rem;  --sp-8: 3rem;
    --sp-9: 4rem;    --sp-10: 5rem;

    --gutter:  clamp(1.25rem, 4vw, 2.75rem);
    --section: clamp(3.5rem, 7vw, 6.5rem);
    --maxw:    1220px;
    --maxw-narrow: 780px;

    /* --- Radii & elevation --------------------------------------------- */
    --r-xs: 6px;  --r-sm: 10px;  --r: 14px;  --r-lg: 20px;  --r-xl: 28px;
    --r-full: 999px;

    --shadow-sm: 0 1px 2px rgba(35, 28, 12, .05),
                 0 2px 8px rgba(35, 28, 12, .04);
    --shadow:    0 2px 6px rgba(35, 28, 12, .05),
                 0 12px 28px -8px rgba(35, 28, 12, .12);
    --shadow-lg: 0 4px 12px rgba(35, 28, 12, .06),
                 0 28px 60px -16px rgba(35, 28, 12, .22);

    /* --- Chrome heights (JS-independent layout anchors) ----------------- */
    /* Tall enough to carry the logo at a legible size. It is a stacked,
       portrait-format mark (261x320), so height is what makes it readable —
       at 62px it was only ~51px wide and read as an afterthought. */
    --header-h: 104px;
    --topbar-h: 40px;

    --ease: cubic-bezier(.22, .61, .36, 1);
}

@media (max-width: 991px) {
    :root { --header-h: 88px; --topbar-h: 0px; }
}

/* =========================================================================
   2. RESET & BASE
   ========================================================================= */
*, *::before, *::after { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    /* Anchor targets clear the sticky header */
    scroll-padding-top: calc(var(--header-h) + 1rem);
}

body {
    margin: 0;
    font-family: var(--font);
    font-size: var(--fs-base);
    line-height: 1.65;
    color: var(--charcoal);
    background: var(--canvas);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    overflow-x: hidden;
}

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

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

button { font: inherit; color: inherit; }

ul, ol { margin: 0; padding: 0; }
li { list-style: none; }

h1, h2, h3, h4, h5, p, figure, blockquote { margin: 0; }

hr { border: 0; border-top: 1px solid var(--line); margin: var(--sp-6) 0; }

::selection { background: var(--champagne-a40); color: var(--on-champagne); }

/* Visible, on-brand focus for keyboard users only */
:focus-visible {
    outline: 3px solid var(--champagne);
    outline-offset: 3px;
    border-radius: var(--r-xs);
}

.visually-hidden {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* Inline SVG icons (sprite in partials/icons.html). Stroke icons by default;
   `.icon--solid` flips to a filled icon (brand marks, stars). */
.icon {
    display: inline-block; width: 20px; height: 20px; flex: none;
    fill: none; stroke: currentColor;
    stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
    vertical-align: middle;
}
.icon--solid { fill: currentColor; stroke: none; }
.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Skip link */
.skip-link {
    position: absolute; top: 0; left: 50%; transform: translate(-50%, -110%);
    z-index: 300; background: var(--champagne); color: var(--on-champagne);
    padding: .75rem 1.25rem; border-radius: 0 0 var(--r-sm) var(--r-sm);
    font-weight: 700; font-size: var(--fs-md);
}
.skip-link:focus { transform: translate(-50%, 0); }

/* =========================================================================
   3. LAYOUT
   ========================================================================= */
.wrap {
    width: 100%;
    max-width: var(--maxw);
    margin-inline: auto;
    padding-inline: var(--gutter);
}
.wrap--narrow { max-width: var(--maxw-narrow); }

.section { padding-block: var(--section); }
.section--tight { padding-block: clamp(2.5rem, 5vw, 4rem); }
.section--flush-top { padding-top: 0; }
.section--sand { background: var(--sand); }
.section--dark { background: var(--ink); color: var(--white); }
/* Section headings on a dark band. Scoped to .sec-head so it can't reach into
   light-surfaced children — the review quotes are white cards sitting ON a
   dark section, and their text must stay dark. */
.section--dark .sec-head h2, .on-dark .sec-head h2 { color: var(--white); }
.section--tint {
    background: linear-gradient(180deg, var(--sand) 0%, var(--canvas) 100%);
}

/* Lifts a section's CONTENT over the section above it, while the section's own
   background still starts at the boundary — so the cards read as floating
   between the two surfaces, as in the previous design.

   The light cards are NOT inside a media query: they must look the same at
   every width. They were previously scoped to >=768px, which left them dark
   and heavy on phones. */
.section--dark.section--overlap .card {
    background: var(--white);
    border-color: transparent;
    box-shadow: 0 26px 50px -22px rgba(0, 0, 0, .65);
}
.section--dark.section--overlap .card:hover { background: var(--white); }
.section--dark.section--overlap .card__title { color: var(--ink); }
.section--dark.section--overlap .card__text { color: var(--muted); }
.section--dark.section--overlap .card--icon .card__icon {
    background: var(--champagne-a24);
    color: var(--champagne-ink);
}

/* The lift itself starts at 992px, and NOT a pixel below, because that is
   exactly where #section-hero gains its `min-height: calc(100vh - 300px)`.
   Below it the hero is only as tall as its content, so there is no spare
   photo to ride up into — on an iPad the cards used to land on top of the
   headline and the CTA. The two breakpoints must stay in lock-step. */
@media (min-width: 992px) {
    .section--overlap { padding-top: 0; }
    .section--overlap > .wrap {
        position: relative;
        z-index: 2;
        margin-top: -130px;
    }
}
/* Taller viewport -> taller hero -> more empty photo under the copy, so the
   cards can ride higher. Verified against the measured gap at each step. */
@media (min-width: 992px) and (min-height: 850px) {
    .section--overlap > .wrap { margin-top: -170px; }
}
@media (min-width: 992px) and (min-height: 1000px) {
    .section--overlap > .wrap { margin-top: -210px; }
}

.grid { display: grid; gap: clamp(1.25rem, 2.5vw, 2rem); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }

@media (max-width: 991px) {
    .grid--3, .grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
    .grid--2, .grid--3, .grid--4 { grid-template-columns: 1fr; }
}

/* Split layout: main column + sidebar */
.split {
    display: grid;
    gap: clamp(2rem, 4vw, 3.5rem);
    grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr);
    align-items: start;
}
.split--even { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: center; }
@media (max-width: 991px) { .split, .split--even { grid-template-columns: 1fr; } }

.stack > * + * { margin-top: var(--sp-4); }
.center { text-align: center; }
.mt-auto { margin-top: auto; }

/* =========================================================================
   4. TYPOGRAPHY
   ========================================================================= */
h1, h2, h3, h4, .h1, .h2, .h3, .h4 {
    font-weight: 700;
    line-height: 1.14;
    letter-spacing: -0.022em;
    color: var(--ink);
    text-wrap: balance;
}
h1, .h1 { font-size: var(--fs-h1); }
h2, .h2 { font-size: var(--fs-h2); }
h3, .h3 { font-size: var(--fs-h3); line-height: 1.25; letter-spacing: -0.015em; }
h4, .h4 { font-size: var(--fs-h4); line-height: 1.3; letter-spacing: -0.01em; }

.display { font-size: var(--fs-display); line-height: 1.05; letter-spacing: -0.03em; }

.lead {
    font-size: var(--fs-lead);
    line-height: 1.6;
    color: var(--muted);
    text-wrap: pretty;
}
.section--dark .lead, .on-dark .lead { color: var(--muted-dark); }

.eyebrow {
    display: inline-flex; align-items: center; gap: .55em;
    font-size: var(--fs-sm); font-weight: 700;
    letter-spacing: .14em; text-transform: uppercase;
    color: var(--champagne-ink);
}
.eyebrow::before {
    content: ""; width: 26px; height: 2px; border-radius: 2px;
    background: var(--champagne);
}
.eyebrow--center::before { display: none; }
.on-dark .eyebrow, .section--dark .eyebrow { color: var(--champagne); }

.accent { color: var(--champagne-ink); }
.on-dark .accent, .section--dark .accent { color: var(--champagne); }

.muted { color: var(--muted); }
.on-dark .muted, .section--dark .muted { color: var(--muted-dark); }

.small { font-size: var(--fs-md); }

/* Section header block */
.sec-head { max-width: 680px; margin-bottom: clamp(2rem, 4vw, 3.25rem); }
.sec-head > * + * { margin-top: var(--sp-4); }
.sec-head--center { margin-inline: auto; text-align: center; }
.sec-head--wide { max-width: 840px; }

/* Header + action on one line */
.sec-head-row {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: var(--sp-5); flex-wrap: wrap;
    margin-bottom: clamp(2rem, 4vw, 3rem);
}
.sec-head-row .sec-head { margin-bottom: 0; }

/* --- Rich text (WordPress-imported service / about copy) --------------- */
.prose { font-size: var(--fs-base); line-height: 1.75; color: #3a3d43; }
.prose > * + * { margin-top: 1.1em; }
.prose h2 { font-size: var(--fs-h3); margin-top: 2em; }
.prose h3 { font-size: var(--fs-h4); margin-top: 1.9em; }
.prose h4 { font-size: var(--fs-base); margin-top: 1.7em; text-transform: uppercase;
            letter-spacing: .08em; color: var(--champagne-ink); }
.prose h2 + *, .prose h3 + *, .prose h4 + * { margin-top: .7em; }
.prose strong { color: var(--ink); font-weight: 700; }
.prose a { color: var(--champagne-ink); font-weight: 600;
           text-decoration: underline; text-underline-offset: 3px; }
.prose a:hover { color: var(--on-champagne); }
.prose ul, .prose ol { padding-left: 0; }
.prose li {
    position: relative; padding-left: 1.85em; margin-top: .55em;
    list-style: none;
}
.prose ul > li::before {
    content: ""; position: absolute; left: .3em; top: .68em;
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--champagne); box-shadow: 0 0 0 4px var(--champagne-a24);
}
.prose ol { counter-reset: p-ol; }
.prose ol > li { counter-increment: p-ol; }
.prose ol > li::before {
    content: counter(p-ol); position: absolute; left: 0; top: .12em;
    width: 1.5em; height: 1.5em; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--champagne-a24); color: var(--champagne-ink);
    font-size: .78em; font-weight: 800;
}
.prose img { border-radius: var(--r); margin-block: 1.5em; }
.prose blockquote {
    border-left: 3px solid var(--champagne);
    padding: .25em 0 .25em 1.4em; color: var(--ink);
    font-size: var(--fs-lead);
}
.prose table { width: 100%; border-collapse: collapse; }
.prose th, .prose td { border: 1px solid var(--line); padding: .6em .8em; text-align: left; }

/* =========================================================================
   5. BUTTONS & PILLS
   ========================================================================= */
.btn {
    --btn-bg: transparent;
    --btn-fg: var(--ink);
    --btn-bd: transparent;
    display: inline-flex; align-items: center; justify-content: center;
    gap: .6em;
    padding: .95rem 1.6rem;
    border: 1.5px solid var(--btn-bd);
    border-radius: var(--r-sm);
    background: var(--btn-bg);
    color: var(--btn-fg);
    font-size: var(--fs-md); font-weight: 700; line-height: 1.2;
    letter-spacing: .005em;
    text-align: center;
    cursor: pointer;
    transition: background .18s var(--ease), border-color .18s var(--ease),
                color .18s var(--ease), transform .18s var(--ease),
                box-shadow .18s var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn .icon { width: 1.15em; height: 1.15em; flex: none; }

.btn--primary {
    --btn-bg: var(--champagne); --btn-fg: var(--on-champagne);
    --btn-bd: var(--champagne);
    box-shadow: 0 4px 14px -4px rgba(var(--champagne-rgb), .7);
}
.btn--primary:hover {
    --btn-bg: var(--champagne-dark); --btn-bd: var(--champagne-dark);
    box-shadow: 0 8px 22px -6px rgba(var(--champagne-dark-rgb), .8);
}

.btn--dark { --btn-bg: var(--ink); --btn-fg: var(--white); --btn-bd: var(--ink); }
.btn--dark:hover { --btn-bg: #2c313b; --btn-bd: #2c313b; }

.btn--ghost { --btn-fg: var(--ink); --btn-bd: var(--line); --btn-bg: var(--white); }
.btn--ghost:hover {
    --btn-bd: var(--champagne); --btn-fg: var(--champagne-ink);
    box-shadow: var(--shadow-sm);
}

/* On dark / photo backgrounds */
.btn--light { --btn-bg: var(--white); --btn-fg: var(--ink); --btn-bd: var(--white); }
.btn--light:hover { --btn-bg: var(--sand); --btn-bd: var(--sand); }

.btn--outline-light {
    --btn-fg: var(--white); --btn-bd: rgba(255, 255, 255, .45);
}
.btn--outline-light:hover {
    --btn-bg: var(--white); --btn-fg: var(--ink); --btn-bd: var(--white);
}

.btn--wa { --btn-bg: #25D366; --btn-fg: #0A2E16; --btn-bd: #25D366; }
.btn--wa:hover { --btn-bg: #1FB855; --btn-bd: #1FB855; }

.btn--lg { padding: 1.15rem 2rem; font-size: var(--fs-base); }
.btn--sm { padding: .65rem 1.1rem; font-size: var(--fs-sm); }
.btn--block { display: flex; width: 100%; }

/* Text link with a sliding arrow */
.arrow-link {
    display: inline-flex; align-items: center; gap: .5em;
    font-weight: 700; font-size: var(--fs-md);
    color: var(--champagne-ink);
}
.arrow-link .icon {
    width: 1.05em; height: 1.05em;
    transition: transform .22s var(--ease);
}
.arrow-link:hover .icon { transform: translateX(4px); }
.on-dark .arrow-link { color: var(--champagne); }

/* Trust chips */
.chips { display: flex; flex-wrap: wrap; gap: .6rem .9rem; }
.chip {
    display: inline-flex; align-items: center; gap: .5em;
    padding: .5rem .9rem;
    border: 1px solid var(--line); border-radius: var(--r-full);
    background: var(--white);
    font-size: var(--fs-md); font-weight: 600; color: var(--ink);
}
.chip .icon { width: 1.05em; height: 1.05em; color: var(--champagne-ink); flex: none; }
.on-dark .chip, .section--dark .chip {
    background: rgba(255, 255, 255, .07);
    border-color: var(--line-dark);
    color: var(--white);
}
.on-dark .chip .icon, .section--dark .chip .icon { color: var(--champagne); }

/* Pill filters (projects) */
.filters { display: flex; flex-wrap: wrap; gap: .55rem; justify-content: center; }
.filter {
    padding: .6rem 1.15rem;
    border: 1.5px solid var(--line); border-radius: var(--r-full);
    background: var(--white);
    font-size: var(--fs-md); font-weight: 600; color: var(--muted);
    transition: all .18s var(--ease);
}
.filter:hover { border-color: var(--champagne); color: var(--ink); }
.filter[aria-current="true"] {
    background: var(--ink); border-color: var(--ink); color: var(--white);
}

/* Badge over an image */
.badge {
    display: inline-flex; align-items: center; gap: .4em;
    padding: .35rem .75rem; border-radius: var(--r-full);
    background: var(--champagne); color: var(--on-champagne);
    font-size: var(--fs-xs); font-weight: 800;
    letter-spacing: .06em; text-transform: uppercase;
}
.badge--soft { background: var(--champagne-a24); color: var(--champagne-ink); }
.badge--dark { background: rgba(32, 36, 44, .82); color: var(--white);
               backdrop-filter: blur(6px); }

/* =========================================================================
   6. HEADER / NAVIGATION
   ========================================================================= */
.topbar {
    background: var(--ink-deep);
    color: var(--muted-dark);
    font-size: var(--fs-sm);
    border-bottom: 1px solid rgba(255, 255, 255, .07);
}
.topbar__inner {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--sp-5); height: var(--topbar-h);
}
.topbar__list { display: flex; align-items: center; gap: var(--sp-5); flex-wrap: wrap; }
.topbar__item { display: inline-flex; align-items: center; gap: .5em; white-space: nowrap; }
.topbar__item .icon { width: 15px; height: 15px; color: var(--champagne); flex: none; }
.topbar a:hover { color: var(--champagne); }
@media (max-width: 991px) { .topbar { display: none; } }

.site-header {
    position: sticky; top: 0; z-index: 100;
    background: var(--ink);
    transition: box-shadow .25s var(--ease);
}
.site-header.is-scrolled { box-shadow: 0 6px 26px -10px rgba(0, 0, 0, .6); }

/* Nothing about the header resizes on scroll, so the document never reflows.
   It used to hide the topbar and shrink the bar, which made the header
   flicker: the topbar is exactly as tall as the old scroll threshold, so
   removing it shifted the page up, scroll anchoring pulled scrollY back under
   the threshold, the topbar returned — and it oscillated forever. Now the
   topbar is a sibling that simply scrolls away on its own, the bar and the
   logo keep a constant size, and `.is-scrolled` only paints a shadow. */
.nav-bar {
    display: flex; align-items: center; gap: var(--sp-5);
    height: var(--header-h);
}

.brand { display: flex; align-items: center; flex: none; }
/* Deliberately one fixed size: the logo does NOT shrink on scroll. A mark this
   small already needs every pixel, and shrinking it further as you scroll made
   it harder to read exactly when the header is all that's on screen. */
.brand img { height: 78px; width: auto; }
@media (max-width: 991px) {
    .brand img { height: 72px; }
}

.nav { margin-left: auto; }
.nav__list { display: flex; align-items: center; gap: clamp(.5rem, 1.6vw, 1.5rem); }
.nav__link {
    position: relative;
    display: block; padding: .5rem .25rem;
    color: rgba(255, 255, 255, .88);
    font-size: var(--fs-md); font-weight: 600;
    transition: color .18s var(--ease);
}
.nav__link::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: -2px;
    height: 2px; border-radius: 2px; background: var(--champagne);
    transform: scaleX(0); transform-origin: left;
    transition: transform .22s var(--ease);
}
.nav__link:hover { color: var(--white); }
.nav__link:hover::after { transform: scaleX(1); }
.nav__link[aria-current="page"] { color: var(--champagne); }
.nav__link[aria-current="page"]::after { transform: scaleX(1); }

/* Phone block + primary CTA on the right */
.header-actions { display: flex; align-items: center; gap: var(--sp-4); flex: none; }

.header-phone {
    display: flex; align-items: center; gap: .65rem;
    color: var(--white);
}
.header-phone__icon {
    display: grid; place-items: center; flex: none;
    width: 42px; height: 42px; border-radius: 50%;
    background: var(--champagne-a12);
    border: 1px solid var(--champagne-a40);
    color: var(--champagne);
}
.header-phone__icon .icon { width: 19px; height: 19px; }
.header-phone__text { display: flex; flex-direction: column; line-height: 1.25; }
.header-phone__label {
    font-size: var(--fs-xs); font-weight: 700; letter-spacing: .1em;
    text-transform: uppercase; color: var(--champagne);
}
.header-phone__num { font-size: var(--fs-md); font-weight: 700; white-space: nowrap; }
.header-phone__num:hover { color: var(--champagne); }

/* WhatsApp, between the phone block and the quote button */
.header-wa {
    display: grid; place-items: center; flex: none;
    width: 46px; height: 46px; border-radius: 50%;
    background: #25D366; color: #0A2E16;
    transition: background .18s var(--ease), transform .18s var(--ease);
}
.header-wa:hover { background: #1FB855; color: #0A2E16; transform: translateY(-2px); }
.header-wa .icon { width: 26px; height: 26px; }

@media (max-width: 1180px) { .header-phone { display: none; } }
@media (max-width: 991px) {
    /* Below the burger breakpoint the drawer and the sticky bottom bar both
       carry WhatsApp, so a third entry point here would just crowd the bar. */
    .nav, .header-actions .btn, .header-wa { display: none; }
}

/* Burger */
.burger {
    display: none;
    margin-left: auto;
    width: 46px; height: 46px; flex: none;
    border: 1px solid var(--line-dark); border-radius: var(--r-sm);
    background: rgba(255, 255, 255, .06);
    cursor: pointer;
    padding: 0;
    place-items: center;
}
.burger__box { display: block; width: 20px; height: 14px; position: relative; }
.burger__box span {
    position: absolute; left: 0; width: 100%; height: 2px; border-radius: 2px;
    background: var(--white);
    transition: transform .25s var(--ease), opacity .2s var(--ease), top .25s var(--ease);
}
.burger__box span:nth-child(1) { top: 0; }
.burger__box span:nth-child(2) { top: 6px; }
.burger__box span:nth-child(3) { top: 12px; }
@media (max-width: 991px) { .burger { display: grid; } }

/* Burger morphs into a close cross while the menu is open. Driven off
   aria-expanded, which the script already maintains — no extra class needed. */
.burger[aria-expanded="true"] { background: var(--champagne-a24); border-color: var(--champagne-a40); }
.burger[aria-expanded="true"] .burger__box span:nth-child(1) { top: 6px; transform: rotate(45deg); }
.burger[aria-expanded="true"] .burger__box span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] .burger__box span:nth-child(3) { top: 6px; transform: rotate(-45deg); }

/* Mobile menu: drops down from under the header rather than sliding in from
   the side. The header itself never moves — no second logo, no second close
   button — so the bar you tapped stays exactly where it was. Sits at z-index
   99, just under the header's 100, so it unrolls behind the bar. */
.drawer {
    position: fixed;
    top: var(--header-h); left: 0; right: 0; bottom: 0;
    z-index: 99;
    background: var(--ink);
    border-top: 1px solid var(--line-dark);
    overflow-y: auto;
    overscroll-behavior: contain;
    /* clip-path reveals downwards; visibility keeps it out of the tab order
       while closed and is delayed so it doesn't cut the animation short. */
    clip-path: inset(0 0 100% 0);
    visibility: hidden;
    transition: clip-path .34s var(--ease), visibility 0s linear .34s;
}
.drawer.is-open {
    clip-path: inset(0 0 0 0);
    visibility: visible;
    transition: clip-path .34s var(--ease), visibility 0s;
}

/* The panel takes focus when the menu opens so the keyboard and screen
   reader land inside it. It is a container, not a control, so it must not
   draw a ring of its own — the links it holds still do. */
.drawer:focus, .drawer:focus-visible { outline: none; }

.drawer__body {
    padding: var(--sp-6) var(--gutter) calc(var(--sp-8) + env(safe-area-inset-bottom));
    display: flex; flex-direction: column; gap: var(--sp-6);
}
.drawer__nav { display: flex; flex-direction: column; }
.drawer__link {
    display: flex; align-items: center; justify-content: space-between;
    padding: 1rem 0;
    border-bottom: 1px solid var(--line-dark);
    color: var(--white); font-size: 1.2rem; font-weight: 700;
}
.drawer__link .icon { width: 18px; height: 18px; color: var(--champagne); }
.drawer__link[aria-current="page"] { color: var(--champagne); }

.drawer__contact { display: flex; flex-direction: column; gap: var(--sp-3); }
.drawer__phone {
    display: flex; align-items: center; gap: .7rem;
    padding: .9rem 1.1rem; border-radius: var(--r-sm);
    background: rgba(255, 255, 255, .06);
    border: 1px solid var(--line-dark);
    color: var(--white); font-weight: 700;
}
.drawer__phone .icon { width: 20px; height: 20px; color: var(--champagne); flex: none; }

body.is-locked { overflow: hidden; }

/* =========================================================================
   7. HERO
   ========================================================================= */
.hero {
    position: relative;
    background:
        radial-gradient(1000px 520px at 88% -10%, var(--champagne-a24), transparent 62%),
        linear-gradient(180deg, var(--sand) 0%, var(--canvas) 78%);
    padding-block: clamp(2.75rem, 5.5vw, 5rem) clamp(3rem, 6vw, 5.5rem);
    overflow: hidden;
}
.hero__grid {
    display: grid;
    grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
    gap: clamp(2rem, 5vw, 4rem);
    align-items: center;
}
@media (max-width: 991px) { .hero__grid { grid-template-columns: 1fr; } }

.hero__copy > * + * { margin-top: var(--sp-5); }
.hero__title { font-size: var(--fs-display); line-height: 1.04; letter-spacing: -0.03em; }
.hero__title .accent { display: inline-block; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.hero__actions .btn { flex: 1 1 auto; min-width: 200px; }
@media (max-width: 480px) { .hero__actions .btn { min-width: 100%; } }

.hero__proof {
    display: flex; align-items: center; gap: var(--sp-4);
    padding-top: var(--sp-5);
    border-top: 1px solid var(--line);
    flex-wrap: wrap;
}
.hero__stars { display: flex; gap: 2px; color: var(--champagne); }
.hero__stars .icon { width: 17px; height: 17px; }

.hero__media { position: relative; }
.hero__frame {
    position: relative;
    border-radius: var(--r-xl);
    overflow: hidden;
    box-shadow: var(--shadow-lg);
    aspect-ratio: 4 / 3.4;
}
.hero__frame img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 991px) { .hero__frame { aspect-ratio: 16 / 10; } }

/* Floating card over the hero image */
.hero__card {
    position: absolute; left: -1.25rem; bottom: -1.5rem;
    display: flex; align-items: center; gap: .9rem;
    padding: 1rem 1.25rem;
    background: var(--white);
    border-radius: var(--r);
    box-shadow: var(--shadow-lg);
    max-width: 280px;
}
.hero__card-icon {
    display: grid; place-items: center; flex: none;
    width: 46px; height: 46px; border-radius: var(--r-sm);
    background: var(--champagne-a24); color: var(--champagne-ink);
}
.hero__card-icon .icon { width: 24px; height: 24px; }
.hero__card-num { display: block; font-size: 1.5rem; font-weight: 800; line-height: 1.1; color: var(--ink); }
.hero__card-label { display: block; font-size: var(--fs-sm); color: var(--muted); line-height: 1.3; }
@media (max-width: 991px) { .hero__card { left: auto; right: 1rem; bottom: -1.25rem; } }
@media (max-width: 480px) { .hero__card { display: none; } }

/* Key figures.
   The homepage no longer uses this — the only remaining consumer is the About
   page, where the figures come from AboutPage.stat1..3 in the admin (currently
   empty, so the band doesn't render). Kept so those admin fields still work;
   delete this block and the `{% if about.stats %}` section in
   templates/core/about.html together if the figures are dropped for good. */
.stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: clamp(1.75rem, 3.5vw, 2.75rem);
}
/* Full-width rows below this, rather than squeezing two-up and orphaning the
   last figure on a second row. */
@media (max-width: 779px) {
    .stats { grid-template-columns: 1fr; }
}

.stat { display: flex; align-items: flex-start; gap: clamp(.85rem, 1.5vw, 1.1rem); }
.stat__body { min-width: 0; }

.stat__icon {
    display: grid; place-items: center; flex: none;
    width: 52px; height: 52px; border-radius: 15px;
    margin-top: .2rem;
    background: var(--champagne-a24);
    color: var(--champagne-ink);
}
.stat__icon .icon { width: 26px; height: 26px; }

.stat__num {
    display: flex; align-items: flex-start; gap: .04em;
    font-size: clamp(2rem, 1.4rem + 2.2vw, 3rem);
    font-weight: 800; line-height: .95; letter-spacing: -0.04em;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}
.stat__label {
    margin-top: .3rem;
    font-size: var(--fs-md); font-weight: 600; line-height: 1.35;
    color: var(--muted);
    max-width: 20ch;
    text-wrap: pretty;
}

/* =========================================================================
   8. CARDS
   ========================================================================= */
.card {
    position: relative;
    display: flex; flex-direction: column;
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    overflow: hidden;
    transition: transform .28s var(--ease), box-shadow .28s var(--ease),
                border-color .28s var(--ease);
}
.card:hover {
    transform: translateY(-5px);
    border-color: var(--champagne-a40);
    box-shadow: var(--shadow);
}
.card__media { position: relative; overflow: hidden; aspect-ratio: 16 / 10; background: var(--sand); }
.card__media img { width: 100%; height: 100%; object-fit: cover;
                   transition: transform .6s var(--ease); }
.card:hover .card__media img { transform: scale(1.06); }
.card__media .badge { position: absolute; left: 1rem; top: 1rem; }

/* Trade icon floating on the image (service cards) */
.card__chip {
    position: absolute; left: 1rem; bottom: 1rem;
    display: grid; place-items: center;
    width: 46px; height: 46px; border-radius: var(--r-sm);
    background: rgba(255, 255, 255, .94);
    color: var(--champagne-ink);
    box-shadow: var(--shadow-sm);
    backdrop-filter: blur(6px);
}
.card__chip .icon { width: 24px; height: 24px; }

.card__body {
    display: flex; flex-direction: column; flex: 1;
    padding: clamp(1.25rem, 2.4vw, 1.75rem);
    gap: .7rem;
}
.card__title { font-size: var(--fs-h4); }
.card__text {
    color: var(--muted); font-size: var(--fs-md); line-height: 1.6;
    /* Keep every card's teaser the same length so the grid stays even */
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
    overflow: hidden;
}
.card__foot { margin-top: auto; padding-top: .5rem; }

/* Whole-card link: covers the card without nesting interactive elements */
.card__link::after { content: ""; position: absolute; inset: 0; }
.card a:not(.card__link) { position: relative; z-index: 1; }

/* Project card — image-led, caption overlaid.
   Media and body share one grid cell instead of the body being absolutely
   positioned: that keeps `.card` as the containing block, so the stretched
   `.card__link::after` covers the whole card (image included) and not just
   the caption strip. */
.card--project { border: 0; border-radius: var(--r-lg); display: grid; }
.card--project .card__media,
.card--project .card__body { grid-area: 1 / 1; }
.card--project .card__media { aspect-ratio: 4 / 3; }
.card--project .card__body {
    align-self: end; z-index: 1;
    padding: clamp(1.25rem, 3vw, 1.6rem);
    background: linear-gradient(to top, rgba(20, 23, 28, .92) 12%,
                                        rgba(20, 23, 28, .55) 55%,
                                        transparent 100%);
    color: var(--white);
    gap: .3rem;
}
.card--project .card__title { color: var(--white); font-size: var(--fs-h4); }
.card--project .card__meta {
    font-size: var(--fs-sm); font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--champagne);
}

/* Icon card — no image, for "why us" / guarantees */
.card--icon { padding: clamp(1.5rem, 3vw, 2rem); gap: .8rem; }
.card--icon .card__icon {
    display: grid; place-items: center;
    width: 52px; height: 52px; border-radius: var(--r-sm);
    background: var(--champagne-a24); color: var(--champagne-ink);
    margin-bottom: .3rem;
}
.card--icon .card__icon .icon { width: 26px; height: 26px; }
.card--icon .card__text { -webkit-line-clamp: unset; display: block; }

.section--dark .card {
    background: rgba(255, 255, 255, .05);
    border-color: var(--line-dark);
}
.section--dark .card:hover { background: rgba(255, 255, 255, .08); }
.section--dark .card__title { color: var(--white); }
.section--dark .card__text { color: var(--muted-dark); }
.section--dark .card--icon .card__icon {
    background: var(--champagne-a12); color: var(--champagne);
}

/* Sand-surface variant so cards stay visible on a sand section */
.section--sand .card, .section--tint .card { background: var(--white); }

/* =========================================================================
   9. PROCESS STEPS
   ========================================================================= */
.steps {
    display: grid; grid-template-columns: repeat(4, 1fr);
    gap: clamp(1.5rem, 3vw, 2.25rem);
    counter-reset: step;
}
@media (max-width: 991px) { .steps { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .steps { grid-template-columns: 1fr; } }

.step { position: relative; counter-increment: step; }
.step__num {
    position: relative; z-index: 1;
    display: grid; place-items: center;
    width: 56px; height: 56px; border-radius: 50%;
    background: var(--champagne); color: var(--on-champagne);
    font-size: 1.25rem; font-weight: 800;
    margin-bottom: var(--sp-4);
}
.step__num::before { content: counter(step, decimal-leading-zero); }
/* Connector line between steps */
.step:not(:last-child)::after {
    content: ""; position: absolute; top: 28px; left: 68px; right: -1.5rem;
    height: 2px;
    background: repeating-linear-gradient(to right,
        var(--champagne-a40) 0 8px, transparent 8px 16px);
}
@media (max-width: 991px) {
    .step:nth-child(2n)::after { display: none; }
}
@media (max-width: 560px) { .step::after { display: none; } }
.step__title { font-size: var(--fs-h4); margin-bottom: .5rem; }
.step__text { color: var(--muted); font-size: var(--fs-md); }
.section--dark .step__text { color: var(--muted-dark); }
.section--dark .step__title { color: var(--white); }

/* =========================================================================
   10. TESTIMONIALS
   ========================================================================= */
.quote {
    display: flex; flex-direction: column; gap: var(--sp-4);
    padding: clamp(1.5rem, 3vw, 2.25rem);
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    height: 100%;
}
.quote__stars { display: flex; gap: 3px; color: var(--star); }
.quote__stars .icon { width: 18px; height: 18px; }
.quote__text { font-size: var(--fs-base); line-height: 1.7; color: #3a3d43; flex: 1; }
.quote__author { display: flex; align-items: center; gap: .85rem;
                 padding-top: var(--sp-4); border-top: 1px solid var(--line); }
.quote__avatar {
    display: grid; place-items: center; flex: none;
    width: 44px; height: 44px; border-radius: 50%;
    background: var(--champagne-a24); color: var(--champagne-ink);
    font-weight: 800; font-size: var(--fs-md);
}
.quote__name { font-weight: 700; color: var(--ink); line-height: 1.3; }
.quote__meta { font-size: var(--fs-sm); color: var(--muted); }

/* =========================================================================
   11. FAQ (native <details>, no JS)
   ========================================================================= */
.faq { border-top: 1px solid var(--line); }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__q {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--sp-4);
    padding: 1.35rem 0;
    font-size: var(--fs-h4); font-weight: 700; color: var(--ink);
    cursor: pointer;
    list-style: none;
    transition: color .18s var(--ease);
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q:hover { color: var(--champagne-ink); }
/* The +/- toggle is shared with the services accordion (section 11b). Selectors
   are grouped rather than duplicated; the two differ only in how the open state
   is expressed — [open] on <details>, .is-open on the JS-driven one. */
.faq__sign, .svc__sign {
    position: relative; flex: none;
    width: 32px; height: 32px; border-radius: 50%;
    border: 1.5px solid var(--line);
    transition: background .2s var(--ease), border-color .2s var(--ease),
                transform .25s var(--ease);
}
.faq__sign::before, .faq__sign::after,
.svc__sign::before, .svc__sign::after {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: 12px; height: 2px; border-radius: 2px;
    background: var(--champagne-ink);
    transform: translate(-50%, -50%);
    transition: transform .25s var(--ease), opacity .2s var(--ease);
}
.faq__sign::after, .svc__sign::after { transform: translate(-50%, -50%) rotate(90deg); }

.faq__item[open] .faq__sign,
.svc__item.is-open .svc__sign { background: var(--champagne); border-color: var(--champagne); }
.faq__item[open] .faq__sign::before, .faq__item[open] .faq__sign::after,
.svc__item.is-open .svc__sign::before,
.svc__item.is-open .svc__sign::after { background: var(--on-champagne); }
.faq__item[open] .faq__sign::after,
.svc__item.is-open .svc__sign::after { transform: translate(-50%, -50%) rotate(0); }
.faq__a { padding: 0 0 1.5rem; max-width: 62ch; color: var(--muted); }
.faq__a > * + * { margin-top: .8em; }

/* =========================================================================
   11b. SERVICES ACCORDION (homepage)
   One entry open at a time, paired with a cross-fading image alongside.
   ========================================================================= */
.svc {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: clamp(2rem, 4vw, 3.5rem);
    align-items: start;
}

.svc__list { border-top: 1px solid var(--line); }
.svc__item { border-bottom: 1px solid var(--line); }
.svc__head { margin: 0; font-size: inherit; }

.svc__btn {
    width: 100%;
    display: flex; align-items: center; gap: .9rem;
    padding: 1.1rem 0;
    background: none; border: 0; cursor: pointer;
    text-align: left; color: var(--ink);
    font-size: var(--fs-h4); font-weight: 700; line-height: 1.3;
    letter-spacing: -0.01em;
    transition: color .18s var(--ease);
}
.svc__btn:hover { color: var(--champagne-ink); }
.svc__title { flex: 1; min-width: 0; }

.svc__icon {
    display: grid; place-items: center; flex: none;
    width: 44px; height: 44px; border-radius: 13px;
    background: var(--champagne-a24); color: var(--champagne-ink);
    transition: background .22s var(--ease), color .22s var(--ease);
}
.svc__icon .icon { width: 23px; height: 23px; }
/* The open entry's icon fills in, so the eye can find it without reading */
.svc__item.is-open .svc__icon { background: var(--champagne); color: var(--on-champagne); }

/* 0fr -> 1fr animates cleanly to the panel's natural height, which a plain
   height transition cannot do without hard-coding a value. */
.svc__panel {
    display: grid; grid-template-rows: 1fr;
    transition: grid-template-rows .34s var(--ease);
}
.js .svc__item:not(.is-open) .svc__panel { grid-template-rows: 0fr; }
.svc__panel-inner { overflow: hidden; }
.svc__text { color: var(--muted); max-width: 58ch; }
.svc__panel-inner > * + * { margin-top: .9rem; }
.svc__panel-inner { padding-bottom: 1.35rem; }
.js .svc__item:not(.is-open) .svc__panel-inner { padding-bottom: 0; }

.svc__media { position: sticky; top: calc(var(--header-h) + 1.5rem); }
.svc__frame {
    position: relative;
    aspect-ratio: 4 / 4.3;
    border-radius: var(--r-xl);
    overflow: hidden;
    background: var(--sand);
    box-shadow: var(--shadow);
}
.svc__img {
    position: absolute; inset: 0;
    width: 100%; height: 100%; object-fit: cover;
    opacity: 0;
    transition: opacity .55s var(--ease);
}
.svc__img.is-active { opacity: 1; }
/* Stand-in for a service that has no photo yet — cross-fades like the images */
.svc__img--blank {
    display: grid; place-items: center;
    background: var(--sand);
    color: var(--champagne-ink);
}
.svc__img--blank .icon { width: 88px; height: 88px; opacity: .5; }

@media (max-width: 899px) {
    .svc { grid-template-columns: 1fr; }
    /* Image first, but NOT pinned. Stacked, the list scrolls up underneath a
       sticky image instead of alongside it, so the pin simply parked a picture
       on top of the text you were trying to read. It scrolls away normally. */
    .svc__media { order: -1; position: static; }
    .svc__frame { aspect-ratio: 16 / 10; }
}
@media (prefers-reduced-motion: reduce) {
    .svc__img { transition: none; }
}

/* =========================================================================
   12. CTA BANDS
   ========================================================================= */
.cta {
    position: relative;
    background:
        radial-gradient(760px 380px at 12% 0%, rgba(var(--champagne-rgb), .22), transparent 66%),
        var(--ink);
    color: var(--white);
    border-radius: var(--r-xl);
    padding: clamp(2rem, 5vw, 3.5rem);
    overflow: hidden;
}
.cta__grid {
    display: grid; grid-template-columns: minmax(0, 1.4fr) auto;
    gap: var(--sp-6); align-items: center;
}
@media (max-width: 860px) { .cta__grid { grid-template-columns: 1fr; } }
.cta__title { color: var(--white); font-size: var(--fs-h2); }
.cta__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
@media (max-width: 480px) { .cta__actions .btn { width: 100%; } }

/* =========================================================================
   13. PAGE HEAD (interior pages)
   ========================================================================= */
.pagehead {
    background:
        radial-gradient(760px 320px at 85% 0%, var(--champagne-a24), transparent 62%),
        var(--sand);
    padding-block: clamp(2rem, 4vw, 3.25rem) clamp(2.25rem, 4.5vw, 3.5rem);
    border-bottom: 1px solid var(--sand-deep);
}
.pagehead__title { margin-top: var(--sp-3); max-width: 20ch; }
.pagehead__lead { margin-top: var(--sp-4); max-width: 62ch; }

.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem;
          font-size: var(--fs-md); color: var(--muted); }
.crumbs a:hover { color: var(--champagne-ink); }
.crumbs .icon { width: 14px; height: 14px; opacity: .55; }
.crumbs [aria-current="page"] { color: var(--ink); font-weight: 600; }

/* =========================================================================
   14. FORMS
   ========================================================================= */
.form-grid {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-4);
}
.field--full { grid-column: 1 / -1; }
@media (max-width: 640px) { .form-grid { grid-template-columns: 1fr; } }

.field { display: flex; flex-direction: column; gap: .45rem; }
.field__label {
    font-size: var(--fs-md); font-weight: 700; color: var(--ink);
}
.field__label .req { color: #C0392B; }
.field__label .field__optional { font-weight: 400; color: var(--muted); font-size: var(--fs-sm); }
.field__hint { font-size: var(--fs-sm); color: var(--muted); }

.field input[type="text"], .field input[type="email"], .field input[type="tel"],
.field select, .field textarea {
    width: 100%;
    padding: .85rem 1rem;
    font: inherit; font-size: var(--fs-md);
    color: var(--charcoal);
    background: var(--white);
    border: 1.5px solid var(--line);
    border-radius: var(--r-sm);
    transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
    appearance: none;
}
.field textarea { min-height: 150px; resize: vertical; line-height: 1.6; }
.field select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2362666E' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    background-size: 18px;
    padding-right: 2.75rem;
}
.field :is(input, select, textarea):focus {
    outline: none;
    border-color: var(--champagne);
    box-shadow: 0 0 0 4px var(--champagne-a24);
}
.field ::placeholder { color: #9AA0A8; }

/* Consent / opt-in checkbox */
.field--check { flex-direction: row; align-items: flex-start; gap: .7rem; }
.field--check input[type="checkbox"] {
    width: 20px; height: 20px; flex: none; margin-top: 2px;
    accent-color: var(--champagne-ink); cursor: pointer;
}
.field--check .field__label { font-weight: 500; color: var(--muted); cursor: pointer; }

.field .errorlist { margin-top: .1rem; }
.field .errorlist li { font-size: var(--fs-sm); font-weight: 600; color: #C0392B; }
.field:has(.errorlist) :is(input, select, textarea) { border-color: #E0A9A2; }

/* Alerts */
.alert {
    display: flex; align-items: flex-start; gap: .75rem;
    padding: 1rem 1.15rem;
    border: 1px solid transparent; border-radius: var(--r-sm);
    font-size: var(--fs-md); font-weight: 600;
}
.alert .icon { width: 20px; height: 20px; flex: none; margin-top: 1px; }
.alert--success { background: #E9F7EF; border-color: #B7E0C4; color: #14683A; }
.alert--error   { background: #FDEDEC; border-color: #F2C0BB; color: #A02B1D; }

/* Contact panel */
.panel {
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    padding: clamp(1.5rem, 3vw, 2rem);
}
.panel--sand { background: var(--sand); border-color: var(--sand-deep); }

.contact-list { display: flex; flex-direction: column; gap: var(--sp-4); }
.contact-row { display: flex; align-items: flex-start; gap: .9rem; }
.contact-row__icon {
    display: grid; place-items: center; flex: none;
    width: 42px; height: 42px; border-radius: var(--r-sm);
    background: var(--champagne-a24); color: var(--champagne-ink);
}
.contact-row__icon .icon { width: 20px; height: 20px; }
.contact-row__label {
    display: block;
    font-size: var(--fs-sm); font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--muted);
}
.contact-row__value { display: block; font-weight: 700; color: var(--ink); line-height: 1.45; }
.contact-row__value a:hover { color: var(--champagne-ink); }

.map-frame {
    border-radius: var(--r); overflow: hidden; border: 1px solid var(--line);
    line-height: 0;
}
.map-frame iframe { width: 100%; height: 100%; border: 0; }

/* Inline CTA inside a panel: text left, buttons right */
.panel-cta {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--sp-5); align-items: center;
}
.panel-cta__actions { display: flex; flex-wrap: wrap; gap: .75rem; }
@media (max-width: 700px) { .panel-cta { grid-template-columns: 1fr; } }

/* Sticky sidebar (service detail, contact) */
.sticky-side { position: sticky; top: calc(var(--header-h) + 1.5rem); }
@media (max-width: 991px) { .sticky-side { position: static; } }

/* =========================================================================
   15. GALLERY & LIGHTBOX
   ========================================================================= */
.gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-3); }
@media (max-width: 640px) { .gallery { grid-template-columns: repeat(2, 1fr); } }

.gallery__item {
    position: relative; display: block;
    aspect-ratio: 1; overflow: hidden;
    border-radius: var(--r); background: var(--sand);
    cursor: zoom-in;
}
.gallery__item img { width: 100%; height: 100%; object-fit: cover;
                     transition: transform .5s var(--ease); }
.gallery__item:hover img { transform: scale(1.07); }
.gallery__item::after {
    content: ""; position: absolute; inset: 0;
    background: rgba(32, 36, 44, .3);
    opacity: 0; transition: opacity .25s var(--ease);
}
.gallery__item:hover::after { opacity: 1; }

.lightbox {
    position: fixed; inset: 0; z-index: 300;
    display: none; place-items: center;
    padding: clamp(1rem, 4vw, 3rem);
    background: rgba(15, 17, 21, .93);
    backdrop-filter: blur(4px);
}
.lightbox.is-open { display: grid; }
.lightbox__img {
    max-width: min(1100px, 100%); max-height: 84vh;
    width: auto; object-fit: contain;
    border-radius: var(--r); box-shadow: var(--shadow-lg);
}
.lightbox__caption {
    margin-top: 1rem; text-align: center;
    color: rgba(255, 255, 255, .8); font-size: var(--fs-md);
}
.lightbox__btn {
    position: absolute;
    display: grid; place-items: center;
    width: 52px; height: 52px; border-radius: 50%;
    background: rgba(255, 255, 255, .12); color: var(--white);
    border: 1px solid rgba(255, 255, 255, .2);
    cursor: pointer; transition: background .18s var(--ease);
}
.lightbox__btn:hover { background: rgba(255, 255, 255, .24); }
.lightbox__btn .icon { width: 24px; height: 24px; }
.lightbox__close { top: clamp(1rem, 3vw, 2rem); right: clamp(1rem, 3vw, 2rem); }
.lightbox__prev { left: clamp(.5rem, 3vw, 2rem); top: 50%; transform: translateY(-50%); }
.lightbox__next { right: clamp(.5rem, 3vw, 2rem); top: 50%; transform: translateY(-50%); }
@media (max-width: 640px) {
    .lightbox__prev { left: .5rem; }
    .lightbox__next { right: .5rem; }
    .lightbox__btn { width: 44px; height: 44px; }
}

/* Horizontal snap rail (project showcase on small screens) */
@media (max-width: 640px) {
    .rail {
        display: grid;
        grid-template-columns: none;   /* beat .grid--3's single-column stack */
        grid-auto-flow: column;
        grid-auto-columns: minmax(78%, 1fr);
        gap: var(--sp-4);
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        /* Bleed to the screen edges so cards peek in from the side */
        margin-inline: calc(var(--gutter) * -1);
        padding-inline: var(--gutter);
        padding-bottom: .5rem;
        scrollbar-width: none;
    }
    .rail::-webkit-scrollbar { display: none; }
    .rail > * { scroll-snap-align: start; }
}

/* =========================================================================
   16. SERVICE NAV (sidebar list on service detail)
   ========================================================================= */
.side-nav { display: flex; flex-direction: column; }
.side-nav__link {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--sp-3);
    padding: .85rem 0;
    border-bottom: 1px solid var(--line);
    font-weight: 600; color: var(--charcoal);
    transition: color .18s var(--ease), padding-left .18s var(--ease);
}
.side-nav__link .icon { width: 16px; height: 16px; color: var(--champagne);
                        opacity: 0; transition: opacity .18s var(--ease); }
.side-nav__link:hover { color: var(--champagne-ink); padding-left: .35rem; }
.side-nav__link:hover .icon { opacity: 1; }
.side-nav__link[aria-current="page"] {
    color: var(--champagne-ink); font-weight: 800;
}
.side-nav__link[aria-current="page"] .icon { opacity: 1; }

/* Prev / next pager */
.pager {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--sp-3); flex-wrap: wrap;
}

/* =========================================================================
   17. FOOTER
   ========================================================================= */
.site-footer { background: var(--ink); color: var(--muted-dark); }
.footer__grid {
    display: grid;
    grid-template-columns: 1.5fr 1fr 1fr 1.2fr;
    gap: clamp(2rem, 4vw, 3rem);
    padding-block: clamp(3rem, 6vw, 4.5rem);
}
@media (max-width: 991px) { .footer__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer__grid { grid-template-columns: 1fr; } }

.footer__logo { height: 78px; width: auto; margin-bottom: var(--sp-4); }
.footer__title {
    color: var(--white); font-size: var(--fs-md); font-weight: 800;
    letter-spacing: .1em; text-transform: uppercase;
    margin-bottom: var(--sp-4);
}
.footer__list { display: flex; flex-direction: column; gap: .6rem; }
.footer__list a:hover { color: var(--champagne); }
/* Standalone links, not inline in a sentence, so the 24px minimum target size
   applies at every width — they were 21px on a phone and 23px on desktop.
   These are also the "call us" links, so worth being generous with. */
.footer__list a,
.footer__contact-row a { display: inline-block; padding-block: .3rem; }
.footer__contact { display: flex; flex-direction: column; gap: .8rem; }
.footer__contact-row { display: flex; align-items: flex-start; gap: .65rem; }
.footer__contact-row .icon { width: 17px; height: 17px; color: var(--champagne);
                             flex: none; margin-top: 4px; }
.footer__contact-row a:hover { color: var(--champagne); }

.socials { display: flex; gap: .6rem; margin-top: var(--sp-5); }
.social {
    display: grid; place-items: center;
    width: 40px; height: 40px; border-radius: 50%;
    background: rgba(255, 255, 255, .07);
    border: 1px solid var(--line-dark);
    color: var(--white);
    transition: background .18s var(--ease), color .18s var(--ease),
                transform .18s var(--ease);
}
.social:hover { background: var(--champagne); color: var(--on-champagne);
                border-color: var(--champagne); transform: translateY(-2px); }
.social .icon { width: 18px; height: 18px; }

.subfooter {
    background: var(--ink-deep);
    border-top: 1px solid var(--line-dark);
    font-size: var(--fs-md);
}
.subfooter__inner {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--sp-4); flex-wrap: wrap;
    padding-block: 1.25rem;
}
@media (max-width: 640px) { .subfooter__inner { justify-content: center; text-align: center; } }

/* Areas served — plain text list, good for local SEO */
.area-list { display: flex; flex-wrap: wrap; gap: .5rem; }
.area-list li {
    padding: .35rem .8rem; border-radius: var(--r-full);
    background: var(--champagne-a12); border: 1px solid var(--champagne-a24);
    font-size: var(--fs-md); color: var(--ink);
}
.section--dark .area-list li { color: var(--white); }

/* =========================================================================
   18. FLOATING / STICKY ACTIONS
   ========================================================================= */
.wa-float {
    position: fixed; right: 22px; bottom: 22px; z-index: 90;
    display: grid; place-items: center;
    width: 60px; height: 60px; border-radius: 50%;
    background: #25D366; color: #0A2E16;
    box-shadow: 0 10px 26px -6px rgba(37, 211, 102, .6);
    transition: transform .2s var(--ease), background .2s var(--ease);
}
.wa-float:hover { background: #1FB855; transform: scale(1.07); }
.wa-float .icon { width: 32px; height: 32px; }

/* Sticky call/quote bar — phones only. This is the main mobile conversion path. */
.action-bar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 95;
    display: none;
    grid-auto-flow: column; grid-auto-columns: 1fr;
    gap: 1px;
    background: var(--line);
    border-top: 1px solid var(--line);
    padding-bottom: env(safe-area-inset-bottom);
    box-shadow: 0 -6px 24px -10px rgba(0, 0, 0, .3);
}
.action-bar__btn {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: .2rem;
    padding: .65rem .35rem;
    background: var(--white);
    font-size: var(--fs-xs); font-weight: 700;
    color: var(--ink);
}
.action-bar__btn .icon { width: 21px; height: 21px; }
.action-bar__btn--call .icon { color: var(--champagne-ink); }
.action-bar__btn--wa .icon { color: #128C7E; }
.action-bar__btn--quote { background: var(--champagne); color: var(--on-champagne); }

@media (max-width: 767px) {
    .action-bar { display: grid; }
    /* Keep the bar from covering the end of the page */
    body { padding-bottom: 66px; }
    .wa-float { display: none; }
}

/* =========================================================================
   18b. MOBILE REFINEMENTS
   ========================================================================= */
@media (max-width: 767px) {
    /* iOS Safari zooms the whole page when a focused field is under 16px.
       On the form that generates the leads, that meant every tap zoomed in and
       left the visitor pinching back out. 16px is the threshold, not a
       preference. */
    .field input[type="text"],
    .field input[type="email"],
    .field input[type="tel"],
    .field select,
    .field textarea { font-size: 16px; }

    /* Small buttons (the project pager) were 38px; give them a full-size
       target now that they are the main way through the gallery on a phone. */
    .btn--sm { padding-top: .85rem; padding-bottom: .85rem; }
}

/* =========================================================================
   19. MOTION
   ========================================================================= */
/* Reveal-on-scroll is opt-in from JS: app.js adds `.js` to <html> before
   anything paints. If the script never loads, nothing is ever hidden. */
.js [data-reveal] {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity .6s var(--ease), transform .6s var(--ease);
}
.js [data-reveal].is-visible { opacity: 1; transform: none; }
/* Stagger children of a revealed grid */
.js [data-reveal-group] > * { transition-delay: calc(var(--i, 0) * 70ms); }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
    [data-reveal] { opacity: 1; transform: none; }
}

/* =========================================================================
   20. PRINT
   ========================================================================= */
@media print {
    .site-header, .site-footer, .action-bar, .wa-float, .drawer,
    .cta, .btn { display: none !important; }
    body { padding: 0; background: #fff; color: #000; }
}

/* =========================================================================
   21. LEGACY HERO
   The homepage hero restored from the pre-redesign design (commit e97febb),
   at the explicit request to keep it identical on desktop and mobile.

   The markup in core/home.html is the original, so the theme classes it used
   (.container/.row/.col-lg-*, .de-front, .overlay-bg, .btn-custom, .btn-line,
   .spacer-double, .lead) had to come back too. Rather than restore Bootstrap
   and the theme sheets for one section, the exact rules that applied to this
   hero were extracted from the old style.css / custom-carpenter.css /
   gmconcept.css and inlined below, every one scoped under #section-hero so
   nothing leaks into the rest of the site. `.lead` in particular is also a
   design-system class; the id scope keeps the two apart.
   ========================================================================= */
#section-hero {
    position: relative;
    padding: 45px 0;
    background: #18191b;
    color: #fff;
    /* The old theme loaded Instrument Sans; without it the 52px headline sets
       noticeably differently. See the @import at the top of base.html. */
    font-family: "Instrument Sans", var(--font);

    /* Parallax depth — the single place to tune it. The image is overscanned
       by this much top and bottom, and travels exactly that far as the section
       crosses the viewport. app.js reads this value, so CSS and JS cannot
       drift apart. Bigger = stronger. */
    --parallax-overscan: 35%;
}
#section-hero.gmc-hero {
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden;
}
@media (min-width: 992px) {
    /* The reserve subtracted here is everything that has to share the first
       screen with the hero: the topbar (41px) and header (104px) stacked above
       it, plus ~155px of the following section left showing at the fold so it
       is visibly there on landing. The old design reserved only 200px, which
       put the hero's bottom edge almost exactly on the fold.
       max() keeps a sensible floor on short viewports. */
    #section-hero { min-height: max(520px, calc(100vh - 300px)); }
}

/* --- the parallax image (was jarallax) ------------------------------- */
/* Overscanned top and bottom so app.js can translate it within the section
   without ever exposing an edge. With JS off it simply sits centred. */
#section-hero .jarallax-img {
    position: absolute;
    left: 0; width: 100%;
    top: calc(-1 * var(--parallax-overscan));
    height: calc(100% + 2 * var(--parallax-overscan));
    object-fit: cover;
    z-index: 0;
    will-change: transform;
}

#section-hero .de-front { position: relative; z-index: 5; width: 100%; }

#section-hero .overlay-bg,
#section-hero .overlay-bg.t2 {
    position: absolute; top: 0; left: 0;
    width: 100%; height: 100%;
    z-index: 1;
    background: linear-gradient(100deg,
        rgba(15, 22, 26, .86) 0%,
        rgba(15, 22, 26, .70) 45%,
        rgba(15, 22, 26, .58) 100%);
    opacity: 1;
}

/* --- Bootstrap 5 grid, only what this hero uses ---------------------- */
#section-hero .container {
    width: 100%;
    margin-right: auto; margin-left: auto;
    padding-right: .75rem; padding-left: .75rem;
}
@media (min-width: 576px)  { #section-hero .container { max-width: 540px; } }
@media (min-width: 768px)  { #section-hero .container { max-width: 720px; } }
@media (min-width: 992px)  { #section-hero .container { max-width: 960px; } }
@media (min-width: 1200px) { #section-hero .container { max-width: 1140px; } }
@media (min-width: 1400px) { #section-hero .container { max-width: 1320px; } }

#section-hero .row {                       /* .row.g-4 */
    display: flex; flex-wrap: wrap;
    margin-top: -1.5rem; margin-right: -.75rem; margin-left: -.75rem;
}
#section-hero .row > * {
    flex-shrink: 0; width: 100%; max-width: 100%;
    padding-right: .75rem; padding-left: .75rem;
    margin-top: 1.5rem;
}
#section-hero .justify-content-between { justify-content: space-between; }
#section-hero .align-items-center { align-items: center; }
@media (min-width: 992px) {
    #section-hero .col-lg-6 { flex: 0 0 auto; width: 50%; }
    #section-hero .col-lg-4 { flex: 0 0 auto; width: 33.33333333%; }

    /* The two buttons need ~426px side by side, but the 33% column is only
       380px at a 1200px viewport — so they wrapped, and `ms-2` left the second
       one indented 8px beneath the first. (The original design had this too.)
       Laying the column out as a flex row lets them share a line where there
       is room, and go full width, flush-aligned, where there isn't. */
    #section-hero .col-lg-4 { display: flex; flex-wrap: wrap; align-content: center; gap: 10px; }
    /* Absorb the row gap so the space under the paragraph stays the original 24px */
    #section-hero .col-lg-4 > .lead { flex: 0 0 100%; margin-bottom: calc(1.5rem - 10px); }
    #section-hero .col-lg-4 > .btn-custom,
    #section-hero .col-lg-4 > .btn-line { flex: 1 1 auto; margin-left: 0; }
    /* A lone button keeps its natural width rather than stretching the column.
       Tested on the absence of a filled sibling rather than :only-of-type,
       which stopped matching as soon as the rating link joined the column. */
    #section-hero .col-lg-4:not(:has(.btn-custom)) > .btn-line { flex: 0 0 auto; }
    /* The rating always takes a line of its own, under the button */
    #section-hero .col-lg-4 > .hero-rating { flex: 0 0 100%; }
}
#section-hero .mb-0 { margin-bottom: 0; }
#section-hero .mb-3 { margin-bottom: 1rem; }
#section-hero .mt-2 { margin-top: .5rem; }
#section-hero .mb-4 { margin-bottom: 1.5rem; }
#section-hero .ms-2 { margin-left: .5rem; }
#section-hero .spacer-double { width: 100%; height: 60px; display: block; clear: both; }

/* --- type ------------------------------------------------------------ */
/* The h1 is the keyword line. It keeps the champagne it had as a strapline and
   simply takes on the heading size; -1px tracking rather than -2px because a
   list of separated terms needs more air than a single phrase. */
#section-hero h1 {
    /* 46, not 52: at 52 the four terms break across three lines and the last
       two sit alone. 46 splits them two and two. */
    font-size: 46px;
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -1px;
    text-align: left;
    text-transform: none;
    color: #fff;
}
/* The tagline, demoted to a slogan sitting under the h1 and dropping in as the
   final beat of the same sequence (see heroKeywords in app.js). */
#section-hero .hero-slogan {
    margin-top: 15px;
    font-size: 20px;
    font-weight: 600;
    letter-spacing: .3px;
    color: var(--champagne);
}
/* Each term is wrapped by app.js so Motion can stagger them in. inline-block
   is required — transforms don't apply to inline boxes. The separators keep
   their surrounding spaces, which `white-space: normal` would otherwise
   collapse away once they sit alone inside a span. */
#section-hero .subtitle__part { display: inline-block; }
#section-hero .subtitle__sep { white-space: pre; }
/* Each term and the separator trailing it share one unit that may not break
   internally, so the line can only ever break BETWEEN units — a separator can
   never open a line. Without this, the hidden separator at a wrap kept its box
   and indented the keyword after it by 15px on a phone.
   inline-block, not inline: an inline unit still offered a break between its
   two atomic children and the separator escaped onto the next line anyway.
   An inline-block is atomic to the line that holds it, so it cannot split. */
#section-hero .subtitle__unit { display: inline-block; white-space: nowrap; }
#section-hero .lead {
    font-size: 16px;
    font-weight: 500;
    line-height: 1.7em;
    color: #fff;
}
#section-hero h1,
#section-hero .hero-slogan,
#section-hero .lead { text-shadow: 0 2px 14px rgba(0, 0, 0, .45); }

/* --- buttons --------------------------------------------------------- */
#section-hero .btn-custom,
#section-hero .btn-line {
    display: inline-block;
    font-size: 13px;
    letter-spacing: 2px;
    line-height: 1.5;
    padding: 12px 30px;
    border-radius: 6px;
    border-width: 2px;
    border-style: solid;
    text-align: center;
    text-decoration: none;
    vertical-align: top;
}
#section-hero .btn-custom {
    background: var(--champagne);
    border-color: transparent;
    color: var(--on-champagne);
    font-weight: bold;
    text-transform: none;      /* custom-carpenter.css overrode the theme's uppercase */
}
#section-hero .btn-custom:hover { opacity: .8; color: var(--on-champagne); }

/* Solid champagne — an outline button was disappearing into a busy photo.
   This is the same treatment as .btn--primary everywhere else on the site
   (champagne fill, dark text, darker champagne on hover with a 2px lift), so
   the hero CTA and the header CTA now read as the same control. The chevron
   is masked from `currentColor` and follows the text colour on its own. */
#section-hero .btn-line {
    background: var(--champagne);
    border-color: var(--champagne);
    color: var(--on-champagne);
    font-weight: 700;
    text-transform: uppercase;
    box-shadow: 0 4px 14px -4px rgba(var(--champagne-rgb), .7);
    transition: background .18s var(--ease), border-color .18s var(--ease),
                color .18s var(--ease), transform .18s var(--ease),
                box-shadow .18s var(--ease);
}
#section-hero .btn-line:hover {
    background: var(--champagne-dark);
    border-color: var(--champagne-dark);
    color: var(--on-champagne);
    transform: translateY(-2px);
    box-shadow: 0 8px 22px -6px rgba(var(--champagne-dark-rgb), .8);
}
/* The theme drew this chevron with FontAwesome (content "\f054"). That font is
   gone, so the same glyph is masked from an inline SVG and inherits the button
   colour — which is what the old colour overrides were doing by hand. */
#section-hero .btn-line::after {
    content: "";
    display: inline-block;
    width: .6em; height: .6em;
    margin-left: 10px;
    vertical-align: -1px;
    background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 512'%3E%3Cpath d='M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z'/%3E%3C/svg%3E") no-repeat center / contain;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 512'%3E%3Cpath d='M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z'/%3E%3C/svg%3E") no-repeat center / contain;
    transition: margin-left .2s var(--ease);
}
#section-hero .btn-line:hover::after { margin-left: 20px; }

/* --- Google rating badge --------------------------------------------- */
#section-hero .hero-rating {
    display: inline-flex; align-items: center; flex-wrap: wrap;
    gap: .2rem .55rem;
    margin-top: 1rem;
    color: #fff;
    font-size: 15px;
    text-decoration: none;
    text-shadow: 0 2px 14px rgba(0, 0, 0, .45);
}
#section-hero .hero-rating__stars { display: inline-flex; gap: 2px; color: var(--star); }
#section-hero .hero-rating__stars .icon { width: 17px; height: 17px; }
#section-hero .hero-rating__score { font-weight: 700; font-size: 17px; }
#section-hero .hero-rating__meta { color: rgba(255, 255, 255, .78); }
#section-hero a.hero-rating:hover .hero-rating__meta { color: #fff; }

/* --- mobile (identical to the old breakpoints) ----------------------- */
@media (max-width: 991px) {
    #section-hero { padding-top: 32px; padding-bottom: 36px; }
    #section-hero .spacer-double { display: none; }
}
@media (max-width: 767px) {
    #section-hero h1 { font-size: 32px; line-height: 1.2; letter-spacing: -.5px; }
    #section-hero .hero-slogan { font-size: 17px; }
    #section-hero .btn-custom,
    #section-hero .btn-line {
        display: block;
        width: 100%;
        text-align: center;
        margin: 10px 0 0 0;
    }
}
