/* ============================================================
   ACCESSIBILITY OVERRIDE LAYER  (loaded LAST — wins the cascade)
   ------------------------------------------------------------
   Fixes WCAG 2.1 AA contrast failures in the locked brand palette
   without touching the design's site.css. Every rule here is
   reversible: delete this file to restore pure brand colors.

   NOTE: the pink AND green WCAG fixes now live in the brand tokens
   themselves (--hot-pink = #d30186, --green = #007e59 in
   colors_and_type.css — the canonical accessible digital colors from
   Claude Design), so they are no longer overridden here. This file now
   only handles the two light-panel eyebrow combos + focus + motion.
   ============================================================ */

/* Smooth in-page scrolling for anchor links (e.g. "Read our philosophy ↓").
   The reduced-motion block below turns this off for users who ask. */
html { scroll-behavior: smooth; }

/* --- Card-wrapper links: these were <button> elements in the design (no
   underline) but we made them real <a> links for clean URLs + keyboard access.
   The global `a { text-decoration: underline }` then underlined ALL their inner
   text. Turn it off on the whole-card click targets — inline text links
   (.inline-link, nav, footer) keep their underline. --- */
.territory-card,
.lb-card,
.bnet-avatar-btn,
.journal-featured,
.post-card,
.services-feature-box,
.oa-chip,
.post-author-link,
.spec-chip-link { text-decoration: none; }

/* --- Eyebrow labels on the LIGHT lilac/sky panels: the brand pink/teal only
   score 3.31:1 there (fail small text). Deepen just the eyebrow on those two
   panels — titles are large display and pass at 3:1, so they're untouched.
   deep-pink on lilac = 6.05:1 · deep-teal on sky = 7.69:1. --- */
.panel-lilac .eyebrow-pink { color: var(--hot-pink-deep); }
.panel-sky .eyebrow-blue { color: var(--bright-blue-deep); }

/* --- 4. Universal focus ring: ink reads on every brand color
        (cream, pink, green, sky, lilac), unlike the hot-pink ring
        which vanishes on pink/green panels. --- */
:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
  border-radius: 4px;
}
.btn:focus-visible { outline-offset: 4px; }
/* On dark/colored panels, switch the ink ring to cream so it stays visible. */
.panel-green :focus-visible,
.panel-pink :focus-visible,
.reviews-strip :focus-visible,
.mobile-cta-sticky:focus-visible { outline-color: var(--off-white); }

/* --- 5. Reduced-motion safety net: kill remaining decorative motion
        for users who ask for it (the hero rotator + smooth scroll are
        already JS-guarded). --- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================
   MOBILE DESIGN TWEAKS  (lives here, not site.css/moodboard.css,
   so a design re-export never clobbers it — this file loads last
   and wins the cascade). Targeted phone-only spacing/sizing fixes.
   ============================================================ */

/* --- (A) LOGO COLOR MATCH — the logo PNG bakes in the PRINT green
   (#038d65); the rest of the site uses the ADA digital green
   (--green #007e59). The two share the exact same hue (162°) and the
   digital green is just ~11% darker, so a brightness/saturate filter
   maps the logo green onto --green precisely. The "CLUB" text + paw
   prints are transparent holes (not cream pixels), so the filter only
   re-tints the green and never ghosts. Verified vs a --green swatch. */
.site-logo img,
.footer-logo {
  filter: brightness(0.89) saturate(1.05);
}

/* --- (B) HOME HERO — one clean phone screen: copy on top, big dog
   photo anchored to the BOTTOM of the *visible* viewport. Key unit:
   svh ("small viewport height") measures the screen WITH Safari's
   URL/tool bars showing; vh assumes they're hidden, which is why the
   photo used to land ~100px below the fold on first load. Also drop
   the "Now booking" eyebrow + "See how it works" link on phones
   (user-approved) so the photo owns the lower half. --- */
