/*
   Premier Exterior - Ad landing pages
   Shared by /gutter-cleaning, /solar-panel-cleaning, /window-screen-repair,
   /christmas-light-installation, /pressure-washing, /window-cleaning. One page per Google Ads
   ad group.

   Uses the tokens and components already defined in style.css (navy/teal palette,
   Outfit/Inter, .container, .section, .btn, .form-control). Every class here is
   prefixed lp- so nothing leaks into the existing pages.

   Structure:
     1. Shared base (hero, sections, includes, explainer)
     2. The interactive quote template (.lp-page--quote): fonts, card, steps, schedule
        picker, result, rating, proof band, CTA bands, sticky bar, photos, focus, motion.
   All four landers use the quote template. The older two-field callback layout is gone.
*/

/* Header height = the site logo height at each breakpoint + the header's 8px padding
   (logo 120px on desktop, 122px on tablets, 96px on phones). The hero and every in-page
   anchor have to clear it or content slides underneath. Once the page scrolls, the header
   compacts to a 60px logo (section 'compact header' below). */
:root {
    --lp-header-h: 128px;
}

@media (max-width: 1120px) {
    :root { --lp-header-h: 130px; }
}

@media (max-width: 520px) {
    :root { --lp-header-h: 104px; }
}

/* ===========================================================================
   1. SHARED BASE
   =========================================================================== */

/* --- HERO --- */
.lp-hero {
    background-color: var(--clr-navy);
    background-image: var(--gradient-primary);
    color: var(--clr-white);
    padding: calc(var(--lp-header-h) + env(safe-area-inset-top, 0px) + 16px) 0 var(--space-4xl);
    position: relative;
    overflow: hidden;
}

.lp-hero::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 4px;
    background: linear-gradient(90deg, var(--clr-navy) 0%, var(--clr-teal) 50%, var(--clr-navy) 100%);
}

.lp-hero-grid {
    display: grid;
    grid-template-columns: 1fr 380px;
    gap: var(--space-4xl);
    align-items: center;
}

/* Pages whose hero carries the interactive quote card need a wider, top-aligned
   right column: the card changes height as the visitor moves between steps, and
   centring it would make the whole hero jump on every tap. */
.lp-hero-grid--quote {
    grid-template-columns: 1fr 460px;
    align-items: start;
    gap: var(--space-3xl);
}

.lp-eyebrow {
    display: inline-block;
    color: var(--clr-teal);
    font-family: var(--font-heading);
    font-weight: var(--fw-medium);
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 1.5px;
    margin-bottom: var(--space-md);
}

.lp-hero-title {
    color: var(--clr-white);
    font-size: 3.25rem;
    line-height: 1.08;
    margin-bottom: var(--space-md);
}

.lp-hero-title span {
    color: var(--clr-teal);
}

.lp-hero-sub {
    font-size: 1.15rem;
    color: rgba(255, 255, 255, 0.82);
    max-width: 34em;
    margin-bottom: var(--space-xl);
}

/* --- CALL / CALLBACK ACTION PAIR --- */
.lp-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
}

.lp-btn-call {
    background: var(--gradient-accent);
    color: var(--clr-navy);
    font-weight: var(--fw-bold);
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    box-shadow: var(--shadow-glow);
}

.lp-actions .btn svg,
.lp-btn-call svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

/* Hover lifts only for real mouse pointers. On touch screens :hover sticks after a
   tap and leaves the button lifted and tinted. */
@media (hover: hover) and (pointer: fine) {
    .lp-btn-call:hover {
        color: var(--clr-navy);
        transform: translateY(-2px);
    }

}

.lp-hero-note {
    font-size: 0.92rem;
    color: rgba(255, 255, 255, 0.75);
}

/* --- SECTION SCAFFOLD --- */
.lp-section-head {
    max-width: 42em;
    margin-bottom: var(--space-2xl);
}

.lp-section-head.is-centered {
    margin-left: auto;
    margin-right: auto;
    text-align: center;
}

.lp-section-title {
    font-size: 2.25rem;
    margin-bottom: var(--space-sm);
    text-wrap: balance;
}

.lp-section-lead {
    color: var(--clr-text-muted);
    font-size: 1.08rem;
}

/* --- WHAT IS INCLUDED ---
   The lander's own language, not a feature grid: the heading on the left (it rides along
   while the list scrolls on desktop), the six items on the right as one checklist, each icon
   in a ring on a teal line, like the route list by the map and the explainer's steps. Rows
   split by hairlines. Information only; the section's one action is the .lp-next row under
   it, across both columns. */
.lp-inc .container {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    grid-template-areas: "head list" "next list";
    grid-template-rows: auto 1fr;
    column-gap: var(--space-4xl);
    align-items: start;
}

.lp-inc .lp-section-head {
    grid-area: head;
    margin: 0;
    text-align: left;
}

.lp-inc .lp-section-title {
    font-size: clamp(1.75rem, 1.35rem + 1.6vw, 2.5rem);
    line-height: 1.15;
}

.lp-inc .lp-section-lead {
    margin-left: 0;
}

/* Desktop: the action sits under the heading, beside the list. */
.lp-inc .lp-next {
    grid-area: next;
    margin-top: var(--space-xl);
}

.lp-includes {
    grid-area: list;
    position: relative;
}

.lp-include {
    position: relative;
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    column-gap: 20px;
    padding: 18px 0;
}

.lp-include + .lp-include::after {
    content: '';
    position: absolute;
    top: 0;
    left: 64px;
    right: 0;
    border-top: 1px solid var(--clr-border);
}

/* The line: each ring to the next one's centre, so it ends at the last ring. */
.lp-include:not(:last-child)::before {
    content: '';
    position: absolute;
    left: 21px;
    top: 40px;
    bottom: -40px;
    width: 2px;
    background: var(--clr-teal);
}

.lp-include-icon {
    position: relative;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border: 2px solid #2B7A78;
    border-radius: 50%;
    background: var(--clr-white);
    box-shadow: 0 0 0 6px var(--clr-white);
    color: #2B7A78;
}

.lp-include-icon svg {
    width: 20px;
    height: 20px;
}

.lp-include h3 {
    margin: 9px 0 4px;
    font-size: 1.12rem;
    line-height: 1.3;
}

.lp-include p {
    margin: 0;
    font-size: 0.95rem;
    color: var(--clr-text-muted);
    text-wrap: pretty;
}

/* One column: heading, list, action. */
@media (max-width: 900px) {
    .lp-inc .container {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas: "head" "list" "next";
        grid-template-rows: none;
    }

    .lp-inc .lp-section-head {
        margin-bottom: var(--space-lg);
    }

    .lp-inc .lp-next {
        margin-top: var(--space-2xl);
    }
}

@media (max-width: 600px) {
    .lp-include:not(:last-child)::before {
        left: 19px;
        top: 34px;
        bottom: -34px;
    }

    .lp-include {
        grid-template-columns: 40px minmax(0, 1fr);
        column-gap: 16px;
        padding: 14px 0;
    }

    .lp-include + .lp-include::after {
        left: 56px;
    }

    .lp-include-icon {
        width: 40px;
        height: 40px;
    }

    .lp-include h3 {
        margin-top: 7px;
        font-size: 1.05rem;
    }

    .lp-include p {
        font-size: 0.9rem;
    }
}

/* --- EXPLAINER: why it matters ---
   The hook (kicker, title, lead), a "left alone vs. done" drawing with the pull line in a navy
   strip, a three-step chain whose markers darken as the stakes rise (white, teal, navy) joined
   by arrows, then why now and one text link up to the quote card. Phones and tablets: one
   column in reading order. Desktop: the drawing left, the words right. */
.lp-explainer {
    background-color: var(--clr-off-white);
}

.lp-exp {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "head" "visual" "steps" "close";
    gap: var(--space-xl);
}

.lp-exp-head {
    grid-area: head;
}

.lp-exp-visual {
    grid-area: visual;
}

.lp-exp-steps {
    grid-area: steps;
}

.lp-exp-close {
    grid-area: close;
}

/* The main site's section label, in the AA teal (#5BC0BE is 2.1:1 on off-white). */
.lp-exp-kicker {
    margin-bottom: var(--space-sm);
    font-weight: var(--fw-bold);
    font-size: 0.85rem;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: #2B7A78;
}

.lp-exp .lp-section-title {
    font-size: clamp(1.75rem, 1.35rem + 1.6vw, 2.5rem);
    line-height: 1.15;
}

.lp-exp-lead {
    margin: 0;
    font-size: 1.1rem;
    text-wrap: pretty;
}

