/*
 * styles.css — the whole visual layer of the Companionship Dog Training site.
 *
 * JOB
 *   One stylesheet, no build step, no framework. It styles five templates
 *   (index, services, about-us, contact, 404) that share includes/header.php
 *   and includes/footer.php.
 *
 * INVARIANTS (T-502 visual pass, 2026-09-19)
 *   1. ONE SPACING SCALE. Every gap, pad and margin comes from --space-*.
 *      Do not introduce loose rem values; add a step to the scale instead.
 *   2. ONE CONTENT WIDTH. Header, hero, cards, prose, form and footer all sit
 *      on the same rails: max-width --max plus --gutter either side. The
 *      `.shell` block below is the single definition; everything else uses it.
 *      Four different widths is exactly the misalignment this pass removed.
 *   3. EVERY IMAGE DECLARES ITS RATIO. object-fit + aspect-ratio + a focal
 *      point, so the box the browser reserves is the box that gets painted
 *      (no layout shift) and no dog's head is ever sliced by a fixed height.
 *      The focal points below were chosen against the source photos in
 *      _intake/assets/images — check there before changing one.
 *   4. MOTION IS OPTIONAL. Everything that moves is a transition or a short
 *      fade-up, all of it switched off under prefers-reduced-motion. No
 *      parallax, no autoplay, nothing that moves without the user asking.
 *   5. COLOURS AND VOICE ARE THE CLIENT'S. Teal, orange, charcoal and the
 *      Raleway/Lato pairing are ported from the original site and stay.
 *
 * T-503 REIMAGINING (owner, 2026-09-19)
 *   The reference is the owners' other business, animalinnpetresort.net (style
 *   read: _warroom/tmp/t503-captures/reference-read.md). Nothing was copied
 *   from it. Four of its habits were adopted, using only this site's own
 *   palette, copy and photographs:
 *     a. THE PAGE IS A STACK OF FULL-BLEED BANDS that change surface often —
 *        strip, nav, hero, white lead, soft-teal photo band, card band, dark
 *        call band, footer — instead of one long white rail.
 *     b. CALLS TO ACTION ARE PILLS and one sits centred at the foot of its
 *        own block; the phone number is typed out large beside it instead of
 *        living only in the footer.
 *     c. SECTION HEADINGS ARE TEAL, not near-black, and centred. Teal at
 *        heading sizes is large text, so 4.35:1 clears AA (3:1); do NOT reuse
 *        --teal for body-sized text, which is what --teal-dark is for.
 *     d. THE PHONE IS ALWAYS IN REACH — a slim teal strip above the nav
 *        carries the location and the number on every page.
 *   Everything T-502 established (rails, spacing scale, image ratios, focal
 *   points, reduced-motion contract, contrast fixes) still holds.
 *
 * FAILURE BEHAVIOR
 *   With CSS off the pages are still ordered, readable documents. With JS off
 *   nothing is hidden: the scroll-reveal only arms itself after js/main.js
 *   sets .js-reveal on <html>, so a JS failure leaves every section visible.
 */

:root {
    /* Brand — ported from the original site, do not re-hue. */
    --teal: #248685;
    --teal-light: #7cc1b7;
    --teal-dark: #165f60;
    --orange: #f79631;
    --orange-dark: #a85400;
    --charcoal: #313131;
    --text: #3f4548;
    --heading: #222;
    --muted: #687276;
    --soft: #f4f6f6;
    --line: #e4eaea;
    --white: #fff;

    /* Spacing scale (invariant 1). 4px base, doubling-ish. */
    --space-1: .25rem;
    --space-2: .5rem;
    --space-3: .75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --space-7: 3rem;
    --space-8: 4rem;
    --space-9: 6rem;

    /* Rails (invariant 2). */
    --max: 1120px;
    --gutter: clamp(1.25rem, 3.4vw, 2rem);
    --section-y: clamp(3.25rem, 6.5vw, 5.5rem);
    --measure: 68ch;

    /* Surfaces. One radius scale, three soft shadows. */
    --radius-sm: 6px;
    --radius: 10px;
    --radius-lg: 14px;
    /* T-503: every call to action is a pill. That single shape is the loudest
       thing the owners' Animal Inn site does and the cheapest way for these
       pages to feel like the same family. */
    --radius-pill: 999px;
    --shadow-sm: 0 1px 2px rgba(20, 45, 50, .06), 0 4px 12px rgba(20, 45, 50, .06);
    --shadow-md: 0 2px 6px rgba(20, 45, 50, .06), 0 14px 32px rgba(20, 45, 50, .1);
    --shadow-lg: 0 4px 10px rgba(20, 45, 50, .07), 0 24px 56px rgba(20, 45, 50, .14);
    --ring: 0 0 0 3px rgba(36, 134, 133, .35);

    --ease: cubic-bezier(.22, .61, .36, 1);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
    margin: 0;
    color: var(--text);
    background: var(--white);
    font: 400 18px/1.72 Lato, "Segoe UI", Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; height: auto; }