@media (max-width: 600px) {
  .hero-cutout-eyebrow { display: none; }
  .hero-cutout .js-scroll-how { display: none; }
  .hero-cutout {
    min-height: 84vh;                  /* fallback for pre-svh browsers */
    min-height: calc(100svh - 62px);   /* 62px ≈ mobile header height */
    padding-bottom: 0;
  }
  /* All four cutout PNGs put the dog in the RIGHT half of the frame
     (left half is transparent), so bleed the EMPTY left side off-screen
     and keep the right edge — where the faces are — fully visible. */
  .hero-cutout-figure {
    width: 190%;
    right: -4%;
    bottom: 0;
  }
  /* Caption pill: recentre for the wider figure so it stays on-screen */
  .hero-cutout-caption { left: 64%; bottom: 11%; }
}

/* Hero doodles on small screens: the pink "shine" was pinned bottom-right,
   which the bigger photo now occupies — it read as stray scribbles ON the
   dog. Hide it on phones; the headline star carries the sticker energy.
   (Tried relocating it / swapping in the hearts doodle: every reliable
   position either lands on the rotating photos or clashes with text as
   it wraps differently per device — cleaner without.) */
@media (max-width: 900px) {
  .hd-shine-pink { display: none; }
}

/* --- (C) DOODLE FIELD SEAMS — the doodle texture is a 1536×1024 collage
   tiled at ~360px, so on a phone it repeats with visible seams ("not a
   continuous image"). Scale one copy to COVER with no repeat → zero seams,
   one continuous doodle field. Applied to every page's hero (first section)
   and to the denser band/full doodle panels anywhere on the page (the home
   "dog people" panel, etc.) — the faint edge/sparse textures don't seam
   noticeably so they keep tiling. Phones only; desktop blocks are wide
   enough that bigger doodles would look odd. */
@media (max-width: 720px) {
  .page > section:first-of-type > .doodle-layer,
  .doodle-band,
  .doodle-full {
    -webkit-mask-size: cover;
            mask-size: cover;
    -webkit-mask-position: center;
            mask-position: center;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
  }
}

/* --- (D) FAQ HERO SPACING — the FAQ hero uses .page-header, which
   (unlike the .panel heroes on the other static pages) never got a
   phone padding/size pass, so its title rendered at the full 64px
   with desktop padding. Bring it in line with the panel heroes. --- */
@media (max-width: 720px) {
  .page-header { padding: 48px 20px 40px; }
  .page-header .page-title { font-size: clamp(34px, 9.2vw, 52px); line-height: 1.12; }
}

/* --- (E) ABOUT HERO — at the tightest .panel-title line-height the
   puffy "you" sticker overlapped the lines around it, and the long
   8-word title overflowed the right edge. Give wrapped panel titles
   breathing room site-wide, and size the about title to fit. --- */
@media (max-width: 720px) {
  .panel-title { line-height: 1.12; }
  .page-about .panel-title {
    font-size: clamp(30px, 8.4vw, 46px);
    overflow-wrap: break-word;
  }
}

/* --- (F) CONTACT PAGE — on phones the two columns stack with the form
   first and the "free meet & greet" steps below. Flip them so the
   what-happens-next steps sit ABOVE the form. (Desktop is side-by-side,
   so order is unaffected there.) --- */
@media (max-width: 900px) {
  /* Form first on mobile — see the contact-hero block below. */
}

/* --- About page: the small round Buddy avatars were the only uploaded photo
   on the site that didn't get the house 90s point-and-shoot treatment, so the
   same photo looked different here and on /team. Adding .photo-treated in the
   markup gives them the filter, but its ::before vignette is absolutely
   positioned — without a positioned, clipping parent it escapes the circle and
   paints a rectangle over the row. These two lines contain it. --- */
.tt-avatar {
  position: relative;
  overflow: hidden;
}

/* --- Legal pages (privacy policy, terms). Long-form generated documents, so
   they get a narrower measure for readability and a little breathing room
   between the many nested lists. Lives here rather than site.css so a design
   re-export can't clobber it. --- */
.legal-inner { max-width: 780px; margin: 0 auto; }
.legal-title { margin-bottom: 8px; }
.legal-updated { color: var(--ink-soft); font-size: 15px; margin-bottom: 28px; }
/* The site's display headings are sized for landing pages, where h3 is a big
   section title. A legal document nests h1>h2>h3>h4, so those sizes invert the
   hierarchy (h3 rendered LARGER than h2, h4 equal to it). Re-scale them inside
   legal pages only, so the visual order matches the document structure. */