/* One hairline card: two drawings split by the border colour, the pull line in a navy strip. */
.lp-exp-visual {
    margin: 0;
    background: var(--clr-white);
    border: 1px solid var(--clr-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.lp-vs {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1px;
    background: var(--clr-border);
}

.lp-vs-side {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    padding: 12px 10px 14px;
    background: var(--clr-white);
}

.lp-vs-tag {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    font-family: var(--font-heading);
    font-weight: var(--fw-bold);
    font-size: 0.78rem;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--clr-navy);
}

.lp-vs-tag svg {
    flex: none;
    width: 16px;
    height: 16px;
    fill: none;
    stroke: var(--clr-text-muted);
    stroke-width: 2.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.lp-vs-side--good .lp-vs-tag {
    color: #2B7A78;
}

.lp-vs-side--good .lp-vs-tag svg {
    stroke: currentColor;
}

.lp-vs-art {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 15;
    border-radius: var(--radius-md);
}

.lp-vs-cap {
    margin: 0;
    font-size: 0.875rem;
    line-height: 1.45;
    color: var(--clr-text-muted);
}

.lp-exp-pull {
    margin: 0;
    padding: 16px 18px 18px;
    background: var(--clr-navy);
    color: var(--clr-white);
    font-family: var(--font-heading);
    font-weight: var(--fw-semibold);
    font-size: 1.2rem;
    line-height: 1.3;
    text-wrap: balance;
}

.lp-exp-pull em {
    display: block;
    font-style: normal;
    color: var(--clr-teal);
}

/* The chain. Each marker is joined to the next by a line ending in an arrowhead: this step
   causes the next. */
.lp-exp-steps {
    margin: 0;
    padding: 0;
    list-style: none;
}

.lp-exp-steps li {
    position: relative;
    padding: 0 0 var(--space-lg) 56px;
}

.lp-exp-steps li:last-child {
    padding-bottom: 0;
}

.lp-exp-steps li:not(:last-child)::before {
    content: '';
    position: absolute;
    left: 19px;
    top: 46px;
    bottom: 6px;
    width: 2px;
    background: linear-gradient(var(--clr-teal), var(--clr-navy-light));
}

.lp-exp-steps li:not(:last-child)::after {
    content: '';
    position: absolute;
    left: 15px;
    bottom: 7px;
    width: 10px;
    height: 10px;
    border: solid var(--clr-navy-light);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.lp-exp-num {
    position: absolute;
    left: 0;
    top: 0;
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border: 2px solid #2B7A78;
    border-radius: 50%;
    background: var(--clr-white);
    color: #2B7A78;
    font-family: var(--font-heading);
    font-weight: var(--fw-bold);
    font-size: 1.1rem;
    line-height: 1;
}

.lp-exp-steps li:nth-child(2) .lp-exp-num {
    border-color: var(--clr-teal);
    background: var(--clr-teal);
    color: var(--clr-navy);
}

.lp-exp-steps li:last-child .lp-exp-num {
    border-color: var(--clr-navy);
    background: var(--clr-navy);
    color: var(--clr-white);
}

.lp-exp-steps h3 {
    margin: 8px 0 2px;
    font-size: 1.15rem;
    line-height: 1.3;
}

.lp-exp-steps p {
    margin: 0;
}

/* Why now, then one text link up to the quote card (not a third CTA band). */
.lp-exp-close {
    padding-top: var(--space-lg);
    border-top: 1px solid var(--clr-border-strong);
}

.lp-exp-close p {
    margin: 0 0 var(--space-xs);
    text-wrap: pretty;
}

.lp-exp-close strong {
    color: var(--clr-navy);
}

.lp-exp-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    min-height: 44px;
    font-family: var(--font-heading);
    font-weight: var(--fw-semibold);
    font-size: 1.05rem;
    color: #2B7A78;
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 5px;
}

.lp-exp-link svg {
    flex: none;
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.25;
    stroke-linecap: round;
    stroke-linejoin: round;
}

@media (hover: hover) and (pointer: fine) {
    .lp-exp-link:hover {
        color: var(--clr-navy);
    }
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
    .lp-exp-link svg {
        transition: transform 0.2s ease;
    }

    .lp-exp-link:hover svg {
        transform: translateX(3px);
    }
}

@media (max-width: 600px) {
    .lp-exp {
        gap: var(--space-lg);
    }
}

/* Narrow phones: a slimmer marker column so step titles keep to one line. */
@media (max-width: 400px) {
    .lp-exp-steps li {
        padding-left: 50px;
    }

    .lp-exp-num {
        width: 36px;
        height: 36px;
        font-size: 1rem;
    }

    .lp-exp-steps li:not(:last-child)::before {
        left: 17px;
        top: 42px;
    }

    .lp-exp-steps li:not(:last-child)::after {
        left: 13px;
    }

    .lp-exp-steps h3 {
        margin-top: 6px;
        font-size: 1.1rem;
    }
}

/* Tablets stack too: a readable column instead of poster-size drawings. */
@media (min-width: 601px) and (max-width: 900px) {
    .lp-exp {
        max-width: 680px;
    }

    .lp-vs-side {
        padding: 16px 16px 18px;
    }
}

@media (min-width: 901px) {
    .lp-exp {
        grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
        grid-template-areas: "visual head" "visual steps" "visual close";
        grid-template-rows: auto auto 1fr;
        gap: var(--space-xl) var(--space-3xl);
        align-items: start;
    }

    .lp-exp-visual {
        align-self: center;
    }

    .lp-vs-side {
        gap: 12px;
        padding: 18px 18px 20px;
    }

    .lp-vs-cap {
        font-size: 0.92rem;
    }

    .lp-exp-pull {
        padding: 18px 24px 20px;
        font-size: 1.4rem;
    }
}

.lp-form-submit {
    width: 100%;
    justify-content: center;
}

.lp-honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* --- SHARED RESPONSIVE --- */
@media (max-width: 1120px) {
    .lp-hero-grid {
        gap: var(--space-2xl);
        grid-template-columns: 1fr 320px;
    }

    .lp-hero-grid--quote {
        grid-template-columns: 1fr 420px;
    }

    .lp-hero-title {
        font-size: 2.75rem;
    }
}

@media (max-width: 900px) {
    .lp-hero-grid,
    .lp-hero-grid--quote {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 768px) {
    .lp-hero {
        padding-bottom: var(--space-3xl);
    }

    .lp-hero-title {
        font-size: 2.15rem;
    }

    .lp-hero-sub {
        font-size: 1.05rem;
    }

    .lp-section-title {
        font-size: 1.75rem;
    }

    .lp-actions .btn {
        width: 100%;
        justify-content: center;
    }
}

/* ===========================================================================
   2. INTERACTIVE QUOTE TEMPLATE  (.lp-page--quote)
   Pattern follows the PPU65 apply lander and its abandonment audit: one question
   per step, tap to advance, progress visible from step 1, the phone number never
   gated behind any of it, and a committed callback time as the payoff.
   =========================================================================== */

/* --- Self-hosted fonts ---
   Every page (landers and main pages) uses these through .lp-page--quote. */
@font-face {
    font-family: 'Outfit LP';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/outfit-latin-wght-v1.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Inter LP';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/inter-latin-wght-v1.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Metric-matched fallbacks: until the web fonts arrive (font-display: swap), text sets in Arial
   (Windows, macOS, iOS) or Roboto (Android) scaled to the web font's widths and line metrics,
   so the swap does not rewrap lines and move the hero. Values from the woff2 files: average
   advance width over English text (capsize's method) against Arial / Arial Bold and Roboto,
   regular for weights 400-500 and bold for 600-700 (the Roboto Bold width is estimated at
   1.02x Roboto). A family whose local() font is missing is skipped. */
@font-face {
    font-family: 'Inter LP Fallback';
    src: local('Arial'), local('ArialMT');
    font-weight: 400 500;
    size-adjust: 107.35%;
    ascent-override: 90.25%;
    descent-override: 22.47%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Inter LP Fallback';
    src: local('Arial Bold'), local('Arial-BoldMT');
    font-weight: 600 700;
    size-adjust: 101.13%;
    ascent-override: 95.80%;
    descent-override: 23.85%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Inter LP Fallback Android';
    src: local('Roboto'), local('Roboto-Regular');
    font-weight: 400 500;
    size-adjust: 106.54%;
    ascent-override: 90.93%;
    descent-override: 22.64%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Inter LP Fallback Android';
    src: local('Roboto Bold'), local('Roboto-Bold');
    font-weight: 600 700;
    size-adjust: 106.42%;
    ascent-override: 91.04%;
    descent-override: 22.67%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Outfit LP Fallback';
    src: local('Arial'), local('ArialMT');
    font-weight: 400 500;
    size-adjust: 99.63%;
    ascent-override: 100.37%;
    descent-override: 26.10%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Outfit LP Fallback';
    src: local('Arial Bold'), local('Arial-BoldMT');
    font-weight: 600 700;
    size-adjust: 93.79%;
    ascent-override: 106.62%;
    descent-override: 27.72%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Outfit LP Fallback Android';
    src: local('Roboto'), local('Roboto-Regular');
    font-weight: 400 500;
    size-adjust: 98.90%;
    ascent-override: 101.11%;
    descent-override: 26.29%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Outfit LP Fallback Android';
    src: local('Roboto Bold'), local('Roboto-Bold');
    font-weight: 600 700;
    size-adjust: 98.70%;
    ascent-override: 101.32%;
    descent-override: 26.34%;
    line-gap-override: 0%;
}

.lp-page--quote {
    --font-heading: 'Outfit LP', 'Outfit LP Fallback', 'Outfit LP Fallback Android', system-ui, sans-serif;
    --font-body: 'Inter LP', 'Inter LP Fallback', 'Inter LP Fallback Android', system-ui, sans-serif;
}

/* --- Anchors and keyboard focus land below the fixed header and above the sticky bar --- */
html:has(.lp-page--quote) {
    scroll-padding-top: calc(var(--lp-header-h) + env(safe-area-inset-top, 0px) + 12px);
}

@media (max-width: 768px), (orientation: landscape) and (max-height: 500px) {
    html:has(.lp-page--quote) {
        scroll-padding-bottom: 80px;
    }
}

@media (prefers-reduced-motion: reduce) {
    html:has(.lp-page--quote) {
        scroll-behavior: auto;
    }
}

/* --- Explicit, short transitions (style.css uses 'all 0.3s', which animates layout
       properties and makes every tap feel soft) --- */
.lp-page--quote a {
    transition: color 0.2s ease;
}

.lp-page--quote .btn {
    transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.lp-page--quote .btn::before {
    display: none;
}

.lp-page--quote .site-header {
    transition: background-color 0.3s ease, box-shadow 0.3s ease;
}

.lp-page--quote .form-control {
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Hover lifts from style.css, re-gated to real mouse pointers on this template. */
.lp-page--quote .btn-primary:hover,
.lp-page--quote .btn-secondary:hover,
.lp-page--quote .btn-accent:hover {
    transform: none;
}

@media (hover: hover) and (pointer: fine) {
    .lp-page--quote .btn-primary:hover,
    .lp-page--quote .btn-accent:hover {
        transform: translateY(-2px);
    }
}

/* Immediate press feedback on touch (iOS needs the touchstart listener in the JS). */
.lp-page--quote .btn,
.lp-option,
.lp-window,
.lp-day,
.lp-asap,
.lp-quote-back,
.lp-rating {
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}

.lp-page--quote .btn:active,
.lp-option:active,
.lp-window:active,
.lp-day:active,
.lp-asap:active {
    transform: scale(0.98);
    transition-duration: 80ms;
}

/* Header "Call Now" and the menu's call button: white on teal is 2.16:1. Navy on teal is 7:1+. */
.lp-page--quote .btn-accent,
.lp-page--quote .mobile-nav-call {
    color: var(--clr-navy);
}

.lp-page--quote .mobile-nav-quote,
.lp-page--quote .mobile-nav-call {
    padding-inline: 10px;
    text-align: center;
    line-height: 1.2;
}

/* The footer logo centres with the rest of the footer on phones and tablets. */
@media (max-width: 768px) {
    .lp-page--quote .site-footer .footer-brand-link {
        justify-content: center;
    }
}

/* --- Focus rings: visible on every surface, 3:1 or better --- */
.lp-page--quote :focus-visible {
    outline: 3px solid var(--clr-navy);
    outline-offset: 2px;
}

.lp-page--quote .site-header :focus-visible,
.lp-page--quote .lp-hero-copy :focus-visible,
.lp-page--quote .site-footer :focus-visible,
.lp-page--quote .lp-bar :focus-visible {
    outline-color: var(--clr-teal);
}

.lp-page--quote .lp-quote :focus-visible {
    outline-color: var(--clr-navy);
}

.lp-page--quote .form-control:focus-visible {
    border-color: var(--clr-navy);
    outline: 2px solid var(--clr-navy);
    outline-offset: 1px;
    box-shadow: none;
}

.lp-page--quote .form-control::placeholder {
    color: var(--clr-text-muted);
    opacity: 1;
}

.lp-step-q:focus,
.lp-step-q:focus-visible {
    outline: none;
}

/* Footer column titles are h2 on this template (an h4 straight after the last section's
   h2 skips a level for screen readers). Same look as the site's footer h4. */
.lp-page--quote .site-footer .footer-links li {
    text-wrap: balance;
}

.lp-footer-heading {
    color: var(--clr-white);
    font-size: 1rem;
    margin-bottom: var(--space-md);
}

/* Four footer columns (brand, services, company, contact) from 1024px up, two on tablets; phones
   keep style.css's single centred column. */
/* Phones: brand on top, Services and Company side by side, Contact below. */
@media (max-width: 768px) {
    .lp-footer-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: var(--space-md);
    }

    .lp-footer-grid > .footer-col:first-child,
    .lp-footer-grid > .footer-col:last-child {
        grid-column: 1 / -1;
    }
}

@media (min-width: 769px) and (max-width: 1023px) {
    .lp-footer-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1024px) {
    .lp-footer-grid {
        grid-template-columns: 1.35fr 1fr 1fr 1.25fr;
    }
}

/* --- Hero: rating lockup + facts ---
   The score set as type, not a capsule: the numeral, a hairline, then the stars over the
   linked count. 8px of padding is pulled back out with a negative margin, so the type sits
   flush with the copy while the focus ring and the 44px tap area get room. */
.lp-rating {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    min-height: 44px;
    margin: var(--space-md) 0 0 -8px;
    padding: 0 8px;
    border-radius: var(--radius-md);
    color: var(--clr-white);
}

.lp-rating-score {
    padding-right: 12px;
    border-right: 1px solid rgba(255, 255, 255, 0.22);
    font: var(--fw-bold) 1.9rem/1 var(--font-heading);
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.lp-rating-meta {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.lp-rating-stars {
    display: inline-flex;
    gap: 2px;
}

.lp-rating-stars svg {
    width: 14px;
    height: 14px;
    fill: #FBBF24;
}

.lp-rating-text {
    font-size: 0.86rem;
    line-height: 1.2;
    color: rgba(255, 255, 255, 0.86);
    text-decoration: underline;
    text-decoration-color: rgba(255, 255, 255, 0.35);
    text-underline-offset: 3px;
}

.lp-rating-ext {
    display: inline-block;
    width: 14px;
    height: 14px;
    margin-left: 4px;
    vertical-align: -2px;
    opacity: 0.7;
}

.lp-rating:active {
    opacity: 0.85;
}

@media (hover: hover) and (pointer: fine) {
    .lp-rating:hover,
    .lp-rating:hover .lp-rating-text {
        color: var(--clr-white);
    }

    .lp-rating:hover .lp-rating-text {
        text-decoration-color: var(--clr-teal);
    }
}

.lp-trust-facts {
    display: block;
    margin-top: var(--space-sm);
    font-size: 0.9rem;
    color: rgba(255, 255, 255, 0.75);
}

/* --- Hero: Google reviews under the rating ---
   The box is a fixed height (clamped quote lines plus the name row) from the first paint, so
   the reviews arriving later, and each rotation, never move anything. Two quote lines on wide
   screens, three on phones; the name row sits at the bottom with the pause button on its
   right. Empty, it is just space. */
.lp-hero-review {
    position: relative;
    display: flex;
    flex-direction: column;
    height: calc(2 * 1.45em + 0.35em + 28px + 13px);
    max-width: 34rem;
    margin: var(--space-sm) 0 0;
    font-size: 0.95rem;
}

.lp-hero-review blockquote {
    margin: 0;
}

.lp-hero-review p {
    display: -webkit-box;
    margin: 0;
    overflow: hidden;
    line-height: 1.45;
    color: rgba(255, 255, 255, 0.9);
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
}

.lp-hero-review blockquote,
.lp-hero-review figcaption {
    transition: opacity 0.25s ease;
}

.lp-hero-review.is-swapping blockquote,
.lp-hero-review.is-swapping figcaption {
    opacity: 0;
}

.lp-hero-review figcaption {
    display: flex;
    align-items: center;
    min-height: 28px;
    margin-top: auto;
    overflow: hidden;
    font-size: 0.82em;
    line-height: 1.4;
    white-space: nowrap;
    text-overflow: ellipsis;
    color: rgba(255, 255, 255, 0.68);
}

.lp-hero-review a {
    color: inherit;
    text-decoration: underline;
    text-decoration-color: rgba(255, 255, 255, 0.35);
    text-underline-offset: 3px;
}

@media (max-width: 640px) {
    .lp-hero-review {
        height: calc(3 * 1.45em + 0.35em + 28px + 13px);
    }

    .lp-hero-review p {
        -webkit-line-clamp: 3;
        line-clamp: 3;
    }
}

.lp-hero-review figcaption a {
    margin-left: 0.3em;
}

/* Rotation progress: a short segmented bar above the quote, one segment per review. The
   current one fills over 7s; its animationend (JS) moves to the next review, and a hold
   (.is-held: hover, touch, keyboard focus, off screen) pauses both. Its 13px are in the box
   height from the first paint, so it never shifts anything. */
.lp-hero-review-progress {
    display: flex;
    gap: 4px;
    width: 140px;
    height: 3px;
    margin-bottom: 10px;
}

.lp-hero-review-progress span {
    flex: 1;
    overflow: hidden;
    border-radius: 2px;
    background: rgba(255, 255, 255, 0.2);
}

.lp-hero-review-progress i {
    display: block;
    height: 100%;
    background: var(--clr-teal);
    transform: scaleX(0);
    transform-origin: left;
}

.lp-hero-review-progress .is-done i {
    transform: none;
}

.lp-hero-review-progress .is-on i {
    animation: lp-review-fill 7s linear forwards;
}

.lp-hero-review.is-held .lp-hero-review-progress .is-on i {
    animation-play-state: paused;
}

@keyframes lp-review-fill {
    to {
        transform: scaleX(1);
    }
}

/* Before reviews arrive, and when there is only one, the bar's space sits above the quote. */
.lp-hero-review:not(.is-rotating) blockquote {
    margin-top: 13px;
}

/* Pause / play for the rotation (WCAG 2.2.2): hidden until a keyboard reaches it, then a
   28px circle on the name row's right. Screen readers always find it. */
.lp-hero-review-pause:not(:focus-visible) {
    width: 1px;
    height: 1px;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
}

.lp-hero-review-pause {
    position: absolute;
    right: 0;
    bottom: 0;
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 50%;
    background: transparent;
    color: var(--clr-white);
    cursor: pointer;
}

.lp-hero-review-pause svg {
    width: 12px;
    height: 12px;
    fill: currentColor;
}

@media (hover: hover) and (pointer: fine) {
    .lp-hero-review-pause:hover {
        border-color: var(--clr-teal);
    }
}

@media (prefers-reduced-motion: reduce) {
    .lp-hero-review blockquote,
    .lp-hero-review figcaption {
        transition: none;
    }
}

/* --- Quote card --- */
.lp-quote {
    position: relative;
    background-color: var(--clr-white);
    border-radius: var(--radius-lg);
    padding: var(--space-xl);
    box-shadow: var(--shadow-xl);
    color: var(--clr-text-body);
}

/* Card head: one row that never changes height, set like a printed running head. Left: Back
   (step 2 on) or the card label. Then a hairline leader, then the step counter (the folio).
   The leader is the row's own ::before, ordered between them, so it stays put when Back takes
   the label's slot. The progress is the card's own top edge, the contact form's teal stripe
   made to count. */
.lp-quote-head {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 44px;
    margin: -6px 0 var(--space-sm);
}

.lp-quote-head::before {
    content: '';
    order: 2;
    flex: 1;
    height: 1px;
    background: var(--clr-border);
}

.lp-quote-back {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 2px;
    min-width: 44px;
    min-height: 44px;
    margin: 0 0 0 -10px;
    padding: 0 8px;
    font-family: var(--font-body);
    font-size: 0.88rem;
    font-weight: var(--fw-medium);
    color: var(--clr-text-body);
    background: none;
    border: 0;
    border-radius: var(--radius-md);
    cursor: pointer;
}

.lp-quote-back svg {
    width: 18px;
    height: 18px;
}

.lp-quote-back[aria-hidden="true"] {
    display: none;
}

@media (hover: hover) and (pointer: fine) {
    .lp-quote-back:hover {
        color: var(--clr-navy);
        background: var(--clr-off-white);
    }
}

/* The card label, set as type (no box, no tint, no caps), led by one small handset in the AA
   teal #2B7A78. Back takes this slot whenever Back is showing. */
.lp-quote-title {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font: var(--fw-semibold) 1rem/1.2 var(--font-heading);
    white-space: nowrap;
    color: var(--clr-navy);
}

.lp-quote-title svg {
    flex: none;
    width: 16px;
    height: 16px;
    color: #2B7A78;
}

.lp-quote-back[aria-hidden="false"] + .lp-quote-title,
.lp-quote.is-finished .lp-quote-title {
    display: none;
}

.lp-quote-count {
    order: 3;
    font: var(--fw-medium) 0.8rem/1 var(--font-body);
    font-variant-numeric: tabular-nums;
    color: var(--clr-text-muted);
    white-space: nowrap;
}

.lp-quote-count b {
    font-weight: var(--fw-bold);
    color: var(--clr-navy);
}

.lp-quote.is-correcting .lp-quote-count,
.lp-quote.is-finished .lp-quote-count,
.lp-quote.is-correcting .lp-quote-head::before,
.lp-quote.is-finished .lp-quote-head::before {
    display: none;
}

/* Result: nothing left to count or go back to, so the row folds away (the stripe stays full). */
.lp-quote.is-finished .lp-quote-head {
    min-height: 0;
    margin: 0;
}

/* A full-card overlay so the 16px corners clip the bar exactly. Never overflow:hidden on
   .lp-quote itself: it would clip the .is-arriving ring. */
.lp-quote-progress {
    position: absolute;
    inset: 0;
    display: flex;
    gap: 3px;
    border-radius: var(--radius-lg);
    overflow: hidden;
    pointer-events: none;
}

.lp-progress-seg {
    flex: 1;
    height: 5px;
    background-color: var(--clr-border);
    transition: background-color 0.25s ease;
}

.lp-progress-seg.is-done,
.lp-progress-seg.is-active {
    background-color: var(--clr-teal-dark);
}

/* Step-1 reassurance, under the options (hidden at 520px and below, and once started). */
.lp-quote-sub {
    margin: var(--space-md) 0 0;
    font-size: 0.85rem;
    color: var(--clr-text-muted);
    text-wrap: pretty;
}

.lp-quote.is-started .lp-quote-sub {
    display: none;
}

.lp-quote.is-finished .lp-quote-steps {
    padding-top: var(--space-sm);
}

.lp-quote-noscript {
    margin: var(--space-md) 0;
    color: var(--clr-text-body);
}

.lp-quote-noscript-call {
    width: 100%;
    justify-content: center;
}

/* --- Steps + the step transition ---
   The swap happens in the same frame as the tap. Motion is compositor-only (opacity
   and transform), short, and never runs on first paint (gated on .is-started).
   The step area keeps a minimum height so the page below does not jump. */
.lp-quote-steps {
    position: relative;
}

.lp-quote.is-started .lp-quote-steps {
    min-height: var(--lp-steps-min, 0px);
}

/* Holds the three one-tap questions at one height; the schedule and contact steps grow the
   card rather than every step carrying their height as empty space. */
.lp-quote {
    --lp-steps-min: 300px;
}

.lp-quote-step.is-hidden {
    display: none;
}

.lp-quote.is-started .lp-quote-step:not(.is-hidden) {
    animation: lp-step-in 180ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

.lp-quote.is-started.is-going-back .lp-quote-step:not(.is-hidden) {
    animation-name: lp-step-in-back;
}

@keyframes lp-step-in {
    from {
        opacity: 0;
        transform: translate3d(0, 8px, 0);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes lp-step-in-back {
    from {
        opacity: 0;
        transform: translate3d(0, -8px, 0);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

.lp-step-q {
    font-size: 1.35rem;
    line-height: 1.25;
    margin-bottom: var(--space-xs);
    text-wrap: balance;
}

/* Notice at collection under the quote form: what the number is for, plus the privacy link. */
.form-consent {
    margin: var(--space-sm) 0 0;
    font-size: 0.875rem;
    line-height: 1.5;
    color: var(--clr-text-muted);
    text-wrap: pretty;
}

.form-consent a {
    position: relative;
    color: var(--clr-navy);
    font-weight: var(--fw-semibold);
    text-decoration: underline;
    text-underline-offset: 2px;
    white-space: nowrap;
}

/* 44px tap area without changing the line height */
.form-consent a::after {
    content: '';
    position: absolute;
    inset: -12px -8px;
}

/* "Wrong number? Fix it" reuses the contact step; swap its heading and help text. */
.lp-fix-copy {
    display: none;
}

.lp-quote.is-correcting span.lp-fix-copy {
    display: inline;
}

.lp-quote.is-correcting p.lp-fix-copy {
    display: block;
}

.lp-quote.is-correcting .lp-book-copy,
.lp-quote.is-correcting [data-step="contact"] .lp-step-help:not(.lp-fix-copy) {
    display: none;
}

.lp-step-help {
    font-size: 0.9rem;
    color: var(--clr-text-muted);
    margin-bottom: var(--space-md);
}

/* --- Option buttons --- */
.lp-options {
    display: grid;
    gap: var(--space-sm);
}

.lp-option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    width: 100%;
    min-height: 52px;
    text-align: left;
    font-family: var(--font-body);
    font-size: 1.02rem;
    font-weight: var(--fw-medium);
    color: var(--clr-navy);
    background-color: var(--clr-white);
    border: 2px solid var(--clr-border);
    border-radius: var(--radius-md);
    padding: 12px var(--space-md);
    cursor: pointer;
    transition: border-color 0.15s ease, background-color 0.15s ease, transform 0.1s ease;
}

.lp-option:focus-visible {
    border-color: var(--clr-teal);
    background-color: rgba(91, 192, 190, 0.07);
}

@media (hover: hover) and (pointer: fine) {
    .lp-option:hover {
        border-color: var(--clr-teal);
        background-color: rgba(91, 192, 190, 0.07);
    }
}

.lp-option.is-chosen,
.lp-option[aria-pressed="true"] {
    border-color: var(--clr-teal-dark);
    background-color: rgba(91, 192, 190, 0.18);
    transition: none;
}

.lp-option::after {
    content: '';
    flex: none;
    width: 8px;
    height: 8px;
    margin-right: 4px;
    border: solid var(--clr-text-muted);
    border-width: 2px 2px 0 0;
    transform: rotate(45deg);
    transition: border-color 0.15s ease, transform 0.15s ease;
}

.lp-option.is-chosen::after,
.lp-option[aria-pressed="true"]::after {
    border-color: var(--clr-teal-dark);
}

@media (hover: hover) and (pointer: fine) {
    .lp-option:hover::after {
        border-color: var(--clr-teal-dark);
        transform: translateX(2px) rotate(45deg);
    }
}

/* --- Schedule picker: one obvious default, then a day, then that day's windows --- */
.lp-asap {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    width: 100%;
    min-height: 64px;
    margin-top: var(--space-md);
    padding: var(--space-md);
    text-align: left;
    font-family: var(--font-body);
    color: var(--clr-navy);
    background: rgba(91, 192, 190, 0.10);
    border: 2px solid var(--clr-teal);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: border-color 0.15s ease, background-color 0.15s ease, transform 0.1s ease;
}

.lp-asap-title {
    font-family: var(--font-heading);
    font-weight: var(--fw-semibold);
    font-size: 1.05rem;
}

.lp-asap-sub {
    font-size: 0.88rem;
    color: var(--clr-text-body);
}

.lp-asap.is-chosen {
    border-color: var(--clr-teal-dark);
    background: rgba(91, 192, 190, 0.22);
}

.lp-pick-label {
    margin: var(--space-lg) 0 var(--space-sm);
    font-size: 0.82rem;
    font-weight: var(--fw-semibold);
    color: var(--clr-text-muted);
}

/* Days: three desk-calendar leaves. A header strip carries the day, the date sits below. The
   chosen leaf gets a navy strip and a 2px navy edge, so the state shows in shape and fill, not
   colour alone. Muted on off-white is 4.55:1. */
.lp-days {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-sm);
    margin-bottom: var(--space-md);
}

.lp-day {
    min-height: 60px;
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
    border: 1px solid var(--clr-border-strong);
    border-radius: var(--radius-md);
    background: var(--clr-white);
    color: var(--clr-navy);
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.lp-day-name {
    padding: 5px 4px 4px;
    border-bottom: 1px solid var(--clr-border);
    background: var(--clr-off-white);
    font: var(--fw-semibold) 0.66rem/1.2 var(--font-body);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--clr-text-muted);
}

.lp-day-date {
    flex: 1;
    display: grid;
    place-items: center;
    font: var(--fw-bold) 1.05rem/1 var(--font-heading);
    font-variant-numeric: tabular-nums;
    color: var(--clr-navy);
}

/* A day sent without a date: the name fills the leaf instead of leaving it half empty. */
.lp-day-name:only-child {
    flex: 1;
    display: grid;
    place-items: center;
    border-bottom: 0;
}

.lp-day[aria-pressed="true"] {
    border-color: var(--clr-navy);
    box-shadow: inset 0 0 0 1px var(--clr-navy);
}

.lp-day[aria-pressed="true"] .lp-day-name {
    border-bottom-color: var(--clr-navy);
    background: var(--clr-navy);
    color: var(--clr-white);
}

/* "TOMORROW" gets a 78px leaf at 320px: tighter tracking and side padding leave it room. */
@media (max-width: 360px) {
    .lp-day-name {
        padding-inline: 2px;
        letter-spacing: 0.04em;
    }
}

/* Forced colours drop the fills and the inset edge: paint the chosen strip in system colours. */
@media (forced-colors: active) {
    .lp-day[aria-pressed="true"] .lp-day-name {
        forced-color-adjust: none;
        background: Highlight;
        color: HighlightText;
    }
}

.lp-windows {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-sm);
    align-content: start;
    /* Three rows always reserved, so switching days never changes the card height. */
    min-height: calc(3 * 48px + 2 * var(--space-sm));
}

.lp-window {
    min-height: 48px;
    font-family: var(--font-body);
    font-weight: var(--fw-medium);
    font-size: 0.98rem;
    line-height: 1.2;
    color: var(--clr-navy);
    background: var(--clr-white);
    border: 2px solid var(--clr-border);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: border-color 0.15s ease, background-color 0.15s ease, transform 0.1s ease;
}

.lp-window:last-child:nth-child(odd) {
    grid-column: 1 / -1;
}

.lp-window.is-chosen {
    border-color: var(--clr-teal-dark);
    background: rgba(91, 192, 190, 0.18);
    transition: none;
}

.lp-skel {
    display: block;
    min-height: 48px;
    border-radius: var(--radius-md);
    background: var(--clr-border);
}

.lp-skel-day {
    min-height: 60px;
}

.lp-schedule-failed .lp-pick-label,
.lp-schedule-failed .lp-days,
.lp-schedule-failed .lp-windows {
    display: none;
}

.lp-slots-status {
    font-size: 0.9rem;
    color: var(--clr-text-body);
}

.lp-slots-status:not(:empty) {
    margin-top: var(--space-md);
}

@media (hover: hover) and (pointer: fine) {
    .lp-window:hover,
    .lp-asap:hover {
        border-color: var(--clr-teal-dark);
    }

    .lp-day:not([aria-pressed="true"]):hover {
        border-color: var(--clr-teal-dark);
    }
}

/* --- Contact step ---
   The chosen time as a ruled line item: a teal-dark rule, a small label over the time set in
   Outfit, and Change as a plain text link (44px tall). No box. */
.lp-chosen {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: var(--space-lg);
    padding-left: 14px;
    border-left: 3px solid var(--clr-teal-dark);
    color: var(--clr-navy);
}

/* Fixing a phone number after booking only updates the number, so the time chip (and its
   Change link) would offer something the correction cannot do. */
.lp-quote.is-correcting [data-chosen] {
    display: none;
}

.lp-chosen-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.lp-chosen-label {
    font: var(--fw-semibold) 0.7rem/1.2 var(--font-body);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--clr-text-muted);
}

.lp-chosen [data-chosen-text] {
    font: var(--fw-semibold) 1.05rem/1.25 var(--font-heading);
}

.lp-chosen .lp-link {
    flex: none;
    padding: 0 2px 0 12px;
}

.lp-link {
    min-height: 44px;
    padding: 0 var(--space-md);
    font-family: var(--font-body);
    font-size: 0.88rem;
    font-weight: var(--fw-semibold);
    color: var(--clr-navy);
    background: none;
    border: 0;
    border-radius: var(--radius-md);
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}

.lp-page--quote .lp-quote .form-group {
    margin-bottom: var(--space-md);
}

.lp-field-error {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 4px;
    font-size: 0.85rem;
    color: var(--clr-text-body);
}

.lp-field-error[hidden] {
    display: none;
}

.lp-field-error::before {
    content: '!';
    flex: none;
    display: grid;
    place-items: center;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--clr-error);
    color: var(--clr-white);
    font-size: 11px;
    font-weight: var(--fw-bold);
    line-height: 1;
}

.lp-form-submit[aria-disabled="true"] {
    opacity: 0.75;
    cursor: progress;
}

.lp-quote-status {
    margin-top: var(--space-sm);
    font-size: 0.9rem;
    color: var(--clr-text-body);
}

.lp-quote-status:empty {
    display: none;
}

.lp-status-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-top: var(--space-sm);
}

.lp-status-actions .btn {
    flex: 1 1 160px;
    min-height: 48px;
    padding: var(--space-sm) var(--space-md);
    justify-content: center;
}

.lp-status-retry {
    font-family: var(--font-heading);
    font-weight: var(--fw-semibold);
    font-size: 0.9rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--clr-navy);
    background: var(--clr-white);
    border: 2px solid var(--clr-navy);
    border-radius: var(--radius-md);
    cursor: pointer;
}

/* --- Result (the payoff) --- */
.lp-quote-step[data-step="result"] {
    text-align: center;
}

.lp-result-icon {
    width: 56px;
    height: 56px;
    margin: 0 auto var(--space-md);
    border-radius: var(--radius-full);
    background-color: rgba(16, 185, 129, 0.14);
    color: var(--clr-success);
    display: grid;
    place-items: center;
}

.lp-result-icon svg {
    width: 28px;
    height: 28px;
}

.lp-quote-step[data-step="result"] .lp-step-q {
    font-size: 1rem;
    color: #2B7A78;
}

.lp-result-when {
    text-wrap: balance;
    font-family: var(--font-heading);
    font-size: 1.35rem;
    font-weight: var(--fw-bold);
    line-height: 1.3;
    color: var(--clr-navy);
    margin-bottom: var(--space-sm);
}

.lp-result-phone {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0 var(--space-xs);
    font-size: 0.95rem;
    color: var(--clr-text-body);
}

.lp-result-save {
    font-size: 0.9rem;
    color: var(--clr-text-muted);
    margin-bottom: var(--space-md);
}

.lp-result-save a {
    color: var(--clr-navy);
    font-weight: var(--fw-semibold);
    white-space: nowrap;
}

/* What they told us, as a centred colophon: small-caps labels set right to a shared axis, the
   answers left of it. A hairline above separates it from the booking. Subgrid gives every row
   one axis; the sr-only ": " (from the JS) is absolutely positioned, so it takes no cell. */
.lp-chips {
    display: grid;
    grid-template-columns: auto auto;
    justify-content: center;
    gap: 6px 14px;
    margin: 0 0 var(--space-lg);
    padding: var(--space-md) 0 0;
    border-top: 1px solid var(--clr-border);
    list-style: none;
    text-align: left;
}

.lp-chips:empty {
    display: none;
}

.lp-chips li {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
    align-items: baseline;
}

/* Must stay before the 360px query, or it would undo the stacking without subgrid. */
@supports not (grid-template-columns: subgrid) {
    .lp-chips li {
        grid-template-columns: 7.5em minmax(0, 1fr);
        column-gap: 14px;
    }
}

.lp-chip-q {
    text-align: right;
    font: var(--fw-semibold) 0.68rem/1.3 var(--font-body);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--clr-text-muted);
}

.lp-chip-a {
    font: var(--fw-medium) 0.9rem/1.35 var(--font-body);
    color: var(--clr-navy);
    text-wrap: balance;
}

/* Under 360px two columns leave each answer a few words wide: stack each pair, centred. */
@media (max-width: 360px) {
    .lp-chips,
    .lp-chips li {
        grid-template-columns: minmax(0, 1fr);
    }

    .lp-chips {
        gap: 10px;
        text-align: center;
    }

    .lp-chip-q {
        text-align: center;
    }
}

.lp-result-or {
    display: block;
    font-size: 0.85rem;
    color: var(--clr-text-muted);
    margin: var(--space-sm) 0 var(--space-xs);
}

.lp-result-call,
.lp-quote-step[data-step="result"] .lp-btn-call {
    width: 100%;
    min-height: 52px;
    justify-content: center;
    white-space: nowrap;
}

/* The arrival ring: a brief cue showing where a "get an estimate" tap landed. */
.lp-quote.is-arriving::after {
    content: '';
    position: absolute;
    inset: -4px;
    border-radius: calc(var(--radius-lg) + 4px);
    box-shadow: 0 0 0 3px var(--clr-teal);
    pointer-events: none;
    animation: lp-ring 0.7s ease-out forwards;
}

@keyframes lp-ring {
    from {
        opacity: 1;
    }

    to {
        opacity: 0;
    }
}

/* --- Proof band --- */
.lp-proof-band {
    background-color: var(--clr-off-white);
    border-bottom: 1px solid var(--clr-border);
    padding: var(--space-lg) 0;
}

.lp-proof {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-md);
    max-width: 880px;
    margin: 0 auto;
    padding: 0;
    list-style: none;
}

.lp-proof-item {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    font-weight: var(--fw-medium);
    font-size: 0.95rem;
    color: var(--clr-navy);
    text-align: center;
}

.lp-proof-item svg {
    flex: none;
    width: 22px;
    height: 22px;
    color: var(--clr-teal-dark);
}

@media (max-width: 900px) {
    .lp-proof-item {
        flex-direction: column;
        justify-content: flex-start;
        gap: 6px;
        line-height: 1.25;
    }
}

/* --- CALLS TO ACTION ---
   Two per page, both in the main site's own language. Mid-page: a quiet row under the
   includes (no box). Closing: the full-bleed teal .cta-bar that ends every main-site page,
   with navy text so it passes AA (white on teal is 2.2:1). */
.lp-next {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-lg) var(--space-2xl);
    margin-top: var(--space-2xl);
}

.lp-next-title {
    font-family: var(--font-heading);
    font-weight: var(--fw-bold);
    font-size: clamp(1.3rem, 1.1rem + 0.8vw, 1.6rem);
    line-height: 1.2;
    color: var(--clr-navy);
    margin-bottom: var(--space-xs);
    text-wrap: balance;
}

.lp-next-lead {
    color: var(--clr-text-muted);
}

.lp-next-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm) var(--space-md);
}

/* Same height as the 2px-bordered outline button beside it; .btn-accent's soft shadow rather
   than the hero's glow on a white section. */
.lp-next .lp-btn-call {
    border: 2px solid transparent;
    box-shadow: 0 4px 15px rgba(91, 192, 190, 0.4);
}

/* style.css fills .btn-secondary on :hover with no pointer check, so it stays navy after a tap. */
.lp-page--quote .btn-secondary:hover {
    background: transparent;
    color: var(--clr-navy);
}

@media (hover: hover) and (pointer: fine) {
    .lp-page--quote .btn-secondary:hover {
        background: var(--clr-navy);
        color: var(--clr-white);
    }
}

@media (max-width: 768px) {
    .lp-next {
        flex-direction: column;
        align-items: stretch;
        text-align: center;
    }

    .lp-next-actions {
        flex-direction: column;
        width: 100%;
        max-width: 420px;
        margin: 0 auto;
    }

    .lp-next-actions .btn {
        width: 100%;
    }
}

/* Closing band. The shimmer layer needs main.js (not loaded here), so it goes. */
.lp-page--quote .cta-bar::before {
    content: none;
}

.lp-page--quote .cta-bar h2 {
    font-size: clamp(1.6rem, 1.15rem + 1.6vw, 2.25rem);
    color: var(--clr-navy);
    text-wrap: balance;
}

.lp-page--quote .cta-bar .cta-copy-compact {
    max-width: 36em;
    margin: 0 auto var(--space-lg);
    font-size: 1.05rem;
    color: var(--clr-navy);
    opacity: 1;
    text-wrap: balance;
}

.lp-page--quote .cta-bar .cta-actions {
    margin-top: 0;
}

.lp-page--quote .cta-bar .cta-btn-primary {
    color: var(--clr-navy);
}

.lp-page--quote .cta-bar .cta-btn-secondary {
    background: transparent;
    color: var(--clr-navy);
    border-color: var(--clr-navy);
    box-shadow: none;
    backdrop-filter: none;
}

.lp-page--quote .cta-bar .btn svg {
    width: 18px;
    height: 18px;
    flex: none;
}

/* style.css lifts these on any :hover, which sticks after a tap. :not(:active) keeps the
   template's press scale (.lp-page--quote .btn:active) working on touch and mouse. */
.lp-page--quote .cta-bar .btn:not(:active):hover {
    transform: none;
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
    .lp-page--quote .cta-bar .btn:not(:active):hover {
        transform: translateY(-2px);
    }
}

@media (hover: hover) and (pointer: fine) {
    .lp-page--quote .cta-bar .cta-btn-secondary:hover {
        background: var(--clr-navy);
        color: var(--clr-white);
    }
}

/* 0,4,0 beats style.css's white 1.35:1 halo (.cta-bar .cta-btn-*:focus-visible, 0,3,0). */
.lp-page--quote .cta-bar .btn:focus-visible {
    outline: 3px solid var(--clr-navy);
    outline-offset: 3px;
    box-shadow: none;
}

/* Phones: as wide as the hero call button (style.css caps these at 320px). */
@media (max-width: 768px) {
    .lp-page--quote .cta-bar .cta-actions .btn {
        max-width: 420px;
    }
}

.lp-close-note {
    margin-top: var(--space-md);
    font-size: 0.9rem;
    color: var(--clr-navy);
}

/* --- CTA moments: phone in a navy disc. When a block's call button is first fully on screen
   (JS adds .is-inview) the phone rings, an outline leaves the button, the band motif plays.
   Transform/opacity only, done in 3s, no loops, no motion under reduced motion or in print. */
.lp-next .lp-btn-call svg,
.lp-page--quote .cta-bar .cta-btn-primary svg {
    width: 30px;
    height: 30px;
    margin: -6px 0 -6px -6px;
    padding: 7px;
    border-radius: 50%;
    background-color: var(--clr-navy);
    color: var(--lp-icon, var(--clr-white));
}

.lp-next {
    --lp-icon: var(--clr-teal);
    --lp-halo: var(--clr-teal-dark);
    position: relative;
    padding-top: var(--space-xl);
    border-top: 1px solid var(--clr-border);
}

.lp-next::before {
    content: '';
    position: absolute;
    top: -2px;
    left: 0;
    width: 72px;
    height: 3px;
    border-radius: 3px;
    background: var(--gradient-accent);
    transform-origin: 0 0;
}

.lp-next .lp-btn-call,
.lp-page--quote .cta-bar .cta-btn-primary {
    overflow: visible;
}

.lp-next .lp-btn-call::after,
.lp-page--quote .cta-bar .cta-btn-primary::after {
    content: '';
    position: absolute;
    inset: -2px;
    border: 2px solid var(--lp-halo, var(--clr-white));
    border-radius: inherit;
    opacity: 0;
    pointer-events: none;
}

/* Band motif per page (CTA_ART in build_landers.py). Rain is white: it only lightens the teal. */
.cta-motif {
    position: absolute;
    inset: 0;
    overflow: hidden;
    color: var(--clr-navy);
    opacity: var(--lp-motif-o, 0.3);
    pointer-events: none;
    content-visibility: auto;
}

.cta-motif svg {
    position: absolute;
}

.cta-motif--rain {
    --lp-motif-o: 0.2;
    color: var(--clr-white);
    mask-image: linear-gradient(90deg, #000 18%, transparent 36% 64%, #000 82%);
}

.cta-motif--rain svg {
    top: -117px;
    left: 0;
    width: calc(100% + 30px);
    height: calc(100% + 117px);
}

.cta-motif--sun {
    --lp-motif-o: 0.55;
    --lp-sun: clamp(220px, 26vw, 360px);
    color: var(--clr-white);
}

.cta-motif--sun svg {
    right: max(-48px, calc(50% - 660px));
    bottom: calc(var(--lp-sun) / -2);
    width: var(--lp-sun);
    height: var(--lp-sun);
}

.cta-motif--screens svg {
    top: 50%;
    left: 6%;
    width: 150px;
    height: 197px;
    margin-top: -98px;
    transform: rotate(var(--lp-tilt, -6deg));
}

.cta-motif--screens svg + svg {
    --lp-tilt: 5deg;
    left: auto;
    right: 6%;
    width: 130px;
    height: 171px;
    margin-top: -85px;
}

.cta-motif--lights {
    --lp-motif-o: 1;
    bottom: auto;
    height: clamp(45px, 5vw + 26px, 64px);
}

.cta-motif--lights svg {
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

/* Washing: a white spray fan from each bottom corner, clear of the centered copy. */
.cta-motif--spray {
    --lp-motif-o: 0.5;
    --lp-spray: clamp(120px, 17vw, 250px);
    color: var(--clr-white);
}

.cta-motif--spray svg {
    bottom: 0;
    left: 0;
    width: var(--lp-spray);
    height: calc(var(--lp-spray) * 0.75);
    transform-origin: 0 100%;
}

.cta-motif--spray svg + svg {
    --lp-tilt: 10deg;
    left: auto;
    right: 0;
    transform-origin: 100% 100%;
}

/* Windows: two four-pane windows beside the copy, each with two long glints on the glass. */
.cta-motif--glass {
    --lp-motif-o: 0.35;
}

.cta-motif--glass svg {
    top: 50%;
    left: 6%;
    width: 136px;
    height: 170px;
    margin-top: -85px;
}

.cta-motif--glass svg + svg {
    left: auto;
    right: 6%;
    width: 116px;
    height: 145px;
    margin-top: -72px;
}

/* Below 1200px the screens peek in from the top corners, clear of the copy. */
@media (max-width: 1199px) {
    .cta-motif--screens svg,
    .cta-motif--screens svg + svg {
        top: -108px;
        left: -50px;
        margin: 0;
        width: 118px;
        height: 155px;
    }

    .cta-motif--screens svg + svg {
        left: auto;
        right: -50px;
    }

    /* The windows hang down from the top corners: their lower panes, glints and sills show. */
    .cta-motif--glass svg,
    .cta-motif--glass svg + svg {
        top: -96px;
        left: -34px;
        margin: 0;
        width: 112px;
        height: 140px;
    }

    .cta-motif--glass svg + svg {
        left: auto;
        right: -34px;
    }
}

@media (max-width: 900px) {
    .cta-motif--rain {
        --lp-rain-peak: 0.45;
        mask-image: linear-gradient(#000, transparent 70%);
    }
}

/* Phones and small tablets: the buttons and note fill the bottom, so the spray layer flips
   and the fans come down from the top corners, beside the heading. */
@media (max-width: 768px) {
    .cta-motif--spray {
        --lp-spray: 100px;
        transform: scaleY(-1);
    }
}

/* Under 360px the fans shrink and lift (the layer is flipped, so bottom moves them up) to stay
   clear of the heading's first line. */
@media (max-width: 359px) {
    .cta-motif--spray {
        --lp-spray: 84px;
    }

    .cta-motif--spray svg {
        bottom: -10px;
    }
}

/* Small phones: the heading starts closer to the top corners, so the windows shrink and lift. */
@media (max-width: 479px) {
    .cta-motif--glass svg,
    .cta-motif--glass svg + svg {
        top: -92px;
        width: 100px;
        height: 125px;
    }
}

@media (max-width: 768px) {
    .lp-next::before {
        left: calc(50% - 36px);
        transform-origin: 50% 0;
    }

    .lp-next,
    .cta-bar {
        --lp-halo-sx: 1.06;
    }
}

@media screen and (prefers-reduced-motion: no-preference) {
    .is-armed:not(.is-inview) :is(.cta-motif, .cta-lit) {
        opacity: 0;
    }

    .lp-next.is-armed:not(.is-inview)::before {
        transform: scaleX(0);
    }

    .lp-next.is-inview::before {
        animation: lp-cta-draw 0.8s cubic-bezier(0.65, 0, 0.35, 1) backwards;
    }

    .is-inview :is(.lp-btn-call, .cta-btn-primary) svg {
        animation: lp-cta-phone 1.1s ease-in-out 0.35s;
    }

    .is-inview :is(.lp-btn-call, .cta-btn-primary)::after {
        animation: lp-cta-halo 1.1s ease-out 0.35s;
    }

    /* The band rings twice, with one small swell of the button. */
    .cta-bar.is-inview .cta-btn-primary {
        animation: lp-cta-bump 0.7s cubic-bezier(0.3, 0.7, 0.4, 1) 0.5s backwards;
    }

    .cta-bar.is-inview .cta-btn-primary svg,
    .cta-bar.is-inview .cta-btn-primary::after {
        animation-delay: 0.5s;
        animation-iteration-count: 2;
    }

    .cta-bar.is-inview .cta-motif {
        animation: lp-cta-fade 0.9s ease-out backwards;
    }

    .cta-bar.is-inview .cta-motif--rain {
        animation: lp-cta-rain-in 1.4s linear backwards;
    }

    .cta-bar.is-inview .cta-motif--rain svg {
        animation: lp-cta-rain 0.7s linear 2;
    }

    .cta-bar.is-inview .cta-motif--sun svg {
        animation: lp-cta-rise 2s cubic-bezier(0.2, 0.6, 0.3, 1) backwards;
    }

    .cta-bar.is-inview .cta-motif--screens svg {
        animation: lp-cta-taut 0.9s cubic-bezier(0.2, 0.8, 0.3, 1) backwards;
    }

    .cta-bar.is-inview .cta-motif--screens svg + svg {
        animation-delay: 0.15s;
    }

    /* The fan swings up into place from its nozzle; its droplet rows fade in outward (.cta-lit). */
    .cta-bar.is-inview .cta-motif--spray svg {
        animation: lp-cta-spray 1.1s cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
    }

    /* Each window's glints sweep in across the glass once and settle (the pane clips them). */
    .cta-bar.is-inview .cta-glint {
        animation: lp-cta-glint 1.1s cubic-bezier(0.25, 0.7, 0.3, 1) calc(0.35s + var(--d) * 0.25s) backwards;
    }

    .cta-bar.is-inview .cta-lit {
        animation: lp-cta-fade 0.45s ease-out calc(0.3s + var(--d) * 75ms) backwards;
    }

    /* Hero: one ring a beat after load. Sticky bar: one ring the first time it slides in. */
    .lp-hero .lp-actions .lp-btn-call svg {
        animation: lp-cta-phone 1.1s ease-in-out 1.4s;
    }

    .lp-bar.is-ringing .lp-bar-call svg {
        animation: lp-cta-phone 1.1s ease-in-out 0.3s;
    }

    /* Replays ring the glyph, not the svg, so leaving can't restart the one-time ring. */
    :is(.lp-btn-call, .cta-btn-primary) path {
        transform-box: fill-box;
        transform-origin: 50% 50%;
    }

    :is(.lp-btn-call, .cta-btn-primary):focus-visible path {
        animation: lp-cta-phone 0.9s ease-in-out;
    }
}

@media screen and (prefers-reduced-motion: no-preference) and (hover: hover) and (pointer: fine) {
    :is(.lp-btn-call, .cta-btn-primary):hover path {
        animation: lp-cta-phone 0.9s ease-in-out;
    }
}

@keyframes lp-cta-phone {
    0%, 42%, 100% { transform: none; }
    6% { transform: rotate(-16deg); }
    13% { transform: rotate(14deg); }
    20% { transform: rotate(-12deg); }
    27% { transform: rotate(9deg); }
    34% { transform: rotate(-5deg); }
}

@keyframes lp-cta-halo {
    0% { opacity: 0; transform: none; }
    8% { opacity: 0.9; }
    70%, 100% { opacity: 0; transform: scale(var(--lp-halo-sx, 1.08), 1.35); }
}

@keyframes lp-cta-bump {
    30% { transform: scale(1.04); }
    62% { transform: scale(0.99); }
}

@keyframes lp-cta-draw {
    from { transform: scaleX(0); }
}

@keyframes lp-cta-fade {
    from { opacity: 0; }
}

@keyframes lp-cta-rain {
    to { transform: translate(-29px, 116.4px); }
}

@keyframes lp-cta-rain-in {
    from { opacity: 0; }
    12%, 50% { opacity: var(--lp-rain-peak, 0.6); }
}

@keyframes lp-cta-rise {
    from { transform: translateY(48px) rotate(-15deg); }
}

@keyframes lp-cta-spray {
    from { transform: rotate(calc(var(--lp-tilt, -10deg) * -1)) scale(0.6); }
}

@keyframes lp-cta-glint {
    from { transform: translateX(-170px); }
}

@keyframes lp-cta-taut {
    from { opacity: 0; transform: rotate(calc(var(--lp-tilt, -6deg) - 5deg)) scale(0.9); }
    60% { opacity: 1; transform: rotate(calc(var(--lp-tilt, -6deg) + 1deg)) scale(1.02); }
}

/* --- Sticky call bar (phones) --- */
.lp-bar {
    display: none;
}

@media (max-width: 768px), (orientation: landscape) and (max-height: 500px) {
    .lp-bar {
        display: flex;
        gap: var(--space-sm);
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 900;
        padding: 8px var(--gutter) calc(8px + env(safe-area-inset-bottom, 0px));
        background: var(--clr-white);
        box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.12);
        transition: transform 0.22s ease, visibility 0s linear 0s;
    }

    .lp-bar.is-hidden {
        transform: translateY(110%);
        visibility: hidden;
        transition: transform 0.22s ease, visibility 0s linear 0.22s;
    }

    .lp-bar .btn {
        flex: 1;
        min-height: 48px;
        padding: var(--space-sm) var(--space-md);
        font-size: 0.9rem;
        justify-content: center;
    }

    .lp-bar-cb {
        background: var(--clr-white);
        color: var(--clr-navy);
        border: 2px solid var(--clr-navy);
    }

    .lp-bar.is-call-only .lp-bar-cb {
        display: none;
    }

    body.no-scroll .lp-bar {
        display: none;
    }

    .lp-page--quote .site-footer {
        padding-bottom: calc(80px + env(safe-area-inset-bottom, 0px));
    }
}

/* --- Real job photos ---------------------------------------------------------
   Every photo on the landers is ours. Below-the-fold ones are lazy, so a phone's
   first load is unchanged. */

/* Hero photo: always AFTER the call button and the quote card, so it never pushes
   either down. Phones and tablets: a rounded photo under the card. Desktop: a wide
   band across both columns (a separate wide crop via <picture>), so the subject is
   never hidden behind the card. */
.lp-hero-photo {
    margin: 0;
    position: relative;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background-color: var(--clr-navy-light);
    box-shadow: var(--shadow-xl);
}

.lp-hero-photo img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    object-position: var(--lp-photo-pos, 50% 50%);
}

/* A navy plate in the photo's bottom-left corner, the same corner-tab shape as the Before/After
   tags, led by the captions' teal tick. White on 88% navy is 10:1 or better over any photo. */
.lp-hero-photo figcaption {
    position: absolute;
    left: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: calc(100% - 48px);
    padding: 9px 16px 9px 14px;
    border-radius: 0 12px 0 0;
    background: rgba(28, 37, 65, 0.88);
    color: var(--clr-white);
    font-size: 0.8rem;
    font-weight: var(--fw-medium);
    line-height: 1.35;
    text-wrap: balance;
}

.lp-hero-photo figcaption::before {
    content: '';
    flex: none;
    width: 16px;
    height: 2px;
    background-color: var(--clr-teal);
}

@media (min-width: 901px) {
    .lp-hero-photo {
        grid-column: 1 / -1;
    }

    .lp-hero-photo img {
        aspect-ratio: 2.6 / 1;
    }

    .lp-hero-photo figcaption {
        padding: 11px 20px 11px 18px;
        border-radius: 0 14px 0 0;
        font-size: 0.88rem;
    }
}

/* Christmas hero (Jackson 2026-10-22): our installs as a sideways row, so people can swipe
   through the work before they scroll on. Same grid slot as .lp-hero-photo, still after the
   call button and the card. The arrows and dots are the gallery's (landing-quote.js), shown
   at every width here because this row always scrolls. One and a half photos show from
   tablet up and one plus a peek on phones, so every dot can be reached. */
.lp-hero-row {
    min-width: 0;   /* a grid item: without this the row would widen the column */
}

.lp-gallery.lp-gallery--hero {
    position: relative;
    display: flex;
    gap: var(--space-lg);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
}

.lp-gallery--hero::-webkit-scrollbar {
    display: none;
}

.lp-gallery.lp-gallery--hero .lp-shot {
    position: relative;
    flex: 0 0 calc((100% - var(--space-lg)) / 1.6);
    overflow: hidden;
    aspect-ratio: 3 / 2;
    border-radius: var(--radius-lg);
    background-color: var(--clr-navy-light);
    scroll-snap-align: start;
}

/* Photos 3 to 5 wait until the row is swiped, stepped or focused (landing-quote.js adds .is-live):
   lazy loading alone still fetched them, because they sit inside its margin. */
.lp-gallery--hero:not(.is-live) .lp-shot:nth-child(n+3) img {
    display: none;
}

.lp-page--quote .lp-gallery--hero .lp-shot img {
    aspect-ratio: 3 / 2;
    border-radius: 0;
    box-shadow: none;
    content-visibility: visible;
}

/* On the photo, as on the single hero photo: a navy corner plate led by the teal tick. */
.lp-gallery--hero .lp-shot figcaption {
    position: absolute;
    left: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: calc(100% - 32px);
    margin: 0;
    padding: 9px 16px 9px 14px;
    border-radius: 0 12px 0 0;
    background: rgba(28, 37, 65, 0.88);
    color: var(--clr-white);
    font-size: 0.8rem;
    font-weight: var(--fw-medium);
    line-height: 1.35;
    text-wrap: balance;
}

.lp-gallery--hero .lp-shot figcaption::before {
    position: static;
    flex: none;
    width: 16px;
    height: 2px;
    background: var(--clr-teal);
}

@media (min-width: 901px) {
    .lp-gallery--hero .lp-shot figcaption {
        padding: 11px 20px 11px 18px;
        border-radius: 0 14px 0 0;
        font-size: 0.88rem;
    }
}

@media (max-width: 640px) {
    .lp-gallery.lp-gallery--hero {
        gap: var(--space-md);
    }

    .lp-gallery.lp-gallery--hero .lp-shot {
        flex-basis: 84%;
    }
}

/* The smallest phones: a smaller plate, so the caption stays on one line and off the lights. */
@media (max-width: 360px) {
    .lp-gallery--hero .lp-shot figcaption {
        gap: 8px;
        padding: 7px 12px 7px 10px;
        font-size: 0.72rem;
    }

    .lp-gallery--hero .lp-shot figcaption::before {
        width: 12px;
    }
}

.lp-hero-row .lp-gallery-nav {
    display: flex;
}

/* Work sections: before/after pairs, design-to-install, galleries, the crew. */
.lp-work {
    background-color: var(--clr-white);
}

/* The photos in these sections sit far below the fold: skip laying them out until they come
   near, so their lazy images are not pulled into the first page load. Only the photo boxes,
   never the captions, so contrast checkers can still see the text on the dark band. */
.lp-page--quote .lp-ba-pair,
.lp-page--quote .lp-shot img {
    content-visibility: auto;
    contain-intrinsic-size: auto 400px;
}

/* Dark, so a photo section never runs into the white or off-white section beside it,
   and night shots and blue skies both read well on it. */
.lp-work--dark {
    background-color: var(--clr-navy);
    background-image: var(--gradient-primary);
}

.lp-work--dark .lp-section-title,
.lp-work--dark .lp-work-subhead {
    color: var(--clr-white);
}

.lp-work--dark .lp-section-lead {
    color: rgba(255, 255, 255, 0.78);
}

.lp-work--dark .lp-ba-pair,
.lp-work--dark .lp-shot img {
    box-shadow: 0 24px 48px -20px rgba(0, 0, 0, 0.55);
}

.lp-ba-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-2xl) var(--space-xl);
}