a { color: var(--teal-dark); transition: color .18s var(--ease); }
a:hover { color: var(--orange-dark); }

/* One visible focus treatment for every interactive thing (D5). */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: 3px solid var(--teal-dark);
    outline-offset: 3px;
    border-radius: var(--radius-sm);
}

h1, h2, h3 {
    color: var(--heading);
    text-wrap: balance;
    font-family: Raleway, "Segoe UI", Arial, sans-serif;
    line-height: 1.18;
    letter-spacing: -.012em;
}
/* Type scale (E1): display sizes tightened so headings lead the body copy
   instead of shouting over it. */
h1 { font-size: clamp(2.1rem, 3.9vw, 3.35rem); }
h2 { font-size: clamp(1.65rem, 2.7vw, 2.35rem); }
h3 { font-size: clamp(1.25rem, 1.5vw, 1.45rem); }
p { margin: 0 0 var(--space-4); max-width: var(--measure); }

.container,
.shell {
    width: 100%;
    max-width: calc(var(--max) + 2 * var(--gutter));
    margin-inline: auto;
    padding-inline: var(--gutter);
}
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.skip-link { position: fixed; left: 1rem; top: -5rem; z-index: 9999; padding: var(--space-3) var(--space-5); color: #fff; background: #111; border-radius: var(--radius-pill); }
.skip-link:focus { top: 1rem; }

/* ---------------------------------------------------------------- header */

/*
 * The utility strip. Its job is one job: the phone number is on every page
 * above the fold without the visitor hunting for the footer. It carries no
 * new words — BUSINESS_LOCATION and CONTACT_PHONE are existing config values.
 * White on --teal-dark is 6.9:1, so it clears AA at this small size.
 */
.topbar { color: #fff; background: var(--teal-dark); font-size: .92rem; }
.topbar-inner {
    width: 100%;
    max-width: calc(var(--max) + 2 * var(--gutter));
    margin-inline: auto;
    padding: var(--space-2) var(--gutter);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2) var(--space-4);
}
.topbar-place { font-weight: 700; letter-spacing: .04em; }
.topbar-call { color: #fff; font-weight: 700; text-decoration: none; }
.topbar-call:hover { color: var(--orange); }

.site-header { position: relative; z-index: 50; background: #fff; border-bottom: 1px solid var(--line); }
.nav-shell {
    width: 100%;
    max-width: calc(var(--max) + 2 * var(--gutter));
    min-height: 104px;
    margin-inline: auto;
    padding-inline: var(--gutter);
    display: flex;
    align-items: center;
    justify-content: center;
}
#primary-nav { display: grid; grid-template-columns: 1fr 1fr 128px 1fr 1fr; align-items: center; width: 100%; gap: var(--space-4); }
#primary-nav > a {
    position: relative;
    padding: var(--space-2) 0;
    /* --teal on white is 4.35:1 at this size — below AA. The darker brand
       teal keeps the same hue family at 6.9:1 (axe color-contrast). */
    color: var(--teal-dark);
    font: 700 1.02rem/1.2 Raleway, "Segoe UI", sans-serif;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    transition: color .18s var(--ease);
}
/* Underline grows from the centre on hover and marks the current page. */
#primary-nav > a:not(.nav-logo)::after {
    content: "";
    position: absolute;
    left: 50%;
    right: 50%;
    bottom: 0;
    height: 2px;
    background: var(--orange);
    transition: left .2s var(--ease), right .2s var(--ease);
}
#primary-nav > a:hover, #primary-nav > a[aria-current="page"] { color: var(--orange-dark); }
#primary-nav > a:hover::after, #primary-nav > a[aria-current="page"]::after { left: 12%; right: 12%; }
#primary-nav .nav-logo { display: flex; align-items: center; justify-content: center; }
#primary-nav .nav-logo img { width: 104px; height: 104px; object-fit: contain; }
.mobile-brand, .mobile-nav-toggle { display: none; }

/* ------------------------------------------------------------- home hero */

/*
 * The hero photo (IMG_0366, 1200x751) has the cream poodle high in the frame
 * and the brown Newfoundland right of centre.
 *
 * T-503 (owner, 2026-09-19): the logo and buttons used to sit off to the left
 * over the photo. They are now CENTRED and stacked — logo above buttons — so
 * the composition is symmetric at every desktop width.
 *
 * Two consequences, both deliberate:
 *   - HEIGHT IS TIED TO WIDTH (45vw). The crop window has to be at least ~66%
 *     of the photo's height to hold the poodle's head and the Newfoundland's
 *     chin at once; below that one of them gets cut, which is what the old
 *     fixed 41rem cap did at 1920. Because 45vw is live at 1280, 1440 AND
 *     1920, the hero crops to exactly the same part of the photo at all three
 *     — the composition does not drift as the window widens.
 *   - THE WASH IS SYMMETRIC, not a left-to-right diagonal. Centred content
 *     lands on the middle of the photo, so the photo is veiled evenly and
 *     given a soft halo behind the badge instead of a bright left edge. The
 *     dogs stay readable at the edges where the veil is thinnest (C3).
 * 32% from the top is the middle of the band in which both dogs survive the
 * crop; do not drift outside 30-34% without re-checking the captures.
 */
.hero-home {
    display: flex;
    align-items: center;
    min-height: clamp(26rem, 45vw, 54rem);
    padding-block: var(--space-7);
    background-image:
        radial-gradient(52% 62% at 50% 46%, rgba(255,255,255,.72) 0%, rgba(255,255,255,.46) 50%, rgba(255,255,255,.12) 82%, rgba(255,255,255,0) 100%),
        linear-gradient(180deg, rgba(255,255,255,.3) 0%, rgba(255,255,255,.42) 38%, rgba(255,255,255,.44) 66%, rgba(255,255,255,.34) 100%),
        url('../assets/images/hero-home.webp');
    background-size: cover;
    background-position: 50% 32%;
    background-repeat: no-repeat;
}
.hero-home .hero-inner {
    width: 100%;
    max-width: calc(var(--max) + 2 * var(--gutter));
    margin-inline: auto;
    padding-inline: var(--gutter);
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}
/*
 * The logo PNG carries an 8.33% transparent margin on EACH side. That margin
 * is symmetric, so once the badge is centred it cancels itself out and the
 * optical centre is the real centre — the negative margin-left that T-502
 * used to pull the badge onto the buttons' left rail (A5) would now push it
 * off centre, so it is gone.
 */
.hero-home .hero-logo {
    --hero-logo-w: clamp(11.5rem, 20vw, 20.5rem);
    width: var(--hero-logo-w);
    height: auto;
    aspect-ratio: 1 / 1;
    object-fit: contain;
}
.hero-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-3); margin-top: var(--space-5); }