.legal-prose h2 { font-size: 32px; line-height: 1.2; margin-top: 44px; }
.legal-prose h3 { font-size: 23px; line-height: 1.25; margin-top: 30px; }
.legal-prose h4 { font-size: 19px; line-height: 1.3; margin-top: 24px; }
@media (max-width: 600px) {
  .legal-prose h2 { font-size: 27px; }
  .legal-prose h3 { font-size: 21px; }
  .legal-prose h4 { font-size: 18px; }
}
.legal-prose li > p { margin: 0 0 6px; }
.legal-prose li { margin-bottom: 10px; }
.legal-credit { margin-top: 40px; color: var(--ink-soft); font-size: 14px; }

/* --- Footer legal links. Sit alongside the copyright line, underlined so they
   read as links rather than small print, and wrap onto their own row on
   phones. --- */
.footer-legal { display: flex; gap: 18px; flex-wrap: wrap; }
.footer-legal a {
  font-size: 14px;
  color: var(--ink-soft);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.footer-legal a:hover { color: var(--ink); }
@media (max-width: 700px) {
  .footer-legal { width: 100%; justify-content: center; margin-bottom: 4px; }
}

/* --- Blue panels that carry a cream doodle overlay ------------------------
   The brand blue (#016fac) passes AA behind cream text on its own: 4.80:1.
   But the decorative doodle layer is cream at 0.16 opacity, which composites
   the surface up to #2884b4 and drops the body text to 3.68:1 — a real AA
   failure that axe flags on the home, team and careers pages.

   Lowering the doodle opacity cannot rescue it: even at 0.06 the text only
   reaches 4.34, and the doodle would be invisible. So the surface is deepened
   to --bright-blue-dark, which is already in the palette. With the same 0.16
   cream overlay that composites to 5.16:1 — comfortably AA, and the doodle
   keeps its intended strength.

   Same approach Chat 1 used for the pink panels: deepen the SURFACE under
   cream text, leave the brand token alone so decorative blue stays vivid. --- */
.panel-blue:has(.doodle-tone-cream),
.panel-blue:has(.blob-tone-cream) {
  background: var(--bright-blue-dark);
}

/* --- Green panels: retone the overlay, don't touch the green ---------------
   Same compositing problem as the blue panels, solved the other way round
   because the brand green has to stay exactly #007e59.

   The doodle and blob layers are cream, so they lighten the green beneath
   them and drop the hero body copy to 3.46:1. Darkening the green would fix
   it but changes the brand colour, and no overlay opacity rescues it — cream
   text on green is only 4.50:1 even with no overlay at all, so any lightening
   at all fails.

   Tinting the overlay with ink instead means the pattern sits DARKER than the
   green rather than lighter, which pushes the surface down to #046e4f and the
   body copy up to 5.55:1. The green itself is untouched, and the motif keeps
   the same presence — it just reads as pressed in rather than raised. --- */
.panel-green .doodle-tone-cream,
.panel-green .blob-tone-cream {
  background: var(--ink);
  opacity: 0.16;
}

/* --- Contrast fixes found by an axe/WCAG 2.1 AA sweep (2026-10-31) ---------
   All measured against the real composited backgrounds, not the raw tokens. */

/* SECONDARY TEXT, SITE-WIDE. --ink-mute was #6b6b6b, which is fine on cream
   (4.72:1) but fails everywhere else it is used: 3.46 on light pink, 3.25 on
   sky, 2.50 on the pink-doodled About panel. Rather than patch the dozen
   components that use it, the token itself is darkened once here, so every
   caption, note and small label on the site stays consistent.

   #4f4f4f clears AA on every surface it lands on: cream 7.25, light pink 5.31,
   white 8.19, sky 5.00. It is still visibly lighter than body text, so the
   visual hierarchy is unchanged. (--ink-mute is never used as a background,
   so darkening it cannot hurt anything else.) */
:root { --ink-mute: #4f4f4f; }

/* The rate-table add-on notes then dim that grey again with opacity:0.85,
   which drops them back to 3.93 on light pink. The dimming was decorative and
   the colour already carries the hierarchy, so it goes. */
.rate-addons .ra-note { opacity: 1; }

/* Hot pink on light pink is 3.31:1. a11y.css already deepened this inside
   .panel-lilac; the BFF-network heading sits outside it and was missed, so
   match on the eyebrow wherever it lands on a light-pink surface (6.05:1). */
.bnet-head .eyebrow-pink,
.panel-lilac .eyebrow-pink { color: var(--hot-pink-deep); }

/* Cream dimmed to 92-95% on a green panel drops to 4.07:1. Full cream on the
   brand green is exactly 4.50:1, so these just need their opacity back. The
   dimming was decorative, and at this size the difference is imperceptible. */
.panel-green .eyebrow-on-green,
.eyebrow-on-green { opacity: 1; }
.careers-inner p { color: var(--off-white); }

/* NOTE: axe also flags .puffy sticker lettering on coloured panels (e.g. 2.98:1
   on the team hero). That is a false positive — the lettering is cream with a
   4.76px ink text-stroke and a hard ink drop shadow, which axe cannot measure;
   the outline is what carries the legibility. Left alone deliberately rather
   than restyling a brand element to satisfy a tool that can't see the stroke. */

/* --- About hero: lighter panel -------------------------------------------
   The hero pairs hot-pink display type with a hot-pink doodle overlay on the
   light-pink panel. The overlay darkens the surface to #e49bcc, so the
   headline landed at 2.38:1 — under even the 3:1 allowed for large text — and
   the "Read our philosophy" link at 2.39:1.

   Lightening the panel to #f2e2ef and easing the doodle to 0.12 composites to
   #eec7e2: headline 3.38:1, body ink 11.52:1. The doodle is still clearly
   pink, just softer against a lighter ground. The link is small text, so it
   needs the full 4.5 — the deep pink takes it to 6.17:1. --- */
.page-about .panel-lilac { background: #f2e2ef; }
.page-about .panel-lilac .doodle-tone-pink { opacity: 0.12; }
.page-about .panel-lilac .btn-text-pink { color: var(--hot-pink-deep); }

/* The handful of eyebrows that survived the cull (e.g. "Service area · 8
   neighborhoods") were light pink on green, which fails at this size. Cream
   clears it at 5.55:1 against the ink-toned green panels, and Rachel approved
   the cream treatment when she saw it. */
.eyebrow-on-green { color: var(--off-white); opacity: 1; }

/* === T5: real lead forms ================================================= */

/* Honeypot. Hidden from people but left in the DOM where a script will find
   it and fill it in. Deliberately NOT display:none — plenty of bots skip
   fields that are display:none or type=hidden, and the point is that they
   should take the bait. It is aria-hidden and tabindex=-1 in the markup, so
   keyboard and screen-reader users never reach it. */
.mfm-hp {
  position: absolute !important;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Texting consent. Set apart from the ordinary checkboxes so the opt-in
   reads as a considered choice rather than another form field, and sized
   down a touch because it is legal microcopy, not instructions. */
.mfm-consent {
  margin-top: 4px;
  padding: 13px 15px;
  border-radius: 12px;
  background: rgba(26, 26, 26, 0.035);
}
.mfm-consent .mfm-check > span,
.mfm-consent .mfm-consent-links {
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink);
}
/* Sits directly under the label, indented to line up with its text so the two
   read as one block. */
.mfm-consent-links {
  font-family: var(--font-body);
  margin: 6px 0 0 31px;
}
/* The deep pink clears 4.5:1 on this tinted ground; the standard link pink
   does not at 13.5px. Underlined so the links don't rely on colour alone. */
.mfm-consent a {
  color: var(--hot-pink-deep);
  text-decoration: underline;
}

.mfm-turnstile {
  margin-top: 4px;
  min-height: 65px;
}

/* The four screening questions on the careers form. Two columns on desktop so
   the question and its Yes/No sit on one line; stacked on phones, where a
   cramped radio row is a mis-tap waiting to happen. */
.mfm-gates {
  border: 1.5px solid rgba(26, 26, 26, 0.14);
  border-radius: 12px;
  padding: 14px 16px 6px;
  margin: 0;
}
.mfm-gates legend {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 11.5px;
  color: var(--ink);
  padding: 0 6px;
}
.mfm-gate {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 0;
  border-bottom: 1px solid rgba(26, 26, 26, 0.08);
}
.mfm-gate:last-child { border-bottom: 0; }
.mfm-gate-q {
  font-family: var(--font-body);
  font-size: 14.5px;
  line-height: 1.35;
  color: var(--ink);
}
.mfm-gate-a {
  display: flex;
  gap: 14px;
  flex-shrink: 0;
}
.mfm-gate-a label {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}
.mfm-gate-a input[type="radio"] {
  width: 19px;
  height: 19px;
  accent-color: var(--hot-pink);
  flex-shrink: 0;
}
.mfm-gate-a span {
  font-family: var(--font-body);
  font-size: 14.5px;
  color: var(--ink);
}

@media (max-width: 600px) {
  .mfm-gate {
    flex-direction: column;
    align-items: flex-start;
    gap: 9px;
  }
  .mfm-gate-a { gap: 22px; }
}

/* --- Checkboxes: text beside the box, not under it ------------------------
   `.monday-form-mock label { flex-direction: column }` exists so a normal
   field stacks its caption above its input. A checkbox is the one case where
   that is wrong, and it beat `.mfm-check` on specificity (two selectors to
   one), so every checkbox in these forms rendered with the label dumped
   underneath the box. This affected the careers "Everything I've shared here
   is accurate" checkbox long before the consent boxes existed.

   Matching `.monday-form-mock label.mfm-check` outranks it cleanly rather
   than reaching for !important. Rachel asked for this on 2026-10-31. --- */
.monday-form-mock label.mfm-check {
  flex-direction: row;
  align-items: flex-start;
  gap: 11px;
}
/* The generic `label > span` rule sets 13px/500 for field captions; a
   checkbox label is a sentence, so it needs body sizing and normal weight. */
.monday-form-mock label.mfm-check > span {
  font-size: 14.5px;
  font-weight: 400;
  line-height: 1.4;
  color: var(--ink);
}
.monday-form-mock .mfm-consent .mfm-check > span {
  font-size: 13.5px;
  line-height: 1.5;
}

/* --- The last two real contrast failures (2026-10-31 QA sweep) ------------
   Both were the same bug T4 already found once on `.ra-note`: a colour that
   would pass, knocked under the line by an opacity.

     .social-sub  cream at 0.92 over hot pink  -> #f1dfd9 on #d72194 = 3.59
     .sfb-sub     off-white at 0.92 over green -> #e0e9d5 on #007e59 = 4.07

   Brand cream at full strength is not enough on the pink (4.10) and only
   scrapes the line on the green (4.50, zero margin — and these panels sit
   under doodle overlays that shift the composite). Pure white clears both
   with room to spare: 4.63 on the pink, 5.09 on the green. At 16–17px on a
   saturated panel the difference from cream is imperceptible.

   Lesson worth repeating: check the OPACITY before blaming the colour. --- */
.social-sub { color: #ffffff; opacity: 1; }
.sfb-sub { color: #ffffff; opacity: 1; }

/* --- The remaining three, same sweep ---------------------------------------
   .comp-fee   cream on the blue panel         -> #f3f2e0 on #39779a = 4.34
   .cl-body    cream at 0.92 on brand pink     -> #f0dfd9 on #d30186 = 3.94
   .inline-link in .ch-fallback, on light pink -> #016fac on #e9c6e0 = 3.51

   First two: white clears them (4.91 and 5.10). Scoped with `.cl-card >` so
   the light `.cl-apps` card keeps its ink-soft body text.

   The links are the same problem T4 solved on the About hero — brand blue is
   simply too light on light pink. `--hot-pink-deep` takes them to 6.05, and
   it is the colour already used for links on that ground elsewhere, so this
   is consistency rather than a new exception. Scoped to .ch-fallback: the
   blue inline-link is fine on cream and is left alone there. --- */
.comp-fee { color: #ffffff; }
.cl-card > .cl-body { color: #ffffff; }
.ch-fallback .inline-link { color: var(--hot-pink-deep); }

/* Social links: mark beside the word, baseline-aligned. The icon is
   aria-hidden and the text is the accessible name, so a screen reader reads
   "Instagram" once rather than announcing a graphic too. */
.footer-social {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.footer-social .social-mark { flex-shrink: 0; }

/* The contact form's thank-you heading became an h2 (it sits directly under
   the page h1, so h3 was a level jump for anyone navigating by heading). The
   existing style is bound to `h3`, so carry it across — this is purely about
   keeping the look identical, not a new design. */
.monday-form-thanks .thanks-h {
  font-family: var(--font-display);
  font-size: 28px;
  letter-spacing: -0.015em;
  margin: 0 0 8px;
}

/* === Senior living: shorter path to the form (2026-11-01) =================
   Rachel's complaint: "a lot of space and on mobile, there's a lot of
   scrolling before the form." Measured on a 375px screen: the form sat
   8.4 screens down a 9,054px page.

   Padding and gap tweaks were tried first and saved only 394px — the problem
   is structural, not spacing, so they were abandoned rather than shipped as
   theatre. What worked:
     • the six service cards become a priced list on mobile (1,973 → 996px)
     • the companion section moved below the form in the markup (−916px from
       the path, and it stops sitting between the reviews and the main CTA)
   Together: 8.4 → 6.2 screens.

   Mobile only. On desktop the cards sit three-across and cost nothing. --- */
@media (max-width: 760px) {
  .sl-services-grid {
    gap: 0;
  }
  .sl-services-grid .sl-service-tile {
    padding: 15px 4px;
    border: 0;
    border-bottom: 1px solid rgba(26, 26, 26, 0.12);
    border-radius: 0;
    background: transparent;
  }
  .sl-services-grid .sl-service-tile:last-child { border-bottom: 0; }
  /* The number badge and the description go: the service names say what they
     are, and /services carries the detail for anyone who wants it. */
  .sl-services-grid .sl-service-tile-n,
  .sl-services-grid .sl-service-tile-d { display: none; }
  .sl-services-grid .sl-service-tile-t { margin: 0 0 3px; }
  .sl-services-grid .sl-service-tile-price { margin: 0; }
}

/* --- Senior living hero on phones. Rachel's note: Patty was below the fold,
   so nothing on the first screen showed what this page is about. The height
   came from four separate bands — lede, buttons, trust chips, photo — each
   with its own margin. Three of them give something back:

     • the trust chips go. Insured / bonded / background-checked is the
       promise the "Vetted, every one" card makes properly further down, and
       as five pills it cost 137px to say it badly.
     • the lede drops a size and tightens its line height.
     • the gap between the buttons and the photo closes to nothing.

   Rachel asked for the button to overlay the photo if that was what it took.
   It wasn't — dropping the chips alone put Patty on the first screen — and
   the overlap landed on "See all services", which read as a mistake rather
   than a flourish. So the photo sits under the buttons, just tight to them.
   --- */
@media (max-width: 760px) {
  .sl-hero { padding-top: 44px; padding-bottom: 40px; }
  .sl-hero-copy .panel-title { margin-bottom: 14px; }
  .sl-hero-lede {
    font-size: 16px;
    line-height: 1.5;
    margin-bottom: 20px;
  }
  .sl-trust-chips { display: none; }
  .sl-hero-cta {
    gap: 12px;
    margin-bottom: 16px;
  }
  .sl-hero-inner { gap: 0; }
  .sl-hero-photo img { max-width: none; }
}

/* The services list ran into 120px of blue before the next section — 56px of
   its own bottom margin on top of the section's padding. The list is a list;
   it doesn't need a gap the size of a service. */
@media (max-width: 860px) {
  .sl-services-grid { margin-bottom: 8px; }
}





/* === Contact hero: blue doodle panel + rotating BFF (2026-11-01) =========
   Rachel's direction: "format it like the home page with the doodle
   background (but make it blue) and rotating images (but instead of the
   cutout, it's outlined version you currently have with caption)."

   So the mechanics are the home hero's — a doodle-patterned panel and a photo
   that cross-fades through the BFFs with the caption following it — and the
   photo treatment is this page's: the outlined frame with the 90s
   point-and-shoot filter.

   It replaced a hot-pink panel she found harsh, and before that a two-photo
   collage that worked on mobile but looked thin on desktop. --- */
.contact-hero {
  position: relative;
  overflow: hidden;
  background: var(--light-blue);
  padding: 76px 0 64px;
}
/* Blobs rather than doodles, per Rachel — the same clover field the home
   page hero uses, tinted blue against the light-blue ground. */
.contact-hero-blobs {
  background: var(--bright-blue);
  opacity: 0.18;
}
.contact-hero-inner {
  position: relative;
  z-index: 2;
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 22px;
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 52px;
  align-items: center;
}
.contact-hero-title {
  font-family: var(--font-display);
  font-size: clamp(38px, 5.4vw, 62px);
  line-height: 1.02;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0;
}
.contact-hero-lede {
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink);
  margin: 18px 0 0;
  /* Short enough that it never reaches the back photo frame. */
  max-width: 40ch;
}

/* Two frames, scattered. Rachel drew the pair over a screenshot: the front
   one high and right, a second one dropped low and left behind it, the way
   photos land when you put two down on a table. Each runs its own rotation.

   Frames inside a rotator are stacked and cross-faded, so a box keeps its
   size whatever is showing — no reflow as the dogs change. */
.contact-hero-photo {
  position: relative;
  width: 100%;
  /* Smaller than it was as a lone photo. Two frames need the room, and a
     420px frame made the hero taller than the form it exists to introduce.
     The bottom margin is for the back frame, which hangs below the front one
     and, being absolutely positioned, adds no height of its own — without it
     the hero clips its caption off. */
  max-width: 330px;
  margin: 0 0 118px auto;
}
.contact-dog-rotator {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;
}
.contact-dog-rotator.is-lead {
  z-index: 2;
  transform: rotate(-2deg);
}
/* Behind and below, so the front frame's caption is never covered. */
.contact-dog-rotator.is-trail {
  position: absolute;
  z-index: 1;
  width: 72%;
  /* Far enough left and low enough to read as a second photo rather than a
     sliver behind the first, but still clear of where the lede's longest
     line ends at the narrow end of the desktop range. */
  left: -52%;
  top: 58%;
  transform: rotate(3.2deg);
}
.contact-dog-frame {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-repeat: no-repeat;
  border: 2.5px solid var(--ink);
  border-radius: 24px;
  box-shadow: var(--shadow-card);
  opacity: 0;
  transition: opacity 620ms ease;
}
.contact-dog-frame[data-active] { opacity: 1; }
.contact-dog-rotator > .bff-photo-cap {
  z-index: 3;
  transition: opacity 300ms ease;
}
.contact-dog-rotator > .bff-photo-cap.is-swapping { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .contact-dog-frame,
  .contact-dog-rotator > .bff-photo-cap { transition: none; }
}

@media (max-width: 860px) {
  .contact-hero { padding: 40px 0 34px; }
  /* Headline and photo keep sharing a row on mobile rather than stacking.
     Stacked, they read as two slots filled in turn; side by side they read
     as one picture. The headline wraps narrow — that's the point, it's what
     lets the photo sit into it. */
  .contact-hero-inner {
    grid-template-columns: 1fr 47%;
    gap: 14px;
    align-items: start;
  }
  /* The headline drops into the notch the two frames leave at the top left —
     bounded on the right by the front frame and underneath by the back one.
     Sitting at the very top it floated above the pair instead of belonging
     to it.

     The size is tied to the viewport so "your BFF." always lands on one
     line in the notch's width — the notch narrows with the screen, and at a
     fixed size the headline broke to a fourth line and ran under the back
     frame. A headline that fits the hole beats two more points of size. */
  .contact-hero-copy { padding-top: 30px; }
  .contact-hero-title { font-size: clamp(26px, 8.4vw, 34px); }
  /* Headline only — the lede repeats what the form makes obvious and pushed
     the form most of a screen further down. */
  .contact-hero-lede { display: none; }
  /* Composed rather than placed. The centred photo with matching 28px
     margins read as a template slot — it would look the same whatever was in
     it. Three changes, all things a person does on purpose and a layout
     engine never does by accident:
       • the frame runs off the right edge, cut by the screen
       • it tilts off-grid, like every other photo on this site
       • it drops below the headline's first line so the two interlock
     Nothing sits on top of the text — the photo has its own column.
     .contact-hero already clips, so the bleed adds no horizontal scroll. */
  /* Both frames pulled in off the right edge and made smaller. Running the
     front one off the screen worked when it was alone; with a second frame
     below it the pair just read as cut off. Now the pair sits inside the
     margins and the overlap does the work instead.

     The bottom margin is room for the back frame, which hangs below the front
     one and is absolutely positioned, so it adds no height of its own. */
  .contact-hero-photo {
    width: 100%;
    max-width: none;
    /* A percentage, not pixels: the back frame's drop scales with the frame
       width, so a fixed gap that cleared it on a 375px phone clipped its
       caption on a 430px one. Percentage margins resolve against the column
       width, which is exactly what the frames are sized from. */
    margin: 0 0 120% 0;
  }
  .contact-dog-rotator { aspect-ratio: 3 / 4; }
  .contact-dog-rotator.is-trail {
    width: 108%;
    left: -97%;
    top: 83%;
  }
  /* Form first, then the meet & greet steps and the contact details. */
  .contact-body-inner { display: flex; flex-direction: column; }
  .monday-frame { order: 0; }
  .contact-rail { order: 1; }
}

/* Tablet band. The phone composition carries up to here now — the back
   photo fills the space under the two-line headline that made this band
   need the lede in the first place. What changes is scale: the frames are
   capped so the pair doesn't grow with the column, and there is more room
   underneath for the back one to hang into. */
@media (min-width: 641px) and (max-width: 860px) {
  .contact-hero { padding: 52px 0 46px; }
  /* A fixed column rather than a percentage: at 42% the pair grew with the
     viewport and the hero ran to 700px, which is no way to introduce a form. */
  .contact-hero-inner {
    grid-template-columns: 1fr 262px;
    gap: 30px;
    align-items: start;
  }
  /* The phone's smaller headline and its drop into the notch are both
     undone here — there is room for the full size at this width. */
  .contact-hero-title { font-size: 41px; }
  .contact-hero-copy { padding-top: 0; }
  .contact-hero-photo {
    width: calc(100% + 30px);
    max-width: none;
    margin: 20px -30px 92px 0;
  }
  .contact-dog-rotator { aspect-ratio: 3 / 4; }
  .contact-dog-rotator.is-trail {
    width: 88%;
    left: -76%;
    top: 42%;
  }
}

/* Mobile menu. At 38px the six links filled the sheet and pushed GET STARTED
   most of a screen down, which made the button — the only thing in there
   anyone needs to press — look like an afterthought next to the links. The
   links come down, the button goes up. Each link is still a ~54px target,
   comfortably over the 44px minimum. */
.mobile-menu a {
  font-size: 27px;
  padding: 11px 0;
}
.mobile-menu a .arr { font-size: 19px; }
.mobile-menu .mobile-cta {
  font-size: 16px;
  padding: 19px 32px;
}

/* "Or reach us directly" read as an empty space: .contact-meta a was written
   when this block sat on a dark panel in the hero, and kept its cream text
   after it moved onto the cream body. Hot pink deep rather than the signature
   hot pink — that one is 4.51:1 on cream, which passes by one hundredth and
   is the same no-margin trap as cream on green. */
.contact-reach .contact-meta a { color: var(--hot-pink-deep); }
.contact-reach .contact-meta a:hover { color: var(--ink); }

/* Footer gained a fourth column ("Follow") — Instagram and TikTok were
   sitting under "Learn", which is not what they are. The brand block and the
   links share the row, so four columns need a little less gap than three. */
.footer-cols { grid-template-columns: repeat(4, 1fr); gap: 24px; }
@media (max-width: 1024px) {
  .footer-cols { grid-template-columns: repeat(2, 1fr); gap: 28px; }
}
@media (max-width: 640px) {
  .footer-cols { grid-template-columns: 1fr; gap: 24px; }
}