@media (max-width: 768px) {
    .lp-ba-list {
        grid-template-columns: minmax(0, 1fr);
    }
}

.lp-ba {
    margin: 0;
}

.lp-ba--wide {
    grid-column: 1 / -1;
}

.lp-ba-pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px;
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow-lg);
    background-color: var(--clr-navy);
}

.lp-ba-shot {
    position: relative;
}

.lp-ba-shot img {
    display: block;
    width: 100%;
    height: 100%;
    aspect-ratio: var(--lp-shot-ratio, 3 / 4);
    object-fit: cover;
}

.lp-ba--wide .lp-ba-shot img {
    --lp-shot-ratio: 4 / 3;
}

/* Before/After are two corner tabs that meet at the seam between the shots, so the pair reads
   as one split label hanging from the top edge. Solid fills over bright sky: white on navy
   (15:1), navy on teal (7.4:1). */
.lp-ba-tag {
    position: absolute;
    top: 0;
    right: 0;
    padding: 6px 12px 7px;
    border-radius: 0 0 0 10px;
    background-color: var(--clr-navy);
    color: var(--clr-white);
    font: var(--fw-semibold) 0.7rem/1.2 var(--font-heading);
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.lp-ba-tag--after {
    background-color: var(--clr-teal);
    color: var(--clr-navy);
}

.lp-ba-shot + .lp-ba-shot .lp-ba-tag {
    right: auto;
    left: 0;
    border-radius: 0 0 10px 0;
}

@media (min-width: 769px) {
    .lp-ba-tag {
        padding: 7px 14px 8px;
        font-size: 0.74rem;
    }
}

/* Stacked wide pairs (phones): the seam turns horizontal, so the tabs meet across it. */
@media (max-width: 640px) {
    .lp-ba--wide .lp-ba-shot:first-child .lp-ba-tag {
        top: auto;
        bottom: 0;
        right: auto;
        left: 0;
        border-radius: 0 10px 0 0;
    }
}

/* Photo captions as editorial lines: a hairline the width of the photo with a short teal lead,
   the bold lead-in as a small Outfit line, then the description. Real figcaption text, AA on light
   (navy 14:1, muted 4.8:1) and on the dark band (white 15:1, 80% white 8:1+). */
:is(.lp-ba, .lp-shot) figcaption {
    --lp-cap-rule: var(--clr-border);
    --lp-cap-lead: var(--clr-teal-dark);
    position: relative;
    margin-top: var(--space-md);
    padding-top: 14px;
    color: var(--clr-text-muted);
    font-size: 0.9rem;
    line-height: 1.5;
    text-wrap: pretty;
}

:is(.lp-ba, .lp-shot) figcaption::before {
    content: '';
    position: absolute;
    inset: 0 0 auto;
    height: 2px;
    background: linear-gradient(var(--lp-cap-lead) 0 0) 0 0 / 28px 2px no-repeat,
        linear-gradient(var(--lp-cap-rule) 0 0) 0 0 / 100% 1px no-repeat;
}

:is(.lp-ba, .lp-shot) figcaption strong {
    display: block;
    margin-bottom: 2px;
    font: var(--fw-semibold) 1.05rem/1.3 var(--font-heading);
    color: var(--clr-navy);
}

.lp-work--dark :is(.lp-ba, .lp-shot) figcaption {
    --lp-cap-rule: rgba(255, 255, 255, 0.16);
    --lp-cap-lead: var(--clr-teal);
    color: rgba(255, 255, 255, 0.8);
}

.lp-work--dark :is(.lp-ba, .lp-shot) figcaption strong {
    color: var(--clr-white);
}

@media (max-width: 640px) {
    :is(.lp-ba, .lp-shot) figcaption {
        margin-top: 12px;
        padding-top: 12px;
        font-size: 0.875rem;
    }

    :is(.lp-ba, .lp-shot) figcaption strong {
        font-size: 1rem;
    }
}

.lp-gallery {
    display: grid;
    grid-template-columns: repeat(var(--lp-cols, 2), minmax(0, 1fr));
    gap: var(--space-xl);
}

.lp-gallery--3 {
    --lp-cols: 3;
}

.lp-shot {
    margin: 0;
}

.lp-shot img {
    display: block;
    width: 100%;
    aspect-ratio: var(--lp-shot-ratio, 3 / 2);
    object-fit: cover;
    object-position: var(--lp-photo-pos, 50% 50%);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    background-color: var(--clr-navy-light);
}

.lp-gallery--portrait .lp-shot img {
    --lp-shot-ratio: 4 / 5;
}

.lp-work-subhead {
    margin: var(--space-3xl) 0 var(--space-xl);
    text-align: center;
    color: var(--clr-navy);
    font-size: 1.35rem;
}

/* Phones: galleries become a swipeable row (the next photo peeks in, so it reads as
   swipeable) instead of a long stack of photos. */
@media (max-width: 640px) {
    .lp-gallery {
        display: flex;
        gap: var(--space-md);
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        overscroll-behavior-x: contain;
        margin-inline: calc(var(--gutter) * -1);
        padding: 0 var(--gutter) var(--space-sm);
        scroll-padding-inline: var(--gutter);
        scrollbar-width: none;
    }

    .lp-gallery::-webkit-scrollbar {
        display: none;
    }

    .lp-gallery .lp-shot {
        flex: 0 0 82%;
        scroll-snap-align: start;
    }

    /* Offsets for the arrows (landing-quote.js) are measured against the row itself. */
    .lp-gallery {
        position: relative;
    }


    .lp-gallery--portrait .lp-shot {
        flex-basis: 68%;
    }

    .lp-ba-list {
        gap: var(--space-xl);
    }

    /* Landscape pairs stack, so each shot gets the full width instead of a postage stamp. */
    .lp-ba--wide .lp-ba-pair {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* --- Quote template responsive --- */
@media (max-width: 768px) {
    .lp-quote {
        padding: var(--space-lg);
    }

    .lp-step-q {
        font-size: 1.2rem;
    }
}

/* Phones: get the first question on the first screen. */
@media (max-width: 520px) {
    .lp-page--quote .lp-hero {
        padding-bottom: var(--space-xl);
    }

    .lp-page--quote .lp-hero-grid--quote {
        gap: var(--space-md);
    }

    .lp-page--quote .lp-eyebrow {
        margin-bottom: var(--space-sm);
        font-size: 0.78rem;
    }

    .lp-page--quote .lp-hero-title {
        font-size: 2rem;
        margin-bottom: var(--space-sm);
    }

    .lp-page--quote .lp-hero-sub {
        font-size: 1rem;
        margin-bottom: var(--space-md);
    }

    .lp-page--quote .lp-actions {
        margin-bottom: var(--space-sm);
    }

    .lp-page--quote .lp-actions .btn-lg {
        padding: var(--space-md) var(--space-lg);
        min-height: 56px;
    }

    .lp-page--quote .lp-rating {
        margin-top: var(--space-sm);
    }

    .lp-trust-facts {
        display: none;
    }

    .lp-quote {
        padding: var(--space-md);
    }

    .lp-quote-sub,
    .lp-quote-step:first-child .lp-step-help {
        display: none;
    }

    .lp-quote-step:first-child .lp-step-q {
        margin-bottom: var(--space-md);
    }

    .lp-proof {
        gap: var(--space-sm);
    }

    .lp-proof-item {
        flex-direction: column;
        gap: 6px;
        font-size: 0.82rem;
        line-height: 1.25;
    }
}

/* Very small phones: keep "CALL (530) 782-3393" on one line. */
@media (max-width: 380px) {
    .lp-page--quote .btn {
        padding-inline: var(--space-md);
        letter-spacing: 0;
    }
}

/* 320-360px phones: keep both sticky-bar labels ("Call now", "Schedule a call") on one line. */
@media (max-width: 360px) {
    .lp-page--quote .lp-bar .btn {
        padding-inline: 10px;
        font-size: 0.8rem;
        white-space: nowrap;
    }
}

/* Landscape phones: card beside the copy, so the call button and Q1 share a screen. */
@media (orientation: landscape) and (max-height: 500px) {
    :root {
        --lp-header-h: 72px;
    }

    .lp-page--quote .site-header .brand-logo img {
        height: 64px !important;
    }

    .lp-page--quote .site-header .nav-wrapper {
        min-height: 0;
    }

    .lp-page--quote .lp-eyebrow {
        display: none;
    }

    .lp-page--quote .lp-hero-title {
        font-size: 1.75rem;
    }

    .lp-page--quote .lp-hero-grid--quote {
        grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
        gap: var(--space-xl);
    }

    .lp-page--quote .lp-actions .btn {
        width: 100%;
        white-space: nowrap;
        padding-inline: 12px;
        font-size: 0.9rem;
    }

    .lp-page--quote .lp-hero-sub {
        display: none;
    }

    .lp-bar {
        padding-top: 4px;
        padding-bottom: calc(4px + env(safe-area-inset-bottom, 0px));
    }
}

/* --- Reduced motion: no transforms, no entrance, no ring --- */
@media (prefers-reduced-motion: reduce) {
    .lp-btn-call,
    .lp-page--quote .btn,
    .lp-option,
    .lp-window,
    .lp-day,
    .lp-asap,
    .lp-progress-seg,
    .lp-option::after {
        transition: none;
    }

    .lp-option:hover::after {
        transform: rotate(45deg);
    }

    .lp-btn-call:hover,
    .lp-page--quote .btn:active,
    .lp-option:active,
    .lp-window:active,
    .lp-day:active,
    .lp-asap:active {
        transform: none;
    }

    .lp-quote.is-started .lp-quote-step:not(.is-hidden) {
        animation: none;
    }

    .lp-quote.is-arriving::after {
        animation: none;
        opacity: 0;
    }

    .lp-bar,
    .lp-bar.is-hidden {
        transition: none;
    }
}

/* --- ROTATING GOOGLE REVIEWS (DESIGN SPEC F; markup built by js/lp-reviews.js) --- */
/* After the white includes section (gutter, screens) the reviews skip their own top padding
   to avoid a doubled white gap. After a dark work section (solar, Christmas) they keep it.
   lp-reviews.js swaps the anchor for the section, so this sibling test sees the real neighbour. */
.section:not(.lp-work--dark) + .lp-reviews {
    padding-top: 0;
}

/* A quote set across the full 1280px container runs ~150 characters a line on desktop.
   880px keeps a review near 90 characters a line and centers the block. */
.lp-reviews .container {
    max-width: 880px;
}

.lp-reviews-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-sm) var(--space-lg);
    margin-bottom: var(--space-lg);
}

.lp-reviews-all {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-weight: var(--fw-semibold);
    color: var(--clr-navy);
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* Every slide sits in one grid cell: the stage is as tall as the tallest slide, so rotation
   never shifts layout. */
.lp-review-stage {
    display: grid;
}

.lp-review {
    grid-area: 1 / 1;
    margin: 0;
    padding: var(--space-xl);
    background: var(--clr-white);
    border: 1px solid var(--clr-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.5s ease, visibility 0s linear 0.5s;
}

.lp-review.is-active {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.5s ease;
}

.lp-review-stars {
    display: flex;
    gap: 2px;
    margin-bottom: var(--space-sm);
}

/* A filled star and an empty one differ in shape, not only in color: the empty star is a slate
   outline (4.8:1 on white). A light grey fill would be ~1.1:1 against the gold and read as a
   5-star review. The gold stroke keeps both stars the same size. */
.lp-review-stars svg {
    width: 18px;
    height: 18px;
    fill: #FBBF24;
    stroke: #FBBF24;
    stroke-width: 1.5;
    stroke-linejoin: round;
}

.lp-review-stars svg.is-off {
    fill: none;
    stroke: var(--clr-text-muted);
}

.lp-review blockquote p {
    font-size: 1.05rem;
    line-height: 1.6;
    color: var(--clr-text-body);
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 6;
    overflow: hidden;
}

.lp-review figcaption {
    margin-top: var(--space-md);
    font-size: 0.9rem;
    color: var(--clr-text-muted);
}

.lp-review figcaption a {
    color: var(--clr-navy);
    font-weight: var(--fw-semibold);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.lp-review-controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    margin-top: var(--space-md);
}

.lp-review-dots {
    display: flex;
}

.lp-review-pause,
.lp-review-dots button {
    min-width: 44px;
    min-height: 44px;
    display: grid;
    place-items: center;
    background: none;
    border: 0;
    cursor: pointer;
}

.lp-review-pause svg {
    width: 20px;
    height: 20px;
    fill: var(--clr-navy);
}

/* Inactive dot is a ring and the current one is filled: shape, not color alone, marks the
   state, and the slate ring is 4.8:1 on white (the spec's --clr-border-strong fill is 1.5:1). */
.lp-review-dots button::before {
    content: '';
    width: 10px;
    height: 10px;
    border-radius: 50%;
    box-shadow: inset 0 0 0 2px var(--clr-text-muted);
}

.lp-review-dots button[aria-current="true"]::before {
    background: var(--clr-navy);
    box-shadow: none;
}

.lp-reviews :focus-visible {
    outline: 3px solid var(--clr-navy);
    outline-offset: 2px;
}

.lp-reviews-attrib {
    margin-top: var(--space-sm);
    text-align: center;
    font-size: 0.8rem;
    color: var(--clr-text-muted);
}

@media (hover: hover) and (pointer: fine) {
    .lp-review-dots button:hover::before {
        box-shadow: inset 0 0 0 2px var(--clr-navy);
    }
}

@media (max-width: 768px) {
    .lp-review {
        padding: var(--space-lg);
    }

    .lp-review blockquote p {
        -webkit-line-clamp: 7;
    }
}

@media (prefers-reduced-motion: reduce) {
    .lp-review,
    .lp-review.is-active {
        transition: none;
    }
}

/* --- SERVICE AREA ---
   A real map: OpenStreetMap data rendered offline to two WebPs (no map library, no third-party
   request), the service area and our I-5 route as a tiny lazy SVG overlay, towns pointed out in HTML
   and listed beside it with distance and ZIPs. No buttons: the closing band sits right below. */
.lp-area-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-xl);
}

.lp-area-head {
    margin: 0 auto;
    text-align: center;
}

.lp-area-head .lp-section-lead {
    text-wrap: pretty;
}

.lp-map {
    position: relative;
    justify-self: center;
    width: 100%;
    max-width: 440px;
    margin: 0;
    aspect-ratio: 1000 / 1533;
    overflow: hidden;
    border: 1px solid var(--clr-border-strong);
    border-radius: var(--radius-lg);
    background: #EFF2F5;
    box-shadow: 0 24px 48px -28px rgba(28, 37, 65, 0.35);
}

.lp-map img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

.lp-map-marks > * {
    position: absolute;
    left: var(--x);
    top: var(--y);
    white-space: nowrap;
}

/* Town pins: dot on the town, label on the side away from I-5, white halo for legibility. */
.lp-pin {
    padding-right: 14px;
    transform: translate(-100%, -50%);
    text-align: right;
    font: var(--fw-semibold) 0.95rem/1.1 var(--font-heading);
    color: var(--clr-navy);
    text-shadow: 0 0 2px #fff, 0 0 3px #fff, 0 0 6px #fff, 0 0 8px #fff;
}

.lp-pin::after {
    content: '';
    position: absolute;
    top: 50%;
    right: -7px;
    width: 14px;
    height: 14px;
    margin-top: -7px;
    border-radius: 50%;
    background: var(--clr-navy);
    box-shadow: 0 0 0 2.5px #fff, 0 1px 5px 2px rgba(15, 23, 42, 0.3);
}

.lp-pin--right {
    padding: 0 0 0 14px;
    transform: translate(0, -50%);
    text-align: left;
}

.lp-pin--right::after {
    right: auto;
    left: -7px;
}

.lp-pin--base::after {
    right: -9px;
    width: 18px;
    height: 18px;
    margin-top: -9px;
    background: var(--clr-teal);
}

.lp-pin small {
    display: block;
    font: var(--fw-semibold) 0.7rem/1.3 var(--font-body);
    color: #2B7A78;
}

.lp-map-water {
    transform: translate(-50%, -50%);
    text-align: center;
    font: italic var(--fw-medium) 0.7rem/1.15 var(--font-body);
    letter-spacing: 0.04em;
    color: #245A6E;
    text-shadow: 0 0 3px rgba(255, 255, 255, 0.9);
}

.lp-map-shield {
    width: 22px;
    height: 22px;
    transform: translate(-50%, -50%);
    border: 2px solid #fff;
    border-radius: 5px 5px 11px 11px;
    background: var(--clr-navy);
    color: #fff;
    font: var(--fw-bold) 0.75rem/18px var(--font-heading);
    text-align: center;
    box-shadow: 0 1px 3px rgba(15, 23, 42, 0.3);
}

.lp-map .lp-map-scale {
    left: 12px;
    top: auto;
    bottom: 10px;
    width: 31.75%;
    font: var(--fw-semibold) 0.68rem/1 var(--font-body);
    color: var(--clr-navy);
    text-shadow: 0 0 3px #fff, 0 0 3px #fff;
}

.lp-map-scale::after {
    content: '';
    display: block;
    height: 5px;
    margin-top: 3px;
    border: 2px solid var(--clr-navy);
    border-top: 0;
}

/* ODbL credit, as maps carry it: small, bottom right. */
.lp-map-credit {
    position: absolute;
    right: 0;
    bottom: 0;
    padding: 3px 8px;
    border-top-left-radius: var(--radius-md);
    background: rgba(255, 255, 255, 0.88);
    font-size: 0.68rem;
    color: var(--clr-text-body);
}

.lp-map-credit a {
    color: inherit;
    text-decoration: underline;
}

/* The towns as a route strip: the teal line is the same teal route drawn on the map. */
.lp-route {
    position: relative;
    margin: 0;
    padding: 0;
    list-style: none;
}

.lp-route::before {
    content: '';
    position: absolute;
    left: 6px;
    top: 24px;
    bottom: 24px;
    width: 2px;
    background: var(--clr-teal);
}

.lp-route li {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0 var(--space-md);
    padding: 12px 0 12px 30px;
}

.lp-route li::before {
    content: '';
    position: absolute;
    left: 1px;
    top: 50%;
    width: 12px;
    height: 12px;
    margin-top: -6px;
    border-radius: 50%;
    background: var(--clr-navy);
    box-shadow: 0 0 0 3px var(--clr-white);
}

.lp-route li + li::after {
    content: '';
    position: absolute;
    top: 0;
    left: 30px;
    right: 0;
    border-top: 1px solid var(--clr-border);
}

.lp-route .is-base::before {
    left: -1px;
    width: 16px;
    height: 16px;
    margin-top: -8px;
    background: var(--clr-teal);
    box-shadow: 0 0 0 3px var(--clr-white), 0 0 0 4px var(--clr-teal-dark);
}

.lp-route-town {
    font: var(--fw-semibold) 1.05rem/1.3 var(--font-heading);
    color: var(--clr-navy);
}

.lp-route-meta {
    font-size: 0.88rem;
    color: var(--clr-text-muted);
}

.lp-area-note {
    font-size: 0.9rem;
    color: var(--clr-text-muted);
}

@media (min-width: 901px) {
    .lp-area-grid {
        max-width: 1060px;
        grid-template-columns: minmax(0, 1fr) 440px;
        grid-template-rows: 1fr auto auto auto 1fr;
        grid-template-areas: ". map" "head map" "list map" "note map" ". map";
        gap: 0 var(--space-3xl);
    }

    .lp-area-head {
        grid-area: head;
        margin: 0 0 var(--space-lg);
        text-align: left;
    }

    .lp-map {
        grid-area: map;
    }

    .lp-route {
        grid-area: list;
    }

    .lp-area-note {
        grid-area: note;
        margin-top: var(--space-lg);
    }
}

@media (max-width: 900px) {
    .lp-area-note {
        margin-top: calc(var(--space-md) - var(--space-xl));
    }

    .lp-route,
    .lp-area-note {
        width: 100%;
        max-width: 440px;
        justify-self: center;
    }
}

/* The phone photo rows scroll sideways and are focusable; keep their ring inside the edge. */
.lp-page--quote :is(.lp-work--dark, .lp-hero-row) .lp-gallery:focus-visible {
    outline-color: var(--clr-teal);
    outline-offset: -3px;
}

@media (min-width: 641px) {
    .lp-page--quote .lp-hero-row .lp-gallery:focus-visible {
        outline-offset: 4px;
    }
}

@media (max-width: 520px) {
    .lp-pin {
        font-size: 0.9rem;
    }
}

/* Under 360px the lake names crowd the Redding label; the lakes still read as lakes. */
@media (max-width: 359px) {
    .lp-map-water {
        display: none;
    }
}

/* ===========================================================================
   HERO ORDER: call, then "Schedule a call", then the rating and one review
   Two columns (desktop, landscape phones): copy over the rating on the left, the card
   down the right, always open. Stacked (phones, tablets): copy, the toggle, the card
   (folded until the toggle opens it), then the rating and review, so the call, the
   rating and a review share the first screen. Row spacing is margins here, so the rating
   sits right under the copy on desktop whatever height the card grows to.
   =========================================================================== */
.lp-page--quote .lp-hero-grid--quote {
    grid-template-areas: "copy quote" "proof quote" "photo photo";
    grid-template-rows: auto 1fr auto;
    row-gap: 0;
}

.lp-page--quote .lp-hero-copy {
    grid-area: copy;
}

.lp-page--quote .lp-quote {
    grid-area: quote;
}

.lp-page--quote .lp-hero-proof {
    grid-area: proof;
}

.lp-page--quote :is(.lp-hero-photo, .lp-hero-row) {
    grid-area: photo;
    margin-top: var(--space-3xl);
}

.lp-page--quote .lp-hero-proof :focus-visible,
.lp-page--quote .lp-quote-toggle:focus-visible {
    outline-color: var(--clr-teal);
}

/* The toggle: a full-width secondary button under the call button. */
.lp-quote-toggle {
    display: none;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: 56px;
    margin-top: var(--space-md);
    padding: 10px var(--space-md);
    border: 1.5px solid rgba(255, 255, 255, 0.4);
    border-radius: var(--radius-md);
    background: rgba(255, 255, 255, 0.06);
    color: rgba(255, 255, 255, 0.82);
    font: inherit;
    font-size: 0.98rem;
    line-height: 1.3;
    text-align: left;
    cursor: pointer;
}

.lp-quote-toggle b {
    color: var(--clr-white);
    font-family: var(--font-heading);
    font-weight: var(--fw-semibold);
    white-space: nowrap;
}

.lp-quote-toggle svg {
    flex: none;
    width: 20px;
    height: 20px;
}

.lp-quote-toggle-icon {
    color: var(--clr-teal);
}

.lp-quote-toggle-text {
    flex: 1;
}

.lp-quote-toggle-chev {
    color: var(--clr-white);
    transition: transform 0.2s ease;
}

.lp-quote-toggle[aria-expanded="true"] .lp-quote-toggle-chev {
    transform: rotate(180deg);
}

.lp-quote-toggle:active {
    background: rgba(255, 255, 255, 0.12);
}

@media (hover: hover) and (pointer: fine) {
    .lp-quote-toggle:hover {
        border-color: var(--clr-teal);
        background: rgba(255, 255, 255, 0.1);
    }
}

@media (prefers-reduced-motion: reduce) {
    .lp-quote-toggle-chev {
        transition: none;
    }
}

@media (max-width: 1120px) {
    .lp-page--quote :is(.lp-hero-photo, .lp-hero-row) {
        margin-top: var(--space-2xl);
    }
}

/* Stacked: every width that is one column (the landscape-phone layout stays two columns). */
@media (max-width: 900px) and (orientation: portrait), (max-width: 900px) and (min-height: 501px) {
    .lp-page--quote .lp-hero-grid--quote {
        grid-template-areas: "copy" "toggle" "quote" "proof" "photo";
        grid-template-rows: none;
    }

    .lp-quote-toggle {
        display: flex;
        grid-area: toggle;
    }

    .lp-page--quote .lp-quote {
        margin-top: var(--space-sm);
    }

    .lp-page--quote .lp-quote:not(.is-open) {
        display: none;
    }
}

@media (max-width: 520px) {
    .lp-page--quote :is(.lp-hero-photo, .lp-hero-row) {
        margin-top: var(--space-lg);
    }
}

@media (orientation: landscape) and (max-height: 500px) {
    .lp-page--quote :is(.lp-hero-photo, .lp-hero-row) {
        margin-top: var(--space-xl);
    }
}

/* A one-line lead under a gallery subhead. */
.lp-work-sublead {
    max-width: 34em;
    margin: calc(-1 * var(--space-lg)) auto var(--space-xl);
    text-align: center;
}

/* Compact header: the logo is 120px on desktop at the top of the page (96-122px on phones and
   tablets), and once the page scrolls it compacts to 60px at every width (the landscape-phone
   size), so the header takes 64px of the screen. The header is fixed, so nothing below it moves. */
@media (min-width: 1121px) and (min-height: 501px) {
    .lp-page--quote .site-header .brand-logo img {
        height: 120px !important;
    }

    .lp-page--quote .site-header .nav-wrapper {
        min-height: 0;
    }
}

.lp-page--quote .site-header .brand-logo img {
    transition: height 0.2s ease;
}

.lp-page--quote .site-header.scrolled .brand-logo img {
    height: 60px !important;
}

.lp-page--quote .site-header.scrolled .nav-wrapper {
    min-height: 0;
}

@media (prefers-reduced-motion: reduce) {
    .lp-page--quote .site-header .brand-logo img {
        transition: none;
    }
}

/* Phone gallery arrows (landing-quote.js): big Previous / Next buttons with dots between, under
   the swipe row, because not everyone knows to swipe. Only shown on phones (see the 640px
   gallery rule), where the row scrolls. Dark sections get light controls. */
.lp-gallery-nav {
    display: none;
    align-items: center;
    justify-content: center;
    gap: var(--space-lg);
    margin-top: var(--space-md);
}

.lp-gallery-btn {
    display: grid;
    place-items: center;
    width: 48px;
    height: 48px;
    padding: 0;
    border: 2px solid var(--clr-navy);
    border-radius: 50%;
    background: var(--clr-white);
    color: var(--clr-navy);
    cursor: pointer;
}

.lp-gallery-btn svg {
    width: 22px;
    height: 22px;
}

.lp-gallery-btn[aria-disabled="true"] {
    opacity: 0.35;
    cursor: default;
}

.lp-gallery-btn:active:not([aria-disabled="true"]) {
    transform: scale(0.95);
}

.lp-gallery-dots {
    display: flex;
    gap: 8px;
}

.lp-gallery-dots span {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: rgba(28, 37, 65, 0.25);
}

.lp-gallery-dots .is-on {
    background: #2B7A78;
}

:is(.lp-work--dark, .lp-hero-row) .lp-gallery-btn {
    border-color: rgba(255, 255, 255, 0.7);
    background: rgba(255, 255, 255, 0.08);
    color: var(--clr-white);
}

:is(.lp-work--dark, .lp-hero-row) .lp-gallery-dots span {
    background: rgba(255, 255, 255, 0.3);
}

:is(.lp-work--dark, .lp-hero-row) .lp-gallery-dots .is-on {
    background: var(--clr-teal);
}

.lp-page--quote :is(.lp-work--dark, .lp-hero-row) .lp-gallery-btn:focus-visible {
    outline-color: var(--clr-teal);
}

@media (max-width: 640px) {
    .lp-gallery-nav {
        display: flex;
    }
}

/* Skip link: the first stop for keyboard users, off screen until focused. */
.skip-link {
    position: fixed;
    top: 8px;
    left: 8px;
    z-index: 2000;
    padding: 12px 18px;
    border-radius: var(--radius-md);
    background: var(--clr-teal);
    color: var(--clr-navy);
    font-family: var(--font-heading);
    font-weight: 700;
    text-decoration: none;
    transform: translateY(-200%);
}

.skip-link:focus {
    transform: none;
    outline: 3px solid var(--clr-white);
    outline-offset: 2px;
}

main:focus {
    outline: none;
}