/* ------------------------------------------------------------- buttons */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 54px;
    padding: var(--space-3) var(--space-6);
    border: 2px solid transparent;
    border-radius: var(--radius-pill);
    font: 700 .95rem/1.2 Raleway, "Segoe UI", sans-serif;
    letter-spacing: .01em;
    text-decoration: none;
    cursor: pointer;
    transition: background-color .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease), box-shadow .18s var(--ease), transform .18s var(--ease);
}
.btn:hover { transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.btn:active { transform: none; box-shadow: none; }
.btn-primary { color: #fff; background: var(--teal-dark); border-color: var(--teal-dark); }
.btn-primary:hover { color: #1d2426; background: var(--orange); border-color: var(--orange); }
.btn-secondary { color: #202829; background: var(--orange); border-color: var(--orange); }
.btn-secondary:hover { color: #fff; background: var(--orange-dark); border-color: var(--orange-dark); }
.btn-outline { color: var(--teal-dark); background: #fff; border-color: var(--teal); }
.btn-outline:hover { color: #fff; background: var(--teal-dark); border-color: var(--teal-dark); }

/* ------------------------------------------------------------- sections */

.eyebrow { margin-bottom: var(--space-2); color: var(--teal-dark); font: 700 .82rem/1.2 Raleway, sans-serif; letter-spacing: .14em; text-transform: uppercase; }
.section { padding-block: var(--section-y); }
/* Gentle alternation: the tinted band carries a hairline so the change of
   surface reads as a deliberate separator rather than a printing accident. */
.section-soft { background: var(--soft); border-block: 1px solid var(--line); }

/*
 * The intro card overlaps the hero by a third of the scale and sits on the
 * same rails as every other block (A1/A2). Its copy is left-aligned inside
 * the card: the old margin-left:auto pushed the heading out of line with the
 * rest of the page.
 */
.intro-card {
    position: relative;
    z-index: 2;
    width: min(100% - 2 * var(--gutter), var(--max));
    margin: calc(var(--space-7) * -1) auto 0;
    padding: clamp(1.75rem, 4.5vw, 3.5rem);
    background: #fff;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}
.intro-card .intro-copy { max-width: var(--measure); }
.intro-card h2 { margin: 0 0 var(--space-4); }
.intro-card .btn { margin-top: var(--space-2); }
/*
 * Above 60rem the card is wider than a comfortable line length, so the lead
 * splits into heading | paragraph instead of leaving half the card empty.
 * Source order is untouched — this is placement only, so the reading order
 * for assistive tech and for a no-CSS render is unchanged.
 */
@media (min-width: 60rem) {
    .intro-card .intro-copy {
        display: grid;
        grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr);
        column-gap: clamp(2rem, 4vw, 3.5rem);
        align-items: start;
        max-width: none;
    }
    /* Row 2 holds the heading and the paragraph side by side; both are
       start-aligned, so the heading stays tight under its eyebrow however
       long the paragraph runs. */
    .intro-card .intro-copy > .eyebrow { grid-column: 1; grid-row: 1; }
    .intro-card .intro-copy > h2 { grid-column: 1; grid-row: 2; align-self: start; margin-bottom: 0; }
    .intro-card .intro-copy > p:not(.eyebrow) { grid-column: 2; grid-row: 2; align-self: start; max-width: 58ch; }
    .intro-card .intro-copy > .btn { grid-column: 2; grid-row: 3; justify-self: start; margin-top: var(--space-5); }
}

.section-heading { max-width: 46rem; margin: 0 auto var(--space-7); text-align: center; }
.section-heading p { margin-inline: auto; }
/* Teal at h2 sizes (26-38px, 700) is large text: 4.35:1 clears the 3:1 bar. */
.section-heading h1, .section-heading h2 { margin: 0 0 var(--space-3); color: var(--teal); }
.intro-card h2 { color: var(--teal); }

/* ------------------------------------------------- services image + cards */

/*
 * The photo band (T-503). The reference runs photographs full-bleed; this
 * photograph cannot go full-bleed, because it is a 1024x683 close-up whose
 * subject's head alone is 537px tall — stretching it across 1920 slices the
 * dog, which is exactly the defect T-502 fixed (B2/B3). So the BAND goes
 * full-bleed and the photograph keeps its own 3:2 frame inside it. Same
 * rhythm, no re-crop.
 */
.photo-band {
    padding: var(--space-7) var(--gutter);
    background: var(--teal-light);
}
.photo-band img {
    width: min(100%, 52rem);
    margin-inline: auto;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    object-position: center;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}
.services-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-5); }
/*
 * Flex column + margin-top:auto on the button is what actually lines the
 * three "Request Training" buttons up (D1). The old rule set margin-top:auto
 * on a button inside a block container, where it does nothing.
 */
.service-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: var(--space-6) var(--space-5);
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    transition: box-shadow .22s var(--ease), transform .22s var(--ease);
}
.service-card:hover { box-shadow: var(--shadow-md); transform: translateY(-3px); }
.service-card h2, .service-card h3 {
    margin: 0 0 var(--space-5);
    padding-bottom: var(--space-4);
    color: var(--teal);
    font-size: clamp(1.3rem, 1.7vw, 1.55rem);
    text-align: center;
}
/* The reference tops each tile with a round icon medallion. There is no icon
   set in _intake, so the divider does that job: a short centred rule that
   separates the name of the programme from its description. */
.service-card h2::after, .service-card h3::after {
    content: "";
    display: block;
    width: 3rem;
    height: 3px;
    margin: var(--space-4) auto 0;
    background: var(--orange);
    border-radius: var(--radius-pill);
}
.service-card ul { margin: var(--space-4) 0 var(--space-5); padding-left: 1.15rem; }
.service-card li { margin-bottom: var(--space-1); }
.service-card .btn { margin-top: auto; align-self: center; }
.service-copy { flex: 1 1 auto; font-size: 1rem; }
.service-copy p { max-width: 58ch; }
.service-copy p:last-child { margin-bottom: var(--space-5); }

/* ----------------------------------------------------------- page heroes */

/*
 * Interior page heroes. The heading sits at the bottom of the band over a
 * bottom-anchored scrim (C1/C2) so it never has to compete with a face, and
 * the photo keeps a focal point that leaves its subject whole.
 */
.page-hero {
    display: grid;
    align-content: end;
    min-height: clamp(15rem, 28vw, 24rem);
    padding: var(--space-8) 0 var(--space-6);
    color: #fff;
    text-align: center;
    background-color: var(--teal-dark);
    background-image:
        linear-gradient(180deg, rgba(8,44,45,.35) 0%, rgba(8,44,45,.55) 55%, rgba(8,44,45,.82) 100%),
        url('../assets/images/services-happy-dog.webp');
    background-size: cover;
    background-position: center 30%;
}
.page-hero h1 { margin: 0; color: #fff; }
/*
 * /services reuses the close-up that appears again 200px below it. At 380px
 * tall the frame cut the dog's head in half (B3) and no height fixes that —
 * the head alone is 537px at 1280. Tinting it hard turns the photo into a
 * brand-coloured texture, which reads as deliberate and de-duplicates the
 * image (B4).
 */
.page-hero:not(.about-hero) {
    background-image:
        linear-gradient(180deg, rgba(16,79,79,.86) 0%, rgba(13,66,67,.93) 100%),
        url('../assets/images/services-happy-dog.webp');
    background-position: center 22%;
}
/* Corwin and both dogs stay whole at 28% from the top. */
.about-hero {
    min-height: clamp(17rem, 34vw, 29rem);
    background-image:
        linear-gradient(180deg, rgba(6,38,39,.12) 0%, rgba(6,38,39,.3) 45%, rgba(6,38,39,.78) 100%),
        url('../assets/images/about-corwin.webp');
    background-position: center 28%;
}

/* --------------------------------------------------------------- about */

.about-layout { display: grid; grid-template-columns: minmax(16rem, .8fr) minmax(0, 1.55fr); gap: clamp(2rem, 4.5vw, 4rem); align-items: start; }
/* Sticky keeps the short aside beside the long prose instead of leaving a
   half-page hole in the left column (A6). */
.about-lead {
    position: sticky;
    top: var(--space-6);
    padding: var(--space-6);
    color: #fff;
    background: var(--teal-dark);
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
}
.about-lead h2 { margin: 0 0 var(--space-4); color: #fff; font-size: clamp(1.45rem, 2vw, 1.9rem); }
.about-lead p { color: #e8f3f2; }
.prose { max-width: 66ch; }
.prose p { max-width: none; }
.prose p:last-child { margin-bottom: 0; }

/* -------------------------------------------------------------- contact */

.contact-hero { padding: clamp(2.75rem, 6vw, 4.5rem) 0 var(--space-6); text-align: center; }
.contact-hero .container > * { margin-inline: auto; }
.contact-hero h1 { margin: 0; color: var(--teal); }
.contact-grid { display: grid; grid-template-columns: minmax(17rem, .7fr) minmax(0, 1.5fr); gap: clamp(2rem, 4.5vw, 4rem); align-items: start; }
.contact-aside {
    position: sticky;
    top: var(--space-6);
    padding: var(--space-6);
    color: #fff;
    background: var(--teal-dark);
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
}
.contact-aside h2 { margin: 0 0 var(--space-4); color: #fff; font-size: clamp(1.45rem, 2vw, 1.9rem); }
.contact-aside p { color: #e8f3f2; }
.contact-aside a { display: inline-block; color: #fff; font-size: 1.3rem; font-weight: 700; }
.contact-aside a:hover { color: var(--orange); }
.contact-form { padding: clamp(1.5rem, 3.5vw, 2.5rem); background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); }
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); }
.form-group { margin-bottom: var(--space-4); }
.form-group.full { grid-column: 1/-1; }
label { display: block; margin-bottom: var(--space-1); color: #2e3a3c; font-weight: 700; }
input, textarea {
    width: 100%;
    padding: .8rem .9rem;
    color: #242c2e;
    background: #f8faf9;
    border: 1px solid #c3d0d0;
    border-bottom: 2px solid var(--teal);
    border-radius: var(--radius-sm);
    font: inherit;
    transition: border-color .18s var(--ease), box-shadow .18s var(--ease), background-color .18s var(--ease);
}
input:hover, textarea:hover { background: #fff; }
input:focus, textarea:focus { outline: none; background: #fff; border-color: var(--teal-dark); box-shadow: var(--ring); }
input:focus-visible, textarea:focus-visible { outline: none; }
textarea { min-height: 9.5rem; resize: vertical; }
.form-note { margin-top: var(--space-3); color: var(--muted); font-size: .9rem; }
.alert { margin-bottom: var(--space-5); padding: var(--space-4) var(--space-5); border-left: 5px solid; border-radius: var(--radius-sm); }
.alert h2 { margin: 0 0 var(--space-1); font-size: 1.3rem; }
.alert p { margin: 0; }
.alert-success { background: #e8f5ee; border-color: #217547; }
.alert-error { background: #fff1ef; border-color: #ad2f23; }

/* ------------------------------------------------------------ call band */

/*
 * The reference puts the phone number, typed out large, next to one pill
 * button in a band of its own, and repeats it near the foot of the page.
 * This band does the same with copy that already exists on this site — the
 * heading, sentence and number are the contact page's "Give Us a Call" aside
 * word for word. Nothing here is newly written.
 */
.call-band {
    padding-block: var(--section-y);
    color: #fff;
    background: var(--teal-dark);
    text-align: center;
}
.call-band h2 { margin: 0 0 var(--space-3); color: #fff; }
.call-band p { margin-inline: auto; color: #e8f3f2; }
.call-band-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-4) var(--space-6);
    margin-top: var(--space-6);
}
.call-band-number {
    color: #fff;
    font: 700 clamp(1.5rem, 2.6vw, 2.1rem)/1.2 Raleway, "Segoe UI", sans-serif;
    text-decoration: none;
}
.call-band-number:hover { color: var(--orange); }

/* --------------------------------------------------------------- footer */

.site-footer {
    position: relative;
    margin-top: 0;
    padding: clamp(2.75rem, 5vw, 4rem) 0 0;
    color: #fff;
    background: var(--charcoal);
}
/*
 * Was a white dome with two hard grey drop shadows — the most dated thing on
 * the site (F1). Same element, now a thin brand rule across the top edge.
 */
.footer-curve {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 4px;
    background: linear-gradient(90deg, var(--teal) 0%, var(--teal-light) 45%, var(--orange) 100%);
}
.footer-grid {
    width: 100%;
    max-width: calc(var(--max) + 2 * var(--gutter));
    margin-inline: auto;
    padding-inline: var(--gutter);
    display: grid;
    grid-template-columns: 1fr 190px 1fr;
    gap: var(--space-6);
    align-items: center;
}
.footer-grid > div, .footer-grid > nav { display: grid; gap: var(--space-2); }
.footer-grid > nav { justify-items: end; }
.footer-grid a { color: #fff; text-decoration: none; }
.footer-grid a:hover { color: var(--orange); }
.footer-grid > nav a { padding: var(--space-1) 0; }
/*
 * Equal widths instead of three ragged fit-content boxes (D7), and the label
 * centred inside the box (T-503, owner: "the phone, Contact Us and Find us on
 * Facebook buttons have left-aligned text in centred boxes"). flex + centre on
 * both axes rather than text-align alone, so a future icon centres with its
 * label instead of hanging off the left edge.
 */
.footer-call, .footer-contact, .footer-social {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    width: 100%;
    max-width: 17rem;
    min-height: 46px;
    text-align: center;
    padding: var(--space-2) var(--space-4);
    border: 1px solid rgba(255, 255, 255, .34);
    border-radius: var(--radius-pill);
    transition: background-color .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease);
}
.footer-call:hover, .footer-contact:hover, .footer-social:hover { color: #fff; background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .7); }
.footer-logo { justify-self: center; }
.footer-logo img { width: 170px; height: 170px; object-fit: contain; opacity: .9; transition: opacity .18s var(--ease); }
.footer-logo:hover img { opacity: 1; }
.copyright { margin: var(--space-7) 0 0; padding: var(--space-4); color: #ccc; background: #252525; text-align: center; font-size: .88rem; }
.copyright, .form-note { max-width: none; }

.back-to-top {
    position: fixed;
    right: var(--space-4);
    bottom: var(--space-4);
    z-index: 40;
    width: 44px;
    height: 44px;
    border: 0;
    border-radius: 50%;
    color: #fff;
    background: var(--teal-dark);
    box-shadow: var(--shadow-md);
    opacity: 0;
    pointer-events: none;
    transform: translateY(10px);
    transition: opacity .22s var(--ease), transform .22s var(--ease), background-color .18s var(--ease);
}
.back-to-top.visible { opacity: 1; pointer-events: auto; transform: none; }
.back-to-top:hover { background: var(--orange); color: #1d2426; }

/* ------------------------------------------------------------------ 404 */

.error-page { display: grid; place-items: center; padding: clamp(3.5rem, 9vw, 6.5rem) var(--gutter) clamp(3.5rem, 9vw, 6rem); text-align: center; }
.error-page > div { max-width: 44rem; }
.error-page h1 { color: var(--teal); }
.error-page p { margin-inline: auto; }
.error-page .hero-actions { justify-content: center; margin-top: var(--space-6); }

/* ---------------------------------------------------------- scroll reveal */

/*
 * Armed by js/main.js, which adds .js-reveal to <html> and only marks blocks
 * that start below the fold — so nothing above the fold is ever hidden (no
 * LCP or CLS cost) and a JS failure leaves the page fully visible.
 */
.js-reveal [data-reveal] { opacity: 0; transform: translateY(14px); }
.js-reveal [data-reveal].is-visible { opacity: 1; transform: none; transition: opacity .55s var(--ease), transform .55s var(--ease); }
/* A short stagger when a row of cards comes in together. */
.js-reveal .service-card[data-reveal]:nth-child(2).is-visible { transition-delay: .08s; }
.js-reveal .service-card[data-reveal]:nth-child(3).is-visible { transition-delay: .16s; }

/* ---------------------------------------------------------- breakpoints */

@media (max-width: 840px) {
    body { font-size: 17px; }
    .nav-shell { min-height: 78px; justify-content: space-between; }
    .mobile-brand, .mobile-nav-toggle { display: flex; }
    .mobile-brand img { width: 62px; height: 62px; object-fit: contain; }
    .mobile-nav-toggle {
        align-items: center;
        justify-content: center;
        width: 48px;
        height: 48px;
        color: var(--teal-dark);
        background: #fff;
        border: 2px solid var(--teal);
        border-radius: var(--radius-sm);
        font-size: 1.4rem;
        transition: background-color .18s var(--ease), color .18s var(--ease);
    }
    .mobile-nav-toggle:hover { color: #fff; background: var(--teal-dark); }
    #primary-nav {
        display: none;
        position: absolute;
        left: 0;
        right: 0;
        top: 100%;
        grid-template-columns: 1fr;
        gap: 0;
        padding: var(--space-2) var(--gutter) var(--space-4);
        background: #fff;
        border-bottom: 1px solid var(--line);
        box-shadow: var(--shadow-md);
    }
    #primary-nav.active { display: grid; }
    #primary-nav > a { padding: var(--space-3); text-align: left; }
    #primary-nav > a:not(.nav-logo)::after { display: none; }
    #primary-nav .nav-logo { display: none; }
    .hero-home { min-height: clamp(24rem, 62vw, 32rem); }
    .services-grid { grid-template-columns: 1fr; gap: var(--space-4); }
    .service-card:hover { transform: none; }
    .about-layout, .contact-grid { grid-template-columns: 1fr; }
    .about-lead, .contact-aside { position: static; }
    .footer-grid { grid-template-columns: 1fr; justify-items: center; text-align: center; }
    .footer-grid > div, .footer-grid > nav { justify-items: center; width: 100%; }
    .footer-grid > nav { gap: var(--space-1); }
    .footer-logo { grid-row: 1; }
    .footer-logo img { width: 130px; height: 130px; }
    .photo-band { padding-block: var(--space-6); }
    .call-band-actions { flex-direction: column; gap: var(--space-4); }
}

@media (max-width: 560px) {
    .topbar-inner { justify-content: center; gap: var(--space-1) var(--space-4); font-size: .86rem; }
    /*
     * At 375 the photo is scaled by height, so only ~56% of its width fits and
     * the two dogs cannot both be whole — T-502 accepted that and framed on the
     * Newfoundland's face. What changes here is the composition: the badge is
     * centred like it is on desktop, so the wash is a centred halo rather than
     * a left-edge ramp, and the band grew to 28rem so the badge and the two
     * stacked buttons are not crammed against the intro card.
     */
    .hero-home {
        min-height: 26rem;
        align-items: center;
        padding-block: var(--space-6);
        background-image:
            radial-gradient(62% 46% at 50% 40%, rgba(255,255,255,.88) 0%, rgba(255,255,255,.6) 52%, rgba(255,255,255,.18) 88%, rgba(255,255,255,0) 100%),
            linear-gradient(180deg, rgba(255,255,255,.3) 0%, rgba(255,255,255,.36) 45%, rgba(255,255,255,.26) 100%),
            url('../assets/images/hero-home.webp');
        background-position: 58% 28%;
    }
    .hero-home .hero-logo { --hero-logo-w: clamp(10.5rem, 46vw, 14rem); }
    .hero-actions { flex-direction: column; align-items: stretch; width: min(17rem, 100%); }
    .intro-card { margin-top: calc(var(--space-6) * -1); padding: var(--space-5); }
    .form-grid { grid-template-columns: 1fr; }
    .form-group.full { grid-column: auto; }
    .footer-call, .footer-contact, .footer-social { max-width: 15rem; }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        scroll-behavior: auto !important;
        transition: none !important;
        animation: none !important;
    }
    /* Reveal is inert, never a permanently hidden section. */
    .js-reveal [data-reveal] { opacity: 1 !important; transform: none !important; }
    .btn:hover, .service-card:hover { transform: none; }
}
