/* ──────────────────────────────────────────────────────────────
   Sploot components
   ──────────────────────────────────────────────────────────────
   Canonical, token-driven implementations of the reusable
   components used across splootvets.com. Every value resolves to a
   design token from sploot-tokens.css — no hardcoded brand values.

   Usage (order matters — tokens first):
     <link rel="stylesheet" href="/styles/sploot-tokens.css">
     <link rel="stylesheet" href="/styles/sploot-components.css">

   Contents:
     · Buttons + CTAs        .btn-*
     · Store badges          .store-badge
     · Eyebrow / accent      .eyebrow, .heading-accent
     · Brand accent marks    .s-accent-mark (hand-drawn underline / circle / sparkle)
     · Section topper        .s-topper (decorative illustration above an eyebrow)
     · Card system           .s-card (+ slots + modifiers)
     · Panels                .s-panel (+ --rows/--cols/--muted/--glass), .s-check-row
     · Checklist             .s-check-list + .s-check-row (+ --brand/--inverse)
     · Fineprint             .s-fineprint (claim substantiation note)
     · Price row             .s-price-row (label + optional desc + price)
     · Matrix                .s-matrix (comparison / pricing table, + --inverse)
     · Split callout         .s-split-callout (neutral copy|media promo)
     · Steps timeline        .s-steps, .s-step
     · Service cards         .cover-card, .beyond-link
     · Tabs                  .stage-tabs, .stage-tab, .stage-panel
     · Phone mockup          .phone, .phone-screen
     · Promo / CTA blocks    .pack-card, .final-block
     · Open-now pulse        .pulse
     · Pill tabs             .s-pill-tabs (segmented control)
     · Coupon bar            .s-coupon-bar (dark tap-to-copy)
     · Clinic info card      .s-info-card / .s-info-row / .s-status / .s-hours
     · Marquee ticker        .marquee (scrolling value-prop banner)
     · Location hero         .hero-* (location-page hero, + data-variant=fullbleed)
     · Services carousel     .s-pill-tabs--teal / .dvr-svc-* / .concerns-grid (toggle + slider + grid)
     · SplootRx callout      .rx-callout (split-hero + image slider + benefit cards)
     · Plan comparison       .plan-card, .plan-savings (membership vs pay-as-you-go)
     · Motion                .reveal
     · Service-page shell    .svc-page, .svc-section (tokens + headings + split hero)
   The FAQ component lives separately in sploot-faq.css.
   ────────────────────────────────────────────────────────────── */

/* ── Buttons + CTAs ──────────────────────────────────────────── */
/* Canonical button — ONE base `.btn` + a variant modifier (.btn--coral / .btn--teal /
   .btn--teal-outline). Tertiary `.btn--link` is self-contained (no pill). The legacy
   classes (.btn-coral / .btn-teal-solid / .btn-teal-outline / .btn-link) are retained as
   aliases — same declarations — so live pages that still ship them are unaffected.
   New markup should use:  <a class="btn btn--coral">  ·  <a class="btn--link"> */
.btn,
.btn-coral,
.btn-teal-solid,
.btn-teal-outline {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 0.65em 1.75em;   /* Cooper 2026-07-20: 0.8em/2em still read oversized in Webflow at 16px (~52px tall). Tightened one step to ~47px. */
    border-radius: var(--radius-pill);
    font-family: var(--font-sans);
    font-weight: var(--weight-medium);   /* 500 — matches the Webflow a-button */
    font-size: var(--text-base);         /* 16px (Cooper 2026-07-10: was 18px/0.95em·2.4em —
                                             read as oversized site-wide; shrunk one step, still
                                             clearly distinct from the 14px .btn--sm compact size) */
    line-height: 1.4;
    border: 2px solid transparent;
    text-decoration: none;
    cursor: pointer;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);   /* soft lift — matches the Webflow a-button */
    transition: var(--transition-button),
                box-shadow var(--duration-fast) var(--ease-standard);
}
/* --sm — compact size for card/inline CTAs (matches the shipped compact pill spec:
   14px/600, tight padding, no lift). Nav buttons are NOT .btn — they belong to the
   nav component (task 22). */
.btn--sm {
    padding: 0.65em 1.4em;
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    box-shadow: none;
}
/* New hover model (from website/pages/a-button-demo/ — the local iteration lab), promoted
   here once it read right: solid buttons hover INTO an outline of themselves; outline
   buttons hover INTO a solid fill — a reciprocal swap instead of a color darken/lighten.
   Two techniques keep the swap from jumping:
   - border-color matches the fill at rest (instead of `transparent`), so the border is
     already there, same width, just invisible against the matching fill — losing the fill
     on hover reveals it instead of animating a border-color from transparent.
   - box-shadow at rest uses a zero-alpha shadow of the SAME shape (not the `none` keyword)
     so it interpolates to/from the real shadow instead of snapping — animating `none` to a
     shadow value doesn't tween in every engine.
   - the fill fades to a zero-alpha of the SAME color (rgb(var(--color-button-rgb) / 0)),
     never the `transparent` keyword. `transparent` is rgba(0,0,0,0) = zero-alpha BLACK, so
     coral→transparent interpolates through a muddy dark-brown/grey mid-fade (the "not smooth"
     flash). Fading to the same hue at alpha 0 changes only the alpha, so it dissolves clean.
     Theme-safe: --color-button-rgb tracks the active fill (opal in default, mint in alt). */
.btn--coral,
.btn-coral {
    background: var(--color-button);         /* opal-100 #E07A6A — the production salmon (Cooper 2026-07-06) */
    color: var(--color-button-text);         /* cream #F2EAE4 */
    border-color: var(--color-button);
}
.btn--coral:hover,
.btn-coral:hover {
    background: rgb(var(--color-button-rgb) / 0);   /* coral at 0 alpha — clean fade, not muddy transparent-black */
    border-color: var(--color-button-hover);
    color: var(--color-button-hover);
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0);
}
/* Coral OUTLINE — the a-button "Outline" variant: same size as .btn--coral,
   token-driven border + text = --color-button, solid coral fill on hover. */
.btn--coral-outline {
    background: rgb(var(--color-button-rgb) / 0);   /* zero-alpha coral, so hover-IN to the solid fill tweens clean */
    border-color: var(--color-button);
    color: var(--color-button);
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0);
}
.btn--coral-outline:hover {
    background: var(--color-button-outline-hover);
    border-color: var(--color-button-outline-hover);
    color: var(--color-button-text);
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
}
.btn--teal,
.btn-teal-solid {
    background: var(--color-midnight-eagle);
    color: var(--color-cream);   /* Webflow button/secondary-text */
    border-color: var(--color-midnight-eagle);
}
.btn--teal:hover,
.btn-teal-solid:hover {
    background: rgb(var(--midnight-eagle-rgb) / 0);   /* teal at 0 alpha — clean fade, not muddy transparent-black */
    border-color: var(--color-midnight-eagle-deep);
    color: var(--color-midnight-eagle-deep);
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0);
}
.btn--teal-outline,
.btn-teal-outline {
    border-color: var(--color-midnight-eagle);
    color: var(--color-midnight-eagle);
    background: rgb(var(--midnight-eagle-rgb) / 0);   /* zero-alpha teal, so hover-IN to the solid fill tweens clean */
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0);   /* outline variant stays flat at rest — no lift */
}
.btn--teal-outline:hover,
.btn-teal-outline:hover {
    background: var(--color-midnight-eagle);
    color: var(--color-white);
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
}
/* Outline button for DARK bands — white border/text, inverts to a solid white fill on
   hover. The dark-background counterpart to .btn--teal-outline; pair it with .btn--coral
   on teal/opal bands (e.g. .final-block) so BOTH CTAs share one box model and can't drift
   out of size sync. Supersedes the bespoke .final-block-outline (which hand-duplicated
   .btn's padding and kept re-drifting). */
.btn--outline-invert {
    background: rgb(255 255 255 / 0);   /* zero-alpha white — clean fade, never the muddy transparent keyword */
    border-color: rgba(255, 255, 255, 0.55);
    color: var(--color-white);
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0);
}
.btn--outline-invert:hover {
    background: var(--color-white);
    border-color: var(--color-white);
    color: var(--color-midnight-eagle-deep);
}
.btn--link,
.btn-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--color-accent);
    font-weight: var(--weight-semibold);
    font-size: var(--text-sm);
    text-decoration: none;
}
.btn--link svg,
.btn-link svg { transition: transform var(--duration-fast) var(--ease-standard); }
.btn--link:hover svg,
.btn-link:hover svg { transform: translateX(3px); }

/* ── Store badges ────────────────────────────────────────────── */
.store-badge {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    background: var(--color-midnight-eagle);
    color: var(--color-white);
    padding: 11px 18px;
    border-radius: var(--radius-md);
    text-decoration: none;
    transition: transform var(--duration-fast) var(--ease-standard),
                box-shadow var(--duration-fast) var(--ease-standard);
}
.store-badge:hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 28px -10px rgb(var(--midnight-eagle-rgb) / 0.35);
}
.store-badge svg { width: 26px; height: 26px; flex-shrink: 0; }
.store-badge .label-small {
    font-size: 10px;
    line-height: 1.1;
    opacity: 0.75;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.store-badge .label-large {
    font-family: var(--font-heading);
    font-weight: var(--weight-medium);
    font-size: var(--text-lg);
    line-height: 1.1;
    margin-top: 2px;
}
/* On dark backgrounds — white chip, teal text */
.store-badge--light { background: var(--color-white); color: var(--color-midnight-eagle); }
.store-badge--light .label-small { color: var(--midnight-eagle-60); opacity: 1; }

/* ── Eyebrow + headline accent ───────────────────────────────── */
.eyebrow {
    font-family: var(--font-sans);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    text-transform: uppercase;
    letter-spacing: var(--tracking-eyebrow);
    color: var(--color-eyebrow);
}
/* .eyebrow-wf — THE site-wide section eyebrow (promoted from 4 inline page copies, task 19).
   CORAL, 13px, with a rule per Cooper's 2026-07-09 call ("eyebrow should be coral with
   lines everywhere") — but About's OWN usage splits the rule count by alignment (verified
   against the source, 2026-07-09): a LEFT-aligned eyebrow (hero, two-col sections) gets
   ONE rule before the label; a CENTERED eyebrow (intro blocks) gets rules flanking BOTH
   sides. Default here is the left/single-rule case (the more common one); add
   .eyebrow-wf--centered on any eyebrow that sits in a text-align:center block.
   --dark (white on dark bands) + --alert (emergency red) remain as overrides. */
.eyebrow-wf {
    display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap;
    font-family: var(--font-sans);
    font-weight: var(--weight-bold);
    font-size: 13px;
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--color-eyebrow);
    margin: 0 0 var(--space-5);
    line-height: 1.4;
}
.eyebrow-wf::before {
    content: ""; flex: 0 0 auto; width: 32px; height: 1px; background: currentColor;
}
.eyebrow-wf--centered::after {
    content: ""; flex: 0 0 auto; width: 32px; height: 1px; background: currentColor;
}
/* --dark is the escape hatch for a dark BAND that isn't wrapped in
   [data-theme="midnight-eagle"] (most live pages just set a dark background on the
   section). It re-points the token rather than hardcoding a colour, so the value stays
   in one place; inside a real theme wrapper the eyebrow already flips on its own and
   this modifier is a no-op. */
.eyebrow-wf--dark { --color-eyebrow: rgb(255 255 255 / 0.6); }
.eyebrow-wf--alert { color: var(--color-red-bright); }
@media (max-width: 640px) {
    .eyebrow-wf { font-size: 11px; margin-bottom: 14px; }
}
.heading-accent {
    font-style: italic;
    color: var(--color-accent);
}
.heading-accent--underline {
    text-decoration: underline;
    text-underline-offset: 4px;
    text-decoration-thickness: 2px;
}

/* ── Brand accent marks — .s-accent-mark ─────────────────────────
   ONE canonical hand-drawn accent laid over a word/figure. Promoted from four
   independent treatments (.hero-accent-word here, .cr-scribble pasted twice on
   reviews + component-library, and two raw-background copies on spay-neuter).

   THE RULE: the mark is ALWAYS a MASK tinted with --color-accent — never a raw
   `background: url(...)`. The source SVGs in /assets/accents each bake their own
   red (line + circle art #E25E5A, stars/paw #EA6460, accent #FF414C, star #F45254)
   and NONE of them is --color-accent (#E07A6A), so a raw background paints an
   off-token red next to on-token text and can't adapt under [data-theme]. The
   CI hex gate cannot catch this (it is non-blocking for SVG fill= attributes).

   Host supplies the box; the ::after supplies the mark. Shape carries geometry. */
.s-accent-mark,
.hero-accent-word { position: relative; white-space: nowrap; }
.s-accent-mark::after,
.hero-accent-word::after {
    content: ""; position: absolute; pointer-events: none;
    background-color: var(--color-accent);
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
    -webkit-mask-position: center; mask-position: center;
    -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
}
/* Underlines sit beneath the word and bleed slightly past it. */
.s-accent-mark--underline-curved::after,
.hero-accent-word::after {
    left: -2px; right: -2px; bottom: -0.16em; height: 0.32em;
    -webkit-mask-image: url('/assets/accents/line-curved.svg');
            mask-image: url('/assets/accents/line-curved.svg');
}
.s-accent-mark--underline-straight::after {
    left: -2px; right: -2px; bottom: -0.16em; height: 0.32em;
    -webkit-mask-image: url('/assets/accents/line-straight.svg');
            mask-image: url('/assets/accents/line-straight.svg');
}
/* The circle wraps its host rather than sitting under it, so it is centred and
   sized in em to track the host's type scale. */
.s-accent-mark--circle::after {
    left: 50%; top: 48%; width: 2.7em; height: 1.9em;
    transform: translate(-50%, -50%) rotate(-4deg);
    -webkit-mask-image: url('/assets/accents/circle-2.svg');
            mask-image: url('/assets/accents/circle-2.svg');
}
/* Sparkle sits BESIDE the phrase, not under or around it: the artwork is a large
   four-point star with a small one trailing off its upper right, so it reads as a
   burst lifting off the end of the words. Anchored past the host's right edge and
   raised — leading-side or behind-the-word placements collide with the type,
   because the big star sits in the asset's lower-left (Cooper 2026-07-16, from a
   4-way render). Sized in em to track the host's type scale; .89/.85 keeps the
   asset's 104x109 ratio. NB it paints OUTSIDE the host box — check a headline that
   ends near its container edge before using it there. */
.s-accent-mark--sparkle::after {
    left: 100%; bottom: 55%;
    width: 0.85em; height: 0.89em;
    margin-left: 0.12em;
    -webkit-mask-image: url('/assets/accents/stars.svg');
            mask-image: url('/assets/accents/stars.svg');
}

/* ── Section topper — .s-topper ──────────────────────────────────
   Decorative illustration above a section eyebrow. Folds three sizes living
   under two class names (.sec-topper at 92/86px, .sparkle-topper at 46px) into
   one atom. Decorative contract for consumers: alt="" + aria-hidden="true" +
   explicit width/height on the <img> (the sparkle instance shipped without
   them — a layout-shift gap). If the eight near-identical centred section
   heads are ever consolidated, this becomes an instance-swap slot inside that
   component rather than a free-standing atom. */
.s-topper { display: block; height: auto; margin: 0 auto var(--space-3); }
.s-topper--lg { width: 92px; }
.s-topper--md { width: 86px; }
.s-topper--sm { width: 46px; }
@media (max-width: 640px) {
    .s-topper--lg { width: 76px; }
    .s-topper--md { width: 72px; }
}

/* ── Decorative pet illustrations — .pet-accent ──────────────────
   Hand-drawn animals (photos/pets/*) tucked into a section's edge or gutter
   for brand personality — the antidote to a flat, templated section rhythm.
   Purely decorative: always aria-hidden + pointer-events:none, and added as
   the FIRST child of a position:relative section so real content paints over
   it. Hidden below 900px so they never crowd the stacked mobile layout.
   Corner + size modifiers avoid per-page positioning rules. */
.pet-accent {
    position: absolute;
    z-index: 0;
    pointer-events: none;
    width: clamp(130px, 13vw, 185px);
    height: auto;
    opacity: 0.9;
}
.pet-accent--br { right: clamp(16px, 4vw, 72px); bottom: 0; }
.pet-accent--bl { left: clamp(16px, 4vw, 72px); bottom: 0; }
.pet-accent--tr { right: clamp(16px, 4vw, 72px); top: 20px; }
.pet-accent--tl { left: clamp(16px, 4vw, 72px); top: 20px; }
.pet-accent--sm { width: clamp(96px, 9vw, 132px); }
.pet-accent--lg { width: clamp(150px, 15vw, 220px); }
@media (max-width: 900px) { .pet-accent { display: none; } }

/* ── Card system — .s-card ───────────────────────────────────── */
.s-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-xl);
    padding: var(--space-7);
    display: flex;
    flex-direction: column;
    transition: transform var(--duration-base) var(--ease-standard),
                box-shadow var(--duration-base) var(--ease-standard);
}
a.s-card { color: inherit; text-decoration: none; }
/* --hoverable carries its own transition so it also works standalone on a
   bespoke (non-.s-card) box — e.g. the pricing / value-prop cards. */
.s-card--hoverable { transition: transform var(--duration-base) var(--ease-standard), box-shadow var(--duration-base) var(--ease-standard); }
/* No vertical lift (Cooper 2026-07-10: matches splootvets.com/sploot-financing —
   subtle scale + shadow only, nothing that moves the card up). Old translateY(-3px)
   treatment lives on in the component graveyard for reference. */
.s-card--hoverable:hover { transform: scale(1.015); box-shadow: var(--shadow-card-hover); }
/* --hover-ring — the OTHER financing hover (Cooper 2026-07-10: "really nice"):
   no motion at all — a 1.5px inset soft-coral ring + a soft drop shadow fade in
   over 0.2s. Values replicated 1:1 from splootvets.com/sploot-financing's
   .split_feature-card.is-white:hover; ring rides opal-80, the nearest real token
   to Webflow's burnt-sienna-shade #F6A3A0. Resting state pre-declares both shadow
   layers (zero spread / zero alpha) so the transition interpolates instead of
   popping. Composable with --bordered / --featured; use INSTEAD of --hoverable. */
.s-card--hover-ring {
    box-shadow: inset 0 0 0 0 var(--opal-80), 0 8px 12px -4px rgb(0 0 0 / 0);
    transition: box-shadow 0.2s ease;
}
.s-card--hover-ring:hover {
    box-shadow: inset 0 0 0 1.5px var(--opal-80), 0 8px 12px -4px rgb(0 0 0 / 0.16);
}
.s-card--center { text-align: center; align-items: center; }
.s-card--featured { background: var(--color-surface-inverse); color: var(--color-text-inverse); border-color: transparent; }
.s-card--bordered { border: 2px solid rgb(var(--opal-rgb) / 0.25); }

.s-card__icon {
    width: 48px; height: 48px;
    border-radius: var(--radius-lg);
    background: var(--color-cream);
    display: grid; place-items: center;
    color: var(--color-midnight-eagle);
    margin-bottom: var(--space-5);
}
.s-card__icon svg { width: 24px; height: 24px; }
.s-card--featured .s-card__icon { background: rgba(255, 255, 255, 0.12); color: var(--color-accent); }

.s-card__number {
    font-family: var(--font-heading);
    font-weight: var(--weight-medium);
    font-size: var(--text-4xl);
    color: var(--color-midnight-eagle);
    line-height: var(--leading-none);
    margin-bottom: var(--space-5);
}
.s-card--featured .s-card__number { color: var(--color-text-inverse); }

.s-card__eyebrow {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-label);
    font-weight: var(--weight-bold);
    color: var(--color-text);   /* was --color-midnight-eagle (primitive) — semantic so it adapts to [data-theme] */
    margin-bottom: var(--space-3);
}
.s-card--featured .s-card__eyebrow { color: var(--color-accent); }

.s-card__title {
    font-family: var(--font-heading);
    font-weight: var(--weight-medium);
    font-size: 22px;
    color: var(--color-text);   /* was --color-midnight-eagle (primitive) — semantic so it adapts to [data-theme] */
    line-height: var(--leading-snug);
    margin-bottom: 10px;
}
.s-card--featured .s-card__title { color: var(--color-text-inverse); }

.s-card__stat {
    font-family: var(--font-heading);
    font-weight: var(--weight-medium);
    font-size: var(--text-4xl);
    color: var(--color-text);   /* was --color-midnight-eagle (primitive) — semantic so it adapts to [data-theme] */
    line-height: var(--leading-none);
    margin-bottom: var(--space-2);
}
/* --featured recolors every other slot; __stat was missed, so a stat on a featured
   card rendered dark-on-dark. Matches the __number treatment (both are big serif numerals). */
.s-card--featured .s-card__stat { color: var(--color-text-inverse); }

.s-card__body {
    font-size: var(--text-md);
    color: var(--color-text-muted);
    line-height: var(--leading-relaxed);
}
.s-card--featured .s-card__body { color: var(--color-text-inverse-muted); }

/* media variant — image-top card. Absorbs the old .cover-card / .ol-card
   image cards: image fills the top, content sits in __body, optional __link. */
.s-card--media { padding: 0; overflow: hidden; }
.s-card--media .s-card__body { padding: var(--space-6) var(--space-6) var(--space-7); display: flex; flex-direction: column; gap: 6px; flex: 1; }
.s-card__media { width: 100%; display: block; object-fit: cover; aspect-ratio: 16 / 10; background: var(--color-mint); }
.s-card__link {
    display: inline-flex; align-items: center; gap: var(--space-2);
    margin-top: auto; padding-top: var(--space-4);
    color: var(--color-accent); font-weight: var(--weight-semibold);
    font-size: var(--text-sm); text-decoration: none;
}
.s-card__link svg { display: inline-block; vertical-align: middle; transition: transform var(--duration-fast) var(--ease-standard); }
.s-card--hoverable:hover .s-card__link svg, .s-card__link:hover svg { transform: translateX(3px); }

/* ── Panels — divided containers ─────────────────────────────── */
.s-panel {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-xl);
    overflow: hidden;
}
.s-panel--cols { display: grid; }
.s-panel--cols.cols-3 { grid-template-columns: repeat(3, 1fr); }
.s-panel--cols.cols-4 { grid-template-columns: repeat(4, 1fr); }
.s-panel--cols > * { border-right: 1px solid var(--color-border); padding: var(--space-8) var(--space-6); text-align: center; }
.s-panel--cols > *:last-child { border-right: none; }
.s-panel--rows > * { border-bottom: 1px solid var(--color-border); padding: var(--space-5) var(--space-6); }
.s-panel--rows > *:last-child { border-bottom: none; }
/* Optional label slot at the top of a divided panel. Was a phantom: the class was
   in spay-neuter's markup but only ever styled page-locally (.sn-page
   .consult-panel .s-panel__head), so copying the panel anywhere else — including
   into the component library — produced an unstyled div. Child-scoped so it beats
   the `> *` divider rule above without !important. */
.s-panel--rows > .s-panel__head {
    font-family: var(--font-sans); font-size: 13px; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.05em; color: var(--granite-100);
    border-bottom: none; padding-bottom: 0;
}
/* Tinted surface — the token already existed and is theme-aware across all four
   [data-theme] blocks, unlike the hardcoded timberwolf primitives pages reached
   for. Added so a tinted divided panel is a variant, not a re-implementation. */
.s-panel--muted { background: var(--color-surface-muted); }
/* Glass — the dark translucent card that sits on a dark band. Promoted from the
   THIRD independent hand-roll of the same recipe (.plan-card's shell, its
   .plan-savings box, and spay-neuter's .price-card). Only the SHELL is shared:
   .plan-card's badge, price and list slots stay membership-specific. */
.s-panel--glass {
    background: rgb(255 255 255 / 0.05);
    border: 1px solid rgb(255 255 255 / 0.12);
    border-radius: var(--radius-2xl);
    padding: var(--space-8);
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
    overflow: visible;
}
.s-panel--glass.s-panel--sm { padding: var(--space-6); border-radius: var(--radius-xl); }
/* Inverse — flush stats band on a dark section (About's proof strip): the section
   supplies the background, so the panel drops its own box and flips to white
   hairline dividers + inverse text. Distinct from .plan-savings, which stays a
   BORDERED box on dark (price comparison, not proof stats). */
.s-panel--inverse { background: transparent; border: none; border-radius: 0; overflow: visible; }
.s-panel--inverse.s-panel--cols > * { border-right-color: rgba(255, 255, 255, 0.2); }
.s-panel--inverse .s-card__eyebrow { color: rgba(250, 247, 244, 0.6); }
.s-panel--inverse .s-card__stat { color: var(--color-text-inverse); }
.s-panel--inverse .s-card__body { color: rgba(255, 255, 255, 0.8); }
/* Coral stat figure — the alternating-accent treatment from About's band. */
.s-card__stat--accent, .s-panel--inverse .s-card__stat--accent { color: var(--color-accent); }
@media (max-width: 700px) {
    .s-panel--cols.cols-3 { grid-template-columns: 1fr; }
    .s-panel--cols > * { border-right: none; border-bottom: 1px solid var(--color-border); }
    .s-panel--cols > *:last-child { border-bottom: none; }
    /* 4-up collapses to a 2×2 grid with the dividers off (About's mobile treatment) */
    .s-panel--cols.cols-4 { grid-template-columns: repeat(2, 1fr); }
    .s-panel--cols.cols-4 > * { border-bottom: none; }
    .s-panel--inverse.s-panel--cols > * { border-bottom-color: rgba(255, 255, 255, 0.2); }
}

/* Checklist row (green check) */
.s-check-row { display: flex; align-items: flex-start; gap: var(--space-3); font-size: 15.5px; font-weight: var(--weight-medium); color: var(--color-midnight-eagle); }
.s-check-row::before {
    content: '';
    flex-shrink: 0;
    width: 22px; height: 22px;
    background: var(--color-success);
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='5 13 9 17 19 7'/></svg>") no-repeat center / contain;
            mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='5 13 9 17 19 7'/></svg>") no-repeat center / contain;
    margin-top: 1px;
}
/* The list WRAPPER. .s-check-row shipped without one, so every consumer
   reinvented the identical five properties and only disagreed on the gap
   (.cc-checks 10px, .bene-list 14px, .fin-checks 0.85rem). --space-3 (12px)
   sits between them. The DIVIDED variant is .s-panel--rows + .s-check-row. */
.s-check-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--space-3); }
/* Brand glyph — swaps the flat token check for the hand-drawn one. The asset's
   mint IS the intended look here, so it stays a raw background (unlike
   .s-accent-mark, where the baked red was drift). */
.s-check-row--brand::before {
    background: url('/assets/accents/check-green.svg') no-repeat center / contain;
    -webkit-mask: none; mask: none;
    width: 24px; height: 24px; margin-top: -1px;
}
/* On a dark band. */
.s-check-row--inverse { color: var(--color-text-inverse); }
/* Wrapping horizontal row of notes rather than a vertical stack. */
.s-check-list--inline { flex-direction: row; flex-wrap: wrap; gap: var(--space-3) var(--space-6); }

/* ── Fineprint — .s-fineprint ────────────────────────────────────
   The muted substantiation note under a claim (savings figures, promo terms).
   Promoted from three pastes on ONE page (.pack-fineprint, .addon-fine, and an
   inline style attribute). Required by the messaging guide wherever a savings
   or pricing claim appears, so it recurs. Dark surfaces are handled
   CONTEXTUALLY below rather than as a variant the author must remember. */
.s-fineprint {
    margin: var(--space-4) 0 0;
    font-size: var(--text-xs);
    line-height: 1.45;
    color: var(--color-text-muted);
    max-width: 60ch;
}
.s-fineprint--center { margin-left: auto; margin-right: auto; text-align: center; }
.pack-card .s-fineprint,
.final-block .s-fineprint,
.s-panel--glass .s-fineprint { color: rgb(255 255 255 / 0.7); }

/* ── Price row — .s-price-row ────────────────────────────────────
   The label/price listing row that lives INSIDE .s-panel--rows (the parent owns
   the divider + padding; this atom owns only the flex/baseline/type). Promoted
   from two copies on one page (.consult-fee-row + .addon-row). Nothing existing
   covered it: .s-info-row mandates a 36px icon and stacks label/value, .s-hours
   is a dt/dd grid, .plan-savings__stat is a dark comparison stat. */
.s-price-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-6); }
.s-price-row__name { font-size: var(--text-base); font-weight: var(--weight-semibold); color: var(--color-text); }
.s-price-row__desc { display: block; margin-top: 3px; font-size: var(--text-sm); font-weight: var(--weight-regular); color: var(--color-text-muted); line-height: var(--leading-normal); }
.s-price-row__price { flex: 0 0 auto; font-size: var(--text-lg); font-weight: var(--weight-bold); color: var(--color-text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.s-price-row__price--free { color: var(--color-success); }

/* ── Matrix — .s-matrix ──────────────────────────────────────────
   The comparison / pricing table. No table component existed in canon, and two
   pages had independently hand-rolled the same recipe — each discovering what
   the other lacked. This is the UNION: tabular-nums + semantic row tints from
   spay-neuter's .price-table; the sticky row label, row hover, and horizontal
   scroll-shadow affordance from financing's table.fin-cmp.
   Empty/unavailable states stay with the consumer — that's data policy. */
.s-matrix__scroll {
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    background: linear-gradient(270deg, var(--midnight-eagle-06), transparent 24px) right / 24px 100% no-repeat local;
}
.s-matrix { width: 100%; border-collapse: collapse; }
.s-matrix th, .s-matrix td {
    text-align: left; padding: var(--space-4) var(--space-3);
    font-size: var(--text-sm); line-height: var(--leading-normal);
    border-bottom: 1px solid var(--color-border);
}
.s-matrix thead th {
    font-family: var(--font-sans); font-weight: var(--weight-semibold);
    font-size: var(--text-xs); text-transform: uppercase; letter-spacing: var(--tracking-label);
    color: var(--color-text-subtle);
}
/* Sticky row label keeps the row readable while the value columns scroll. */
.s-matrix tbody th {
    font-weight: var(--weight-medium); color: var(--color-text); white-space: nowrap;
    position: sticky; left: 0; background: var(--color-surface);
}
.s-matrix td { color: var(--color-text); font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; }
.s-matrix tbody tr { transition: background var(--duration-fast) var(--ease-standard); }
.s-matrix tbody tr:hover,
.s-matrix tbody tr:hover th { background: var(--color-surface-muted); }
.s-matrix tr:last-child th, .s-matrix tr:last-child td { border-bottom: none; }
/* Semantic row tints — the member price and the saving. */
.s-matrix__row--success td { color: var(--color-success); }
.s-matrix__row--accent td { color: var(--color-accent); }
@media (max-width: 720px) { .s-matrix { min-width: 480px; } }
/* --inverse — on a dark band (e.g. inside .s-panel--glass). */
.s-matrix--inverse th, .s-matrix--inverse td { border-bottom-color: rgb(255 255 255 / 0.1); }
.s-matrix--inverse thead th { color: rgb(255 255 255 / 0.5); }
.s-matrix--inverse tbody th { color: rgb(255 255 255 / 0.85); background: transparent; }
.s-matrix--inverse td { color: var(--color-text-inverse); }
.s-matrix--inverse tbody tr:hover,
.s-matrix--inverse tbody tr:hover th { background: rgb(255 255 255 / 0.04); }

/* ── Steps timeline ──────────────────────────────────────────── */
.s-steps {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-7);
    /* 4-up default width. This is a per-component default, NOT a "4 columns => 1200"
       rule — there isn't one: .pack-card (:977) is 2-up at 1200 and .concerns-grid
       (:1531) is 3-up at 920. 1080 (--content-wide) is the site default; 1200 is the
       escape hatch a dense 4-up takes. Without any max-width here a consumer silently
       filled its whole container (same bug .why-grid had at :641). Inert where the
       container is already narrower than 1200 (e.g. financing's 1088px .fin-wrap). */
    max-width: var(--content-xwide);
    margin-inline: auto;
    position: relative;
}
.s-steps::before {
    content: '';
    position: absolute;
    top: 32px; left: 8%; right: 8%;
    height: 2px;
    background: repeating-linear-gradient(90deg, var(--color-coral) 0 8px, transparent 8px 16px);
    z-index: 0;
}
.s-step { position: relative; z-index: 1; }
.s-step__num {
    width: 64px; height: 64px;
    border-radius: 50%;
    background: var(--color-surface);
    border: 2px solid var(--color-midnight-eagle);
    display: grid; place-items: center;
    font-family: var(--font-heading);
    font-size: var(--text-2xl);
    font-weight: var(--weight-semibold);
    color: var(--color-midnight-eagle);
    margin-bottom: var(--space-6);
    box-shadow: var(--shadow-sm);
}
.s-step__title {
    font-family: var(--font-heading);
    font-weight: var(--weight-medium);
    font-size: 19px;
    color: var(--color-midnight-eagle);
    margin-bottom: var(--space-2);
}
.s-step__body { font-size: var(--text-sm); color: var(--color-text-muted); line-height: var(--leading-normal); }
@media (max-width: 800px) {
    .s-steps { grid-template-columns: 1fr 1fr; gap: var(--space-6); }
    .s-steps::before { display: none; }
}

/* ── "Why choose us" card grid (.why-grid / .why-card) ─────────
   Values match the byte-identical triplicate found on primary-care,
   emergency-services and wellness-exams (task 24) — a numbered variant
   (.why-num) on two of the three, an image-icon variant (.why-icon) on
   the third. Each page keeps its own .why-head (heading wrapper) and
   responsive breakpoint overrides, same split as .s-steps above. */
/* max-width is canon, not page-local: without it the grid filled the 1280 section
   zone while every other multi-column grid beside it sat at 1080, so the left edge
   jumped 100px at the why section on primary-care/emergency-services/spay-neuter.
   wellness-exams had patched it locally (1100) — the only page that had noticed. */
.why-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-6); max-width: var(--content-wide); margin-inline: auto; }
.why-card {
    border: 1px solid var(--cream-100);
    padding: 32px 28px;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    transition: transform var(--duration-base) var(--ease-standard),
                box-shadow var(--duration-base) var(--ease-standard);
}
.why-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-card-hover); /* was --shadow-md, never a real token — silently a no-op */ }
.why-card .why-num {
    font-family: var(--font-heading); font-size: 32px; font-weight: var(--weight-medium);
    color: var(--midnight-eagle-120); line-height: 1; margin-bottom: 18px;
}
.why-card .why-icon {
    width: 84px; height: 84px; margin-bottom: 20px;
    display: flex; align-items: center; justify-content: center;
}
.why-card .why-icon img { width: 100%; height: 100%; object-fit: contain; }
.why-card h4 { font-size: 22px; margin-bottom: 10px; color: var(--midnight-eagle-120); }
.why-card p { font-size: 15px; color: var(--granite-100); margin: 0; line-height: 1.55; }
@media (max-width: 800px) {
    .why-grid { grid-template-columns: 1fr; gap: var(--space-5); }
}

/* ── Decision cards — treat vs ER (.dec-card) ───────────────────
   Promoted from emergency-services (task 27, audit finding #2) — this
   existed in TWO places, neither canonical: emergency-services' own
   .es-page-scoped copy (the real, live one) and a byte-similar copy trapped
   in component-library's own local <style> block (docs only, never shared —
   same pattern as .hero-availbtn before that was promoted). Values below
   are emergency-services' real, live ones, with three token substitutions
   for vars that turned out to be page-local aliases, not real tokens:
     --r-lg (16px)      -> --radius-lg (14px, matches sibling .why-card)
     --dur-base/--ease-out-soft -> --duration-base/--ease-standard (matches
       every other promoted hover-lift card)
     --color-mint-deep (#0AA370, page-invented) -> --color-success (#10B981,
       the real semantic "affirmative" token, same use-case as the open-now
       pulse and other checkmarks)
   --color-timberwolf-cool (border) isn't a real token either (see
   .inc-card/.cad-cell audit note) — substituted the nearest real one,
   --cream-100, visually indistinguishable at 1px border weight. */
.dec-card {
    background: var(--color-white);
    border: 1px solid var(--cream-100);
    padding: 36px 36px 40px;
    border-radius: var(--radius-lg);
    /* No hover lift: these are informational triage lists, not links — a hover
       animation would signal clickability (Cooper 2026-07-10). */
}
.dec-card h3 {
    font-size: 28px; margin: 0 0 24px;
    color: var(--midnight-eagle-120);
    position: relative; padding-left: 18px;
}
.dec-card .dec-head::before {
    content: "";
    position: absolute; left: 0; top: 8px; bottom: 8px;
    width: 4px; border-radius: 2px;
}
.dec-card .dec-head.treat::before { background: var(--color-success); }
.dec-card .dec-head.er::before { background: var(--color-red-bright); }
.dec-list { list-style: none; padding: 0; margin: 0; }
.dec-list li {
    padding: 12px 0; border-bottom: 1px solid var(--cream-100);
    font-size: 15px; color: var(--midnight-eagle-120);
    display: flex; align-items: flex-start; gap: 12px; line-height: 1.4;
}
.dec-list li:last-child { border-bottom: none; }
.dec-list li::before {
    content: ""; width: 18px; height: 18px; flex-shrink: 0;
    margin-top: 1px;
    background: var(--color-success);
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>") no-repeat center/contain;
            mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>") no-repeat center/contain;
}
.dec-list.er li::before { background: var(--color-red-bright); }
.decision-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; max-width: 1080px; margin: 0 auto; }
.decision-cta-row { text-align: center; margin-top: 44px; }
.decision-cta-row .btn-sub { margin-top: 14px; }
@media (max-width: 640px) {
    .decision-grid { grid-template-columns: 1fr; gap: 16px; }
    .dec-card { padding: 24px; }
    .dec-card h3 { font-size: 22px; }
}

/* ── Service cards — vertical (.cover-card) ────────────────────
   Values match the only real deployment (primary-care) — canonical CSS was
   previously an unused, aspirational definition the live page always
   overrode; reconciled to reality here instead of the other way round,
   task 23. */
.cover-card {
    background: var(--color-white);
    border: 1px solid var(--cream-100);
    border-radius: var(--radius-lg);
    padding: 32px 32px 28px;
    display: flex;
    flex-direction: column;
    text-decoration: none;
    color: inherit;
    transition: transform var(--duration-base) var(--ease-standard),
                box-shadow var(--duration-base) var(--ease-standard);
}
.cover-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-card-hover); /* was --shadow-md, never a real token — silently a no-op */ }
.cover-card--static { cursor: default; }
.cover-card--static:hover { transform: none; box-shadow: none; }
.cover-icon {
    width: 56px; height: 56px;
    border-radius: var(--radius-md);
    background: var(--cream-40);
    display: flex; align-items: center; justify-content: center;
    color: var(--color-midnight-eagle);
    margin-bottom: 22px;
}
.cover-icon svg { width: 26px; height: 26px; stroke-width: 1.8; }
.cover-card h3 { font-size: var(--text-2xl); margin-bottom: var(--space-2); color: var(--color-midnight-eagle); }
.cover-card p { font-size: var(--text-sm); color: var(--color-text-muted); margin: 0 0 var(--space-5); line-height: var(--leading-normal); }
.cover-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: auto;
    font-family: var(--font-sans);
    font-weight: var(--weight-bold);
    font-size: 13px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-midnight-eagle);
    transition: gap var(--duration-base) var(--ease-standard);
}
.cover-card:hover .cover-link { gap: 10px; }

/* ── Service cards — horizontal (.beyond-link) ─────────────────
   Values match the only real deployment (primary-care), same reconciliation
   as .cover-card above, task 23. */
.beyond-link {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
    padding: var(--space-6) 26px;
    background: var(--color-white);
    border-width: 1px;
    border-style: solid;
    border-color: var(--cream-100);
    border-radius: var(--radius-lg);
    text-decoration: none;
    color: inherit;
    transition: transform var(--duration-base) var(--ease-standard),
                box-shadow var(--duration-base) var(--ease-standard),
                border-color var(--duration-base) var(--ease-standard);
}
.beyond-link:hover { transform: translateY(-2px); box-shadow: var(--shadow-card-hover); border-color: var(--color-accent); /* was --color-red-bright #EF4953 (alert red) — unified to the brand accent opal-100 #E07A6A so it matches the buttons/links/sidebar (Cooper 2026-07-09: "two different opals"). box-shadow was --shadow-md, never a real token — silently a no-op */ }
.beyond-link .b-text { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
.beyond-link .b-title { font-family: var(--font-heading); font-size: var(--text-xl); font-weight: var(--weight-medium); color: var(--color-midnight-eagle); }
.beyond-link .b-meta { font-size: 13px; color: var(--color-text-muted); }
.beyond-link .b-arrow {
    width: 36px; height: 36px;
    border-radius: var(--radius-pill);
    background: var(--cream-40);
    display: flex; align-items: center; justify-content: center;
    color: var(--color-accent);
    flex-shrink: 0;
    transition: background var(--duration-base) var(--ease-standard);
}
.beyond-link:hover .b-arrow { background: var(--color-accent); color: var(--color-white); }

/* ── Directory link card (.page-card) ─────────────────────────
   Promoted from index.html (task 27) — the project directory/sitemap page,
   used 12x there. Interaction-only: background, padding, per-instance width
   span, and color variant stay as Tailwind utilities on the <a>/<div> itself
   (same split as .s-card--hoverable). Pair with the canonical .reveal for
   the entrance animation (index.html previously duplicated .reveal as its
   own .card-stagger/.card-visible — retired in favor of the shared one). */
.page-card {
    position: relative;
    overflow: hidden;
    border-radius: 1.5rem;
    text-decoration: none;
    transition: transform 0.4s var(--ease-out-expo), box-shadow 0.4s var(--ease-standard);
}
.page-card:hover { transform: translateY(-6px); box-shadow: 0 20px 50px rgba(27, 75, 75, 0.12); /* no exact token match — closest (--shadow-dropdown) adds an unwanted extra ring layer */ }
.page-card::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(135deg, rgb(var(--opal-rgb) / 0.35), rgb(var(--midnight-eagle-rgb) / 0.15), transparent);
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.4s var(--ease-standard);
}
.page-card:hover::before { opacity: 1; }
.page-card .card-arrow { transition: transform 0.3s var(--ease-out-expo); }
.page-card:hover .card-arrow { transform: translateX(4px); }

/* ── Tabs (.stage-tabs / .stage-panel) ───────────────────────── */
.stage-tabs {
    display: flex;
    gap: 0;
    border-bottom: 1px solid var(--color-border-strong);
    margin-bottom: var(--space-6);
}
.stage-tab {
    flex: 1;
    padding: 14px 16px;
    text-align: center;
    background: transparent;
    border: none;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    color: var(--color-text-subtle);
    transition: var(--transition-colors);
}
.stage-tab:hover { color: var(--color-midnight-eagle); }
.stage-tab.is-active { border-bottom-color: var(--color-midnight-eagle); color: var(--color-midnight-eagle); }
.stage-tab .age {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: var(--tracking-label);
    font-weight: var(--weight-bold);
    margin-bottom: var(--space-1);
}
.stage-tab .name {
    font-family: var(--font-heading);
    font-weight: var(--weight-medium);
    font-size: 19px;
    color: inherit;
}
.stage-panel { display: none; }
.stage-panel.is-active {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-8);
    align-items: center;
    background: var(--color-surface);
    border: 1px solid var(--color-hairline);
    border-radius: var(--radius-xl);
    padding: var(--space-6);
    animation: stage-fade 0.35s var(--ease-standard);
}
@keyframes stage-fade {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}
@media (max-width: 720px) {
    .stage-panel.is-active { grid-template-columns: 1fr; }
}

/* ── Phone mockup ────────────────────────────────────────────── */
.phone {
    position: relative;
    width: 200px;
    aspect-ratio: 9 / 19.5;
    background: var(--color-midnight-eagle);
    border-radius: var(--radius-phone);
    padding: 7px;
    box-shadow: var(--shadow-phone);
}
.phone::before {
    content: '';
    position: absolute;
    top: 12px; left: 50%; transform: translateX(-50%);
    width: 64px; height: 18px;
    background: var(--midnight-eagle-140); /* was #0c2929 — nearest token, imperceptible on a phone bezel */
    border-radius: var(--radius-pill);
    z-index: 3;
}
.phone-screen {
    width: 100%; height: 100%;
    background: var(--color-paper);
    border-radius: 26px;
    overflow: hidden;
}

/* ── Split callout — .s-split-callout ────────────────────────────
   The NEUTRAL split promo: a copy column (eyebrow / heading / lead / check-list
   / CTA / fineprint) beside a media column. Promoted from two independent
   implementations of one recipe — spay-neuter's .cc-callout and financing's
   .fin-split, which drove that page's CareCredit section with the same
   ingredients under a different class vocabulary.

   Deliberately NOT built on .pack-card below: that component's identity IS the
   SplootPack-red band (hardcoded opal surface, white text, white check glyphs,
   white pill CTA), so reskinning it here would mean overriding nearly every
   declaration and fighting a semantically-named component. Longer term the
   relationship inverts — .pack-card becomes .s-split-callout--splootpack — but
   not while this base is still settling.

   Column ratio standardised on 1.1fr/1fr, already shared by .pack-card and the
   service-page hero (the site had four subtly different 2-col splits). */
.s-split-callout {
    display: grid; grid-template-columns: 1.1fr 1fr; gap: var(--space-10);
    align-items: stretch;
}
.s-split-callout__copy { align-self: center; }
.s-split-callout__media { align-self: stretch; }
/* Radius belongs to the image, not to --boxed: the only live consumer (spay-neuter's
   CareCredit callout) is --boxed, so the rounding was written there and the bare base
   rendered square corners — off-brand, and invisible until the component library
   demoed the base. --boxed still gets the same 14px; nothing on the live page moves. */
.s-split-callout__media img { width: 100%; height: 100%; min-height: 300px; object-fit: cover; display: block; border-radius: var(--radius-lg); }
/* --boxed — a surfaced card rather than bare on the section background. */
.s-split-callout--boxed {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-2xl);
    padding: var(--space-10);
}
/* --reverse — media leads. */
.s-split-callout--reverse .s-split-callout__copy { order: 2; }
.s-split-callout--reverse .s-split-callout__media { order: 1; }
@media (max-width: 1024px) {
    .s-split-callout { grid-template-columns: 1fr; gap: var(--space-8); }
    .s-split-callout__copy { align-self: auto; }
    .s-split-callout--reverse .s-split-callout__copy,
    .s-split-callout--reverse .s-split-callout__media { order: 0; }
    .s-split-callout__media img { min-height: 240px; }
}
@media (max-width: 640px) {
    .s-split-callout--boxed { padding: var(--space-6); }
}

/* ── SplootPack membership callout (.pack-card) ───────────────────
   The real red SplootPack promo band that primary-care + wellness-exams render
   (reconciled from those two byte-identical page copies, task 26). Canonical was
   previously a stale CORAL version only the docs demo showed — red is the actual
   SplootPack brand color (opal-120). Two-column: copy panel + visual
   panel (an <img>, or the opal gradient as fallback). One column on mobile.
   Headings match both the pages' bare <h2> and the docs demo's <h3>. */
.pack-card {
    display: grid;
    grid-template-columns: 1.1fr 1fr;
    max-width: var(--content-xwide);
    margin: 0 auto;
    background: var(--opal-120);  /* was --color-red-bright #EF4953 — the ALERT red as a brand surface read neon ("the opal is too vibrant", Cooper 2026-07-06); the band now sits on the actual SplootPack opal */
    border-radius: var(--radius-2xl);
    overflow: hidden;
    color: var(--color-white);
    box-shadow: var(--shadow-feature);  /* was --shadow-md, never a real token — silently a no-op. This is a permanent (not hover) shadow, so --shadow-feature (not --shadow-card-hover) — matches the "prominent, always-elevated" cards that already use it. */
}
.pack-copy {
    padding: 64px 64px 56px;
    display: flex; flex-direction: column; justify-content: center;
}
.pack-eyebrow {
    display: inline-block;
    font-family: var(--font-sans);
    font-weight: var(--weight-bold);
    font-size: var(--text-xs);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.8);
    margin-bottom: var(--space-4);
}
.pack-card h2,
.pack-card h3,
.pack-heading {
    font-family: var(--font-heading);
    font-weight: var(--weight-medium);
    font-size: 44px;
    line-height: 1.05;
    color: var(--color-white);
    margin-bottom: var(--space-5);
}
.pack-card h2 em,
.pack-card h3 em,
.pack-heading em {
    color: var(--color-white);
    font-style: italic;
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 6px;
}
.pack-lead {
    font-size: 16px;
    color: rgba(255, 255, 255, 0.9);
    margin-bottom: 22px;
    line-height: var(--leading-relaxed);
}
.pack-perks {
    list-style: none; padding: 0; margin: 0 0 28px;
    display: flex; flex-direction: column; gap: var(--space-3);
}
.pack-perks li {
    display: flex; align-items: center; gap: var(--space-3);
    font-size: 16px;
    color: rgba(255, 255, 255, 0.95);
}
.pack-perks li::before {
    content: ''; width: 22px; height: 22px; flex-shrink: 0;
    background-color: var(--color-white);
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>") no-repeat center/14px 14px;
            mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>") no-repeat center/14px 14px;
}
.pack-cta {
    display: inline-flex; align-items: center; gap: var(--space-2);
    background: var(--color-white);
    color: var(--opal-120);  /* matches the band (was --color-red-bright) */
    padding: 16px 28px;
    border-radius: var(--radius-pill);
    font-family: var(--font-sans);
    font-weight: var(--weight-bold);
    font-size: 13px;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    text-decoration: none;
    align-self: flex-start;
    transition: transform var(--duration-fast) var(--ease-out-expo),
                box-shadow var(--duration-fast) var(--ease-out-expo);
}
.pack-cta:hover { transform: translateY(-1px); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15); }
.pack-visual {
    position: relative;
    min-height: 360px;
    background: linear-gradient(140deg, var(--opal-120) 0%, var(--opal-120) 100%);
    display: flex; align-items: center; justify-content: center;
    overflow: hidden;
}
.pack-visual img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 1024px) {
    .pack-card { grid-template-columns: 1fr; }
    .pack-copy { padding: 48px 40px; }
    .pack-visual { min-height: 280px; order: -1; }
    .pack-card h2, .pack-card h3, .pack-heading { font-size: 36px; }
}
@media (max-width: 640px) {
    .pack-copy { padding: 36px 24px; }
    .pack-card h2, .pack-card h3, .pack-heading { font-size: 28px; }
    .pack-perks li { font-size: 15px; }
}

/* ── Booking CTA (.final-block) ──────────────────────────────── */
.final-block {
    background: var(--color-midnight-eagle-deep);
    border-radius: var(--radius-2xl);
    padding: var(--space-16) var(--space-8);
    text-align: center;
    position: relative;
    overflow: hidden;
}
.final-block::before {
    content: '';
    position: absolute;
    bottom: -100px; left: -100px;
    width: 320px; height: 320px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(217, 232, 223, 0.15) 0%, transparent 70%);
    pointer-events: none;
}
.final-block-inner { position: relative; max-width: 720px; margin: 0 auto; }
.final-block h2, .final-block h3 {
    font-family: var(--font-heading);
    font-weight: var(--weight-medium);
    font-size: var(--text-5xl);
    line-height: 1.05;
    color: var(--color-white);
    margin-bottom: var(--space-4);
}
.final-block h2 em, .final-block h3 em { font-style: italic; color: var(--color-coral-soft); }
.final-block p {
    font-size: var(--text-md);
    color: rgba(255, 255, 255, 0.7);
    margin-bottom: var(--space-7);
    line-height: var(--leading-relaxed);
}
.final-block-ctas { display: inline-flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 14px; }
/* .final-block-outline removed 2026-07-08 — superseded by the canonical .btn--outline-invert
   (see the button block above). It had zero remaining usages after the Booking CTA demo
   moved to .btn btn--outline-invert; the live service pages never used it (they pair two
   .btn-wf variants inside .final-block). */
.final-block-sub { display: block; margin-top: var(--space-4); font-style: italic; color: rgba(255, 255, 255, 0.45); font-size: var(--text-sm); }

/* Full-bleed variant — the service-page booking band (primary-care /
   emergency-services / wellness-exams). Same dark ground + centered headline as
   the base card, but edge-to-edge: square corners, taller padding, a bigger
   display headline, and a mint glow instead of the base's cream one. Pair with
   the base class:  <section class="final-block final-block--fullbleed">.
   Consolidated from 3 byte-identical page copies (task 25). The .btn-wf.secondary
   override lives here because .btn-wf is the Webflow button family used by these
   export pages; it's scoped through .final-ctas so it only touches CTA-row
   buttons (specificity 0,4,0 — beats the page-local base .btn-wf.secondary). The
   raw on-dark #FFD7C7 / #C5C1B9 match the base .final-block's own
   rgba(255,255,255,…) approach for this band. */
.final-block--fullbleed {
    border-radius: 0;
    padding: 120px 80px;
    color: var(--cream-60);
}
.final-block--fullbleed::before {
    bottom: -200px; left: -140px;
    width: 520px; height: 520px;
    background: radial-gradient(circle at center, rgba(127, 209, 185, 0.16), transparent 70%);
}
.final-block--fullbleed > * { position: relative; }
/* ...except a decorative .pet-accent, which must stay absolute to tuck into a
   corner. The > * rule above is only for stacking the content layer. */
.final-block--fullbleed > .pet-accent { position: absolute; }
.final-block--fullbleed h2,
.final-block--fullbleed h3 {
    font-size: 64px;
    max-width: 780px;
    margin: 0 auto 18px;
    color: var(--cream-60);
}
.final-block--fullbleed h2 em,
.final-block--fullbleed h3 em { color: #FFD7C7; }
/* The service-page shell's generic `.svc-page h2` color rule (defined later in
   this file) has equal specificity to the final-block heading rules above and,
   winning on source order, repaints the heading dark — identical to the block's
   own dark background, making it invisible. Re-assert the intended light heading
   at higher specificity so every service page's closing CTA stays readable. */
.svc-page .final-block h2, .svc-page .final-block h3 { color: var(--cream-60); margin-bottom: var(--space-4); }
/* The same generic `.svc-page h2 { margin: 0 }` / `.svc-page p { margin: 0 0 12px }`
   rules also strip the centering (`margin: 0 auto`) off the fullbleed heading and
   paragraph, pinning them to the left. Re-assert the centered layout. */
.svc-page .final-block--fullbleed h2, .svc-page .final-block--fullbleed h3 { max-width: 780px; margin-left: auto; margin-right: auto; margin-bottom: 18px; }
.svc-page .final-block--fullbleed p { max-width: 580px; margin: 0 auto 36px; }
.final-block--fullbleed p {
    font-size: 18px;
    color: #C5C1B9;
    max-width: 580px;
    margin: 0 auto 36px;
    line-height: 1.55;
}
.final-block--fullbleed .final-ctas { display: flex; justify-content: center; gap: 14px; flex-wrap: wrap; }
.final-block--fullbleed .final-ctas .btn-wf.secondary {
    background: transparent;
    border-color: var(--cream-60);
    color: var(--cream-60);
}
.final-block--fullbleed .final-ctas .btn-wf.secondary:hover {
    background: var(--cream-60);
    border-color: var(--cream-60);
    color: var(--midnight-eagle-120);
}
.final-block--fullbleed .btn-sub { color: #C5C1B9; font-style: italic; }
@media (max-width: 1024px) {
    .final-block--fullbleed { padding: 80px 40px; }
    .final-block--fullbleed h2,
    .final-block--fullbleed h3 { font-size: 48px; }
}
@media (max-width: 640px) {
    .final-block--fullbleed { padding: 64px 20px; }
    .final-block--fullbleed h2,
    .final-block--fullbleed h3 { font-size: 34px; line-height: 1.1; }
    .final-block--fullbleed p { font-size: 15px; }
    .final-block--fullbleed .final-ctas { flex-direction: column; align-items: stretch; }
    .final-block--fullbleed .final-ctas .btn-wf { width: 100%; justify-content: center; text-align: center; }
}

/* ── Open-now pulse ──────────────────────────────────────────── */
.pulse {
    box-shadow: 0 0 0 0 rgb(var(--success-rgb) / 0.55);
    animation: pulse 2s infinite;
}
@keyframes pulse {
    0%   { box-shadow: 0 0 0 0 rgb(var(--success-rgb) / 0.55); }
    70%  { box-shadow: 0 0 0 10px rgb(var(--success-rgb) / 0); }
    100% { box-shadow: 0 0 0 0 rgb(var(--success-rgb) / 0); }
}

/* ── Motion — reveal on scroll ───────────────────────────────── */
.reveal {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity var(--duration-reveal) var(--ease-out-expo),
                transform var(--duration-reveal) var(--ease-out-expo);
}
.reveal.in { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
    .reveal { opacity: 1; transform: none; transition: none; }
    .pulse { animation: none; }
}

/* ── Pill tabs (.s-pill-tabs) — segmented control ──────────────────
   Consolidates today-availability .avail-tabs + services/highlands .svc-tabs (both retired).
   Distinct from the underline .stage-tabs above. aria-selected drives the
   active state; .is-active kept as a legacy alias. Keyboard nav + roving
   tabindex are wired by sploot-components.js (initPillTabs). */
.s-pill-tabs {
    display: inline-flex; flex-wrap: wrap; align-items: center; justify-content: center;
    gap: var(--space-1); padding: var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--color-surface-muted);
    border: 1px solid var(--color-border-strong);
}
.s-pill-tabs-wrap { text-align: center; }
.s-pill-tab {
    flex: 0 0 auto; padding: var(--space-2) var(--space-3);
    border: none; background: transparent; border-radius: var(--radius-sm);
    font-family: var(--font-sans); font-size: var(--text-sm); font-weight: var(--weight-semibold);
    color: var(--color-text); line-height: 1; cursor: pointer;
    transition: var(--transition-colors), box-shadow var(--duration-fast) var(--ease-standard);
}
.s-pill-tab:hover { background: rgb(255 255 255 / 0.45); color: var(--color-text); }
.s-pill-tab[aria-selected="true"],
.s-pill-tab.is-active { background: var(--color-surface); color: var(--color-button); }
.s-pill-tab:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.s-pill-tab:disabled,
.s-pill-tab[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.s-pill-tabs--paper { background: var(--color-surface-muted); border-color: var(--color-border-strong); }
.s-pill-tabs--paper .s-pill-tab[aria-selected="true"],
.s-pill-tabs--paper .s-pill-tab.is-active { background: var(--color-surface); color: var(--color-button); }
.s-pill-tabs--teal {
    gap: var(--space-2); padding: var(--space-2); border-radius: var(--radius-pill);
    background: var(--midnight-eagle-06); border: none;
}
.s-pill-tabs--teal .s-pill-tab {
    padding: var(--space-3) var(--space-5); border-radius: var(--radius-pill);
    color: var(--color-midnight-eagle); opacity: 0.65;
    transition: opacity var(--duration-fast) var(--ease-standard),
                background-color var(--duration-fast) var(--ease-standard),
                box-shadow var(--duration-fast) var(--ease-standard);
}
.s-pill-tabs--teal .s-pill-tab:hover { background: transparent; opacity: 1; }
.s-pill-tabs--teal .s-pill-tab[aria-selected="true"],
.s-pill-tabs--teal .s-pill-tab.is-active {
    background: var(--color-paper); color: var(--color-midnight-eagle); opacity: 1; box-shadow: var(--shadow-sm);
}
/* --inverse — the on-dark-glass skin. The family shipped --paper and --teal but
   nothing for a dark band, so consumers re-skinned background/border/hover/
   selected by hand. Folds those four overrides into the family. */
.s-pill-tabs--inverse { background: rgb(255 255 255 / 0.06); border-color: rgb(255 255 255 / 0.14); }
.s-pill-tabs--inverse .s-pill-tab { color: rgb(255 255 255 / 0.75); }
.s-pill-tabs--inverse .s-pill-tab:hover { background: rgb(255 255 255 / 0.1); color: var(--color-text-inverse); }
.s-pill-tabs--inverse .s-pill-tab[aria-selected="true"],
.s-pill-tabs--inverse .s-pill-tab.is-active { background: var(--color-button); color: var(--color-text-inverse); }

/* Filter bar — several LABELLED pill-tab controls in one wrapping row. Each
   group stays its own independent tablist; this only supplies the caption +
   row rhythm the family was missing. */
.s-filter-bar { display: flex; flex-wrap: wrap; gap: var(--space-5) var(--space-8); }
.s-filter-bar__group { display: flex; flex-direction: column; gap: var(--space-2); }
.s-filter-bar__label {
    font-family: var(--font-sans); font-size: var(--text-xs); font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--color-text-subtle);
}
.s-panel--glass .s-filter-bar__label { color: rgb(255 255 255 / 0.5); }

.s-pill-panel { display: none; }
.s-pill-panel.is-active { display: block; animation: s-pill-fade var(--duration-base) var(--ease-standard); }
.s-pill-panel[hidden] { display: none; }
@keyframes s-pill-fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@media (max-width: 700px) {
    .s-pill-tabs { display: flex; width: 100%; }
    .s-pill-tab { flex: 1 1 auto; text-align: center; }
}
@media (prefers-reduced-motion: reduce) {
    .s-pill-panel.is-active { animation: none; }
    .s-pill-tab { transition: none; }
}

/* ── Coupon bar (.s-coupon-bar) — dark-teal perforated tap-to-copy ──
   Rebuilt from the location-page .ci-coupon. PINNED dark: uses the stable
   --color-teal / --color-paper primitives (NOT *-inverse, which flip under
   midnight-eagle). Copy behavior wired by sploot-components.js (initCouponBars). */
.s-coupon-bar {
    display: flex; align-items: stretch; gap: 0;
    background: var(--color-midnight-eagle);
    border: 1.5px dashed var(--border-inverse);
    border-radius: var(--radius-lg); overflow: hidden;
    box-shadow: var(--shadow-card-hover);
}
.s-coupon-bar__info { flex: 1; display: flex; align-items: center; gap: var(--space-3); padding: 14px var(--space-4); min-width: 0; }
.s-coupon-bar__icon {
    flex: 0 0 36px; width: 36px; height: 36px; border-radius: var(--radius-pill);
    background: rgb(var(--opal-120-rgb) / 0.20); color: var(--color-button);
    display: inline-flex; align-items: center; justify-content: center;
}
.s-coupon-bar__icon svg { width: 18px; height: 18px; }
.s-coupon-bar__text { min-width: 0; }
.s-coupon-bar__head { display: block; margin: 0; font-family: var(--font-sans); font-size: var(--text-base); font-weight: var(--weight-semibold); color: var(--color-paper); line-height: 1.25; text-align: left; }
.s-coupon-bar__sub { display: block; margin: 2px 0 0; font-family: var(--font-sans); font-size: var(--text-xs); color: var(--color-paper); opacity: 0.6; line-height: 1.3; text-align: left; }
.s-coupon-bar__copy {
    position: relative; flex: 0 0 auto; display: flex; flex-direction: column;
    align-items: stretch; justify-content: center; gap: 2px; min-width: 132px;
    padding: 10px var(--space-5); background: transparent; border: 0;
    border-left: 1.5px dashed var(--border-inverse);
    font-family: var(--font-sans); text-align: center; cursor: pointer;
    transition: var(--transition-colors);
}
.s-coupon-bar__copy:hover { background: rgb(255 255 255 / 0.06); }
.s-coupon-bar__copy:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -2px; }
.s-coupon-bar__copy-label { display: block; font-size: 11px; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; font-weight: var(--weight-semibold); color: var(--color-paper); opacity: 0.55; transition: opacity var(--duration-fast) var(--ease-standard); }
.s-coupon-bar__copy-value { display: block; font-family: var(--font-heading); font-weight: var(--weight-medium); font-size: var(--text-base); letter-spacing: 0.04em; color: var(--color-paper); }
.s-coupon-bar__copy-icon { position: absolute; top: 8px; right: 8px; width: 16px; height: 16px; color: var(--color-paper); opacity: 0.45; transition: opacity var(--duration-fast) var(--ease-standard); }
.s-coupon-bar__copy-icon svg { position: absolute; inset: 0; width: 16px; height: 16px; transition: opacity var(--duration-fast) var(--ease-standard), transform var(--duration-fast) var(--ease-standard); }
.s-coupon-bar__icon-check { opacity: 0; transform: scale(0.6); color: var(--color-success); }
.s-coupon-bar__copy:hover .s-coupon-bar__copy-icon { opacity: 0.95; }
.s-coupon-bar__copy.is-copied .s-coupon-bar__copy-label { opacity: 0; }
.s-coupon-bar__copy.is-copied::before { content: 'Copied \2713'; position: absolute; left: 0; right: 0; top: 12px; text-align: center; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; font-weight: var(--weight-bold); color: var(--color-success); }
.s-coupon-bar__copy.is-copied .s-coupon-bar__copy-icon { opacity: 1; }
.s-coupon-bar__copy.is-copied .s-coupon-bar__icon-copy { opacity: 0; transform: scale(0.6); }
.s-coupon-bar__copy.is-copied .s-coupon-bar__icon-check { opacity: 1; transform: scale(1); }
.s-coupon-bar__status { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.s-coupon-bar--compact { border-radius: var(--radius-md); }
.s-coupon-bar--compact .s-coupon-bar__info { padding: var(--space-2) var(--space-3); gap: var(--space-2); }
.s-coupon-bar--compact .s-coupon-bar__icon { flex-basis: 28px; width: 28px; height: 28px; }
.s-coupon-bar--compact .s-coupon-bar__icon svg { width: 15px; height: 15px; }
.s-coupon-bar--compact .s-coupon-bar__head { font-size: var(--text-sm); }
.s-coupon-bar--compact .s-coupon-bar__sub { display: none; }
.s-coupon-bar--compact .s-coupon-bar__copy { min-width: 112px; padding: 8px var(--space-4); }
.s-coupon-bar--compact .s-coupon-bar__copy-value { font-size: var(--text-sm); }
@media (max-width: 480px) {
    .s-coupon-bar, .s-coupon-bar--compact { flex-direction: column; }
    .s-coupon-bar__copy { border-left: 0; border-top: 1.5px dashed var(--border-inverse); width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
    .s-coupon-bar__copy, .s-coupon-bar__copy-label, .s-coupon-bar__copy-icon, .s-coupon-bar__copy-icon svg { transition: none; }
}

/* ── Clinic info card (.s-info-card + .s-info-row / .s-status / .s-hours) ──
   Specializes .s-card for location pages. Status tints use the --success-rgb /
   --granite-rgb channels. .s-info-row / .s-status / .s-hours are reusable alone. */
.s-info-card { background: var(--color-paper); border-color: var(--color-hairline); border-radius: var(--radius-2xl); padding: var(--space-8) var(--space-8) var(--space-7); gap: var(--space-6); box-shadow: var(--shadow-lift); text-align: left; }
.s-status { display: inline-flex; align-items: center; gap: var(--space-2); align-self: flex-start; margin: 0; padding: 6px 14px 6px 10px; border-radius: var(--radius-pill); background: rgb(var(--success-rgb) / 0.12); color: var(--color-text); font-family: var(--font-sans); font-size: var(--text-sm); font-weight: var(--weight-semibold); line-height: 1; }
.s-status__dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: var(--radius-pill); background: var(--color-success); box-shadow: 0 0 0 4px rgb(var(--success-rgb) / 0.18); }
.s-status--pulse .s-status__dot { animation: pulse 2s infinite; }
.s-status--closed { background: rgb(var(--granite-slate-rgb) / 0.12); color: var(--color-text-muted); }
.s-status--closed .s-status__dot { background: var(--granite-slate-100); box-shadow: 0 0 0 4px rgb(var(--granite-slate-rgb) / 0.18); animation: none; }
.s-info-row { display: flex; align-items: flex-start; gap: var(--space-4); text-align: left; }
.s-info-row + .s-info-row { padding-top: var(--space-6); border-top: 1px solid var(--color-hairline); }
.s-info-row__icon { flex: 0 0 36px; width: 36px; height: 36px; border-radius: var(--radius-pill); background: var(--color-mint); color: var(--color-midnight-eagle); display: inline-flex; align-items: center; justify-content: center; }
.s-info-row__icon svg { width: 18px; height: 18px; display: block; }
.s-info-row__body { flex: 1; min-width: 0; }
.s-info-row__label { display: block; margin: 0 0 var(--space-1); font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--color-text-subtle); }
.s-info-row__value { display: block; margin: 0; font-size: var(--text-base); line-height: var(--leading-relaxed); color: var(--color-text); }
.s-info-row__value strong { font-weight: var(--weight-semibold); }
.s-info-row__value a { color: inherit; text-decoration: none; border-radius: var(--radius-sm); transition: color var(--duration-fast) var(--ease-standard); }
.s-info-row__value a:hover { color: var(--color-accent); }
.s-info-row__note { margin: var(--space-2) 0 0; font-size: var(--text-sm); line-height: var(--leading-normal); color: var(--color-text-subtle); }
.s-info-row__link { display: inline-flex; align-items: center; gap: var(--space-1); margin-top: var(--space-2); color: var(--color-accent); font-weight: var(--weight-semibold); font-size: var(--text-sm); text-decoration: none; border-radius: var(--radius-sm); }
.s-info-row__link svg { transition: transform var(--duration-fast) var(--ease-standard); }
.s-info-row__link:hover svg { transform: translateX(3px); }
.s-hours { display: grid; grid-template-columns: auto 1fr; column-gap: var(--space-5); row-gap: var(--space-1); margin: 0; font-size: var(--text-sm); color: var(--color-text); }
.s-hours dt { font-weight: var(--weight-medium); color: var(--color-text-muted); }
.s-hours dd { margin: 0; font-variant-numeric: tabular-nums; }
.s-info-card a:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .s-status--pulse .s-status__dot { animation: none; } }
@media (max-width: 700px) { .s-info-card { padding: var(--space-6) var(--space-6) var(--space-5); } .s-info-row__value { overflow-wrap: anywhere; } }

/* ── Marquee ticker (.marquee) — scrolling value-prop banner ──────
   Promoted from the component-library demo. Pure CSS scroll; pauses on hover. */
.marquee { overflow: hidden; border-top: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); background: var(--color-paper); }
/* Icons sit as separators BETWEEN items (not glued to the following text) — flex `gap`
   on the track keeps every icon perfectly centered in the space between two text runs. */
.marquee-track { display: inline-flex; align-items: center; gap: 28px; white-space: nowrap; animation: marquee-scroll 26s linear infinite; }
.marquee-track .item { display: inline-flex; align-items: center; padding: 14px 0; font-family: var(--font-heading); font-weight: 500; font-size: 18px; color: var(--color-midnight-eagle); }
.marquee-track .m-ico { width: 20px; height: 20px; flex-shrink: 0; }
@keyframes marquee-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.marquee:hover .marquee-track { animation-play-state: paused; }
/* --dark — dark teal banner variant (merged from highlands' inline copy, task 19):
   cream text/icons, hairline light borders, slightly roomier rhythm + slower scroll. */
.marquee--dark { background: var(--color-midnight-eagle); border-top-color: rgb(250 247 244 / 0.14); border-bottom-color: rgb(250 247 244 / 0.14); }
.marquee--dark .marquee-track { animation-duration: 30s; }
.marquee--dark .marquee-track { gap: 32px; }
.marquee--dark .marquee-track .item { padding: 18px 0; color: var(--color-cream); }
.marquee--dark .marquee-track .m-ico { filter: brightness(0) invert(1); }
@media (prefers-reduced-motion: reduce) { .marquee-track { animation: none; } }

/* ── Location hero (.hero-*) — location-page hero organism ────────
   Promoted from the component-library #hero-location demo. Two-column
   (content + framed image): breadcrumbs, location pill, scribble-accent
   headline, ASAP phone, Google-reviews badge. data-part toggles for the
   optional bits + a --variant="fullbleed" full-bleed image variant.
   (On a real page the data-part attrs are inert decoration; the property
   panel that drives them lives only in the component library.) */
.hero-preview { display: grid; grid-template-columns: 1.05fr 0.95fr; align-items: stretch; min-height: 480px; background: var(--cream-60); border-radius: var(--radius-lg); overflow: hidden; }
/* --flat — surface modifier, orthogonal to data-variant (which picks the IMAGE treatment):
   drops the rounded cream card so the hero sits directly on the section's own band — ONE
   flat color edge-to-edge, the production city-page look (Cooper 2026-07-06: "why are
   there multiple colors on the hero?" — card-beige nested on section-beige read as
   unintentional). The section behind it supplies the single background (cream-60).
   Highlands keeps the framed card: no modifier there. */
.hero-preview--flat { background: transparent; border-radius: 0; }
.hero-content { padding: 40px 38px; display: flex; flex-direction: column; justify-content: center; gap: 16px; }
/* Breadcrumbs sit ABOVE the hero card (page-level, top-left) — this margin
   separates them from the card so they read as wayfinding, not hero content. */
.hero-crumbs { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 22px; font-size: 13px; color: var(--midnight-eagle-55); }
.hero-crumbs a { color: var(--midnight-eagle-55); text-decoration: none; }
.hero-crumbs a:hover { color: var(--color-midnight-eagle); }
.hero-crumbs a[aria-current] { color: var(--color-midnight-eagle); font-weight: 600; }
.hero-locpill { align-self: flex-start; display: inline-flex; align-items: center; gap: 8px; padding: 9px 16px; background: var(--cream-100); border-radius: var(--radius-sm); font-size: 14px; font-weight: 500; color: var(--color-accent); /* coral text+pin, matching production (was midnight-eagle) */ }
.hero-locpill svg { flex-shrink: 0; }
.hero-h1 { position: relative; margin: 4px 0 2px; font-family: var(--font-heading); font-weight: 500; font-size: clamp(var(--hero-h1-min), 3.6vw, var(--hero-h1-max)); /* sanctioned fluid exception (D5) — token endpoints */ line-height: 1.04; color: var(--color-midnight-eagle); }
/* .hero-accent-word lives with the accent-mark family above (:279) — it is the
   legacy alias of .s-accent-mark + --underline-curved. The standalone copy that
   used to sit here was the pre-promotion original: identical output, but later in
   the file, so it silently won any edit to the canonical rule. Deleted 2026-07-16. */
.hero-sub { margin: 6px 0 2px; max-width: 30rem; font-size: 17px; line-height: 1.55; color: var(--midnight-eagle-70); }
.hero-sub a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; }
.hero-avail { align-self: flex-start; display: inline-flex; align-items: center; gap: 10px; padding: 10px 16px; background: var(--color-surface); border: 1px solid var(--cream-100); border-radius: var(--radius-md); font-size: 15px; font-weight: 500; color: var(--color-midnight-eagle); box-shadow: var(--shadow-sm); }
.hero-avail .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--mint-100); flex-shrink: 0; }
.hero-coupon { align-self: flex-start; display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; max-width: 420px; background: var(--color-surface); border: 1.5px solid var(--color-accent); border-radius: var(--radius-md); padding: 12px 18px; }
.hero-coupon .code { padding: 7px 13px; border: 1px dashed var(--color-accent); border-radius: var(--radius-sm); font-weight: 700; font-size: 16px; color: var(--color-midnight-eagle); }
.hero-coupon .desc { margin: 0; font-size: 15px; color: var(--midnight-eagle-70); }
/* CTA button group — buttons stretch to the wrapper's width so Book + Call are
   equal-width (the Webflow pattern: wrap buttons, stretch to the div). */
.hero-ctas { display: flex; flex-direction: column; align-items: stretch; gap: 12px; margin-top: 4px; max-width: 20rem; }
.hero-ctas .btn, .hero-ctas .btn-coral { width: 100%; justify-content: center; }
.hero-asap-group { display: flex; flex-direction: column; align-items: stretch; gap: 6px; }
.hero-asap { font-size: 14px; font-weight: 600; color: var(--color-button); text-align: center; }
/* Hero "Call" CTA now uses the canonical .btn.btn--coral-outline (matched a-button
   pair with the filled Book button) — the old bespoke .hero-phone was removed. */
.hero-reviews { align-self: flex-start; display: inline-flex; align-items: center; justify-content: center; /* content centers inside the pill to match the centered button labels + "Need care ASAP?" above it (Cooper 2026-07-10: left-aligned read as odd in the centered CTA column) */ gap: 14px; padding: 12px 20px; width: 20rem; max-width: 100%; box-sizing: border-box; /* same width as the .hero-ctas button column above it (Cooper 2026-07-06) */ background: var(--color-paper); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); text-decoration: none; }
.hero-reviews .g { width: 34px; height: 34px; border-radius: 50%; background: #fff; display: inline-flex; align-items: center; justify-content: center; box-shadow: 0 2px 6px rgba(0,0,0,0.08); flex-shrink: 0; }
.hero-reviews .hr-body { display: flex; flex-direction: column; gap: 3px; }
.hero-reviews .hr-row { display: flex; align-items: center; gap: 10px; }
.hero-reviews .rating { font-family: var(--font-heading); font-weight: 500; font-size: 22px; color: var(--color-midnight-eagle); line-height: 1; }
.hero-reviews .stars { color: var(--color-accent); letter-spacing: 1px; font-size: 15px; }
.hero-reviews .cap { font-size: 12px; color: var(--midnight-eagle-60); }
.hero-ratingbadge { align-self: flex-start; display: flex; flex-direction: column; gap: 6px; }
.hero-ratingbadge .rb-row { display: flex; align-items: center; gap: 10px; }
.hero-ratingbadge .rb-score { font-family: var(--font-heading); font-weight: 500; font-size: 20px; color: var(--color-midnight-eagle); line-height: 1; }
.hero-ratingbadge .rb-stars { display: inline-flex; gap: 3px; color: var(--color-accent); }
.hero-ratingbadge .rb-stars svg { width: 18px; height: 18px; }
.hero-ratingbadge .rb-cap { font-size: 14px; color: var(--midnight-eagle-70); }
/* Third optional hero CTA — the branded "Today's Availability" button (promoted from
   component-library's local .hu-availbtn, task 24; real content ports it onto Denver).
   Production look (Cooper 2026-07-06): NOT a white pill — a flat beige tile with a faint
   street-map texture behind the label. The texture is a mask (::before), so the streets
   tint from the midnight-eagle token instead of baking a hex into the data URI. */
.hero-availbtn { position: relative; isolation: isolate; display: inline-flex; align-items: center; gap: 14px; padding: 15px 26px; background: rgb(var(--midnight-eagle-rgb) / 0.05); /* adaptive light tint — surface-raised read too dark (Cooper 2026-07-06) */ border: none; border-radius: var(--radius-md); font-size: 18px; font-weight: 600; color: var(--color-midnight-eagle); text-decoration: none; box-shadow: none; transition: box-shadow var(--duration-fast) var(--ease-standard); }
.hero-availbtn::before {
    content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
    background: var(--color-midnight-eagle); opacity: 0.07; pointer-events: none;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cg fill='none' stroke='%23000' stroke-width='3'%3E%3Cpath d='M-6 34h44q10 0 10 10v102'/%3E%3Cpath d='M96 -6v52q0 10 10 10h40'/%3E%3Cpath d='M-6 104h56q8 0 8-8V62'/%3E%3Cpath d='M118 146V96q0-8-8-8H84'/%3E%3C/g%3E%3Ccircle cx='104' cy='112' r='5' fill='%23000'/%3E%3C/svg%3E") 0 0 / 140px 140px repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cg fill='none' stroke='%23000' stroke-width='3'%3E%3Cpath d='M-6 34h44q10 0 10 10v102'/%3E%3Cpath d='M96 -6v52q0 10 10 10h40'/%3E%3Cpath d='M-6 104h56q8 0 8-8V62'/%3E%3Cpath d='M118 146V96q0-8-8-8H84'/%3E%3C/g%3E%3Ccircle cx='104' cy='112' r='5' fill='%23000'/%3E%3C/svg%3E") 0 0 / 140px 140px repeat;
}
.hero-availbtn:hover { box-shadow: var(--shadow-sm); }
.hero-availbtn svg { color: var(--color-midnight-eagle); flex-shrink: 0; }
.hero-media { position: relative; display: flex; align-items: center; justify-content: center; padding: 18px; }
.hero-frame { position: relative; width: 100%; max-width: 440px; aspect-ratio: 4 / 5; }
.hero-frame__back { position: absolute; inset: 16px -14px -12px 14px; background: var(--color-accent); border-radius: var(--radius-lg); transform: rotate(-2.5deg); }
.hero-frame__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: var(--radius-lg); transform: rotate(1.2deg); box-shadow: var(--shadow-feature); }
.hero-sticker { position: absolute; top: 2px; right: -2px; z-index: 3; transform: rotate(4deg); padding: 8px 16px; background: var(--color-surface); border-radius: var(--radius-pill); font-family: var(--font-heading); font-style: italic; font-size: 15px; color: var(--color-midnight-eagle); box-shadow: var(--shadow-lift); }
.hero-preview[data-variant="fullbleed"] .hero-media { padding: 0; }
.hero-preview[data-variant="fullbleed"] .hero-frame { max-width: none; aspect-ratio: auto; position: absolute; inset: 0; }
.hero-preview[data-variant="fullbleed"] .hero-frame__back,
.hero-preview[data-variant="fullbleed"] .hero-sticker { display: none; }
.hero-preview[data-variant="fullbleed"] .hero-frame__img { border-radius: 0; transform: none; box-shadow: none; }
[data-part].is-off { display: none !important; }
@media (max-width: 820px) {
  /* minmax(0, 1fr), not bare 1fr — the stacked column's automatic minimum
     size otherwise grows to fit .hero-media's content (Cooper 2026-07-10:
     photo was rendering ~50px wider than the card and getting clipped by
     .hero-preview's overflow:hidden, reading as "cut off"/lopsided margins). */
  .hero-preview { grid-template-columns: minmax(0, 1fr); }
  /* Stacked: the desktop 38px card padding sits on top of the section's own 16px
     container padding, so keep the card's share slim on small screens. */
  .hero-content { padding: 32px 20px; }
  /* Stacked: content FIRST, photo LAST (Cooper 2026-07-06 — was order:-1/image-first),
     and the frame flips from the tall 4:5 desktop portrait to a wide 16:9 band so the
     photo doesn't push the headline and CTAs below the fold. Side padding leaves room
     for the rotated coral back-card's overhang (±14px). */
  .hero-media { padding: 0 20px 20px; }
  .hero-frame { max-width: none; aspect-ratio: 16 / 9; }
  .hero-preview[data-variant="fullbleed"] .hero-media { min-height: 240px; }
}

/* ── Services carousel (.s-pill-tabs--teal toggle + .dvr-svc-* slider + .concerns-grid) ──
   Promoted from the component-library demo. The "What we treat" block: a
   Services / Symptoms segmented toggle (.s-pill-tabs--teal, shared component)
   over two panels — a scroll-snapping card carousel (prev/next via
   sploot-components.js initServicesCarousels) + a concerns grid. The tabs
   used to be a bespoke .svc-tabs/.svc-tab-btn/.svc-tab-panel trio; retired
   onto .s-pill-tabs/.s-pill-tab/.s-pill-panel, task 22 close-out. */
.dvr-svc-slider { position: relative; }
.dvr-svc-track { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(260px, 300px); gap: 20px; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-left: 16px; padding: 10px 16px 30px; scrollbar-width: none; }
.dvr-svc-track::-webkit-scrollbar { display: none; }
.dvr-svc-card { scroll-snap-align: start; position: relative; isolation: isolate; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); overflow: visible; box-shadow: 0 8px 24px -10px rgb(var(--midnight-eagle-rgb) / 0.16); display: flex; flex-direction: column; text-decoration: none; color: inherit; transition: box-shadow 0.22s ease; }
.dvr-svc-card::before { content: ""; position: absolute; inset: 0; border-radius: var(--radius-lg); background: var(--color-coral); transform: rotate(-3deg); opacity: 0; z-index: -1; transition: opacity 0.22s ease, transform 0.22s ease; }
/* Hover: the card itself stays put — only the coral back-plate swings in (+ a shadow
   deepen). The old translateY(-4px) lift was pulled (Cooper 2026-07-10). */
.dvr-svc-card:hover { box-shadow: var(--shadow-card-hover); }
.dvr-svc-card:hover::before { opacity: 1; transform: rotate(-4deg) translateY(6px); }
.dvr-svc-art { aspect-ratio: 4/3; width: 100%; display: block; object-fit: cover; background: var(--color-cream); border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
.dvr-svc-art.t1 { background: linear-gradient(135deg, var(--cream-60) 0%, #E9DFD8 100%); }
.dvr-svc-art.t2 { background: linear-gradient(135deg, var(--mint-40) 0%, #C9E4D8 100%); }
.dvr-svc-art.t3 { background: linear-gradient(135deg, #FCE6E1 0%, #F3C9C2 100%); }
.dvr-svc-art.t4 { background: linear-gradient(135deg, #DCE9E7 0%, #B7CFCB 100%); }
.dvr-svc-body { padding: 20px 20px 22px; display: flex; flex-direction: column; gap: 8px; flex: 1; background: var(--color-surface); border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
.dvr-svc-body h4 { margin: 0; font-family: var(--font-heading); font-weight: 500; font-size: 20px; color: var(--color-midnight-eagle); }
.dvr-svc-body p { margin: 0; color: var(--color-text-muted); line-height: 1.55; font-size: 14px; flex: 1; }
.dvr-svc-link { margin-top: 4px; color: var(--color-accent); font-weight: 600; font-size: 14px; }
.dvr-svc-link::after { content: ' →'; }
.dvr-svc-controls { display: flex; justify-content: center; gap: 12px; margin-top: 8px; }
.dvr-svc-btn { width: 44px; height: 44px; border-radius: var(--radius-pill); border: 1px solid var(--color-border-strong); background: var(--color-surface); color: var(--color-midnight-eagle); font-size: 20px; line-height: 1; cursor: pointer; transition: var(--transition-colors); }
.dvr-svc-btn:hover { background: var(--color-accent); border-color: var(--color-accent); color: #fff; }
.concerns-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 8px auto 0; max-width: 920px; }
@media (max-width: 768px) { .concerns-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .concerns-grid { grid-template-columns: 1fr; } }
.concerns-grid a { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px 14px 20px; min-height: 64px; background: var(--color-paper); border: 1px solid var(--color-hairline); border-radius: var(--radius-md); text-decoration: none; color: var(--color-midnight-eagle); font-size: 15px; line-height: 1.35; transition: background 0.2s ease, transform 0.2s ease, border-color 0.2s ease; }
.concerns-grid a::after { content: '→'; flex: 0 0 auto; color: var(--color-accent); font-weight: 600; font-size: 16px; opacity: 0; transform: translateX(-6px); transition: opacity 0.2s ease, transform 0.2s ease; }
.concerns-grid a:hover { background: var(--color-surface); border-color: rgb(var(--opal-120-rgb) / 0.45); transform: translateY(-2px); }

/* ── SplootRx callout (.rx-callout) — promoted from the splootrx page ──
   Split hero (copy + 3-slide image slider) + 3 benefit cards. Entrance anims
   gated by .rx-callout.rx-ready (no-JS-safe). Behavior: sploot-components.js
   (initRxCallouts) — reveal observer + slider, multi-instance. */
/* ── SplootRx callout (.rx-callout) — split hero + slider + benefit cards ──
   A drop-in promo organism: copy left, a 3-slide image slider right (auto-
   advance + dot nav), then a row of 3 benefit cards (the middle one featured).

   Reveal-on-scroll safety: the entrance-animation INITIAL states (opacity:0 /
   transforms) are scoped under `.rx-callout.rx-ready`, a class JS adds the
   moment it initializes. With no JS (no .rx-ready) every element is fully
   visible. JS then adds `.rx-callout.rx-active` when the section scrolls into
   view to play the reveal. prefers-reduced-motion disables the motion. */

/* ── Reveal: initial (hidden) states — ONLY once JS marks the block ready ── */
.rx-callout.rx-ready .rx-eyebrow {
    opacity: 0;
    transform: translateY(20px);
    transition: all 0.6s var(--ease-out-expo);
}
.rx-callout.rx-ready .rx-headline {
    opacity: 0;
    clip-path: inset(100% 0 0 0);
    transition: all 0.9s var(--ease-out-expo) 0.12s;
}
.rx-callout.rx-ready .rx-subline {
    opacity: 0;
    transform: translateY(24px);
    transition: all 0.7s var(--ease-out-expo) 0.3s;
}
.rx-callout.rx-ready .rx-cta-inline {
    opacity: 0;
    transform: translateY(16px);
    transition: all 0.6s var(--ease-out-expo) 0.45s;
}
.rx-callout.rx-ready .rx-hero-img {
    opacity: 0;
    transform: translateX(40px) scale(0.97);
    transition: all 0.9s var(--ease-out-expo) 0.2s;
}
.rx-callout.rx-ready .rx-hero-accent {
    opacity: 0;
    transform: translateX(50px) rotate(3deg) scale(0.95);
    transition: all 1s var(--ease-out-expo) 0.1s;
}
.rx-callout.rx-ready .rx-divider {
    width: 0;
    transition: width 1.2s var(--ease-out-expo) 0.5s;
}
.rx-callout.rx-ready .rx-card {
    opacity: 0;
    transform: translateY(50px) scale(0.96);
    transition: all 0.7s var(--ease-out-expo);
}
.rx-callout.rx-ready .rx-card:nth-child(1) { transition-delay: 0.6s; }
.rx-callout.rx-ready .rx-card:nth-child(2) { transition-delay: 0.75s; }
.rx-callout.rx-ready .rx-card:nth-child(3) { transition-delay: 0.9s; }
.rx-callout.rx-ready .rx-bottom-cta {
    opacity: 0;
    transform: translateY(20px);
    transition: all 0.6s var(--ease-out-expo) 1.05s;
}

/* ── Reveal: active (in-view) states ── */
.rx-callout.rx-active .rx-eyebrow,
.rx-callout.rx-active .rx-subline,
.rx-callout.rx-active .rx-cta-inline,
.rx-callout.rx-active .rx-bottom-cta {
    opacity: 1;
    transform: translateY(0);
}
.rx-callout.rx-active .rx-headline {
    opacity: 1;
    clip-path: inset(0 0 0 0);
}
.rx-callout.rx-active .rx-hero-img {
    opacity: 1;
    transform: translateX(0) scale(1);
}
.rx-callout.rx-active .rx-hero-accent {
    opacity: 1;
    transform: translateX(0) rotate(3deg) scale(1);
}
.rx-callout.rx-active .rx-divider {
    width: 100%;
}
.rx-callout.rx-active .rx-card {
    opacity: 1;
    transform: translateY(0) scale(1);
}

/* ── Card interactivity ── */
.rx-card {
    position: relative;
    overflow: hidden;
    cursor: default;
}
/* Gradient hairline border, faded in on hover */
.rx-card::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(135deg, rgb(var(--opal-rgb) / 0.35), rgb(var(--midnight-eagle-rgb) / 0.15), transparent);
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
    opacity: 0;
    transition: opacity var(--duration-slow) var(--ease-standard);
}
.rx-card:hover::before { opacity: 1; }

.rx-card-inner {
    transition: transform 0.5s var(--ease-out-expo);
}
.rx-card:hover .rx-card-inner {
    transform: translateY(-4px);
}
.rx-card-featured:hover .rx-card-inner {
    transform: none;
}

/* Icon containers: scale + color change on card hover */
.rx-icon-wrap {
    transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1),
                background 0.3s var(--ease-standard);
}
.rx-card:hover .rx-icon-wrap {
    transform: scale(1.1) rotate(-4deg);
    background: var(--color-accent);
}
.rx-card:hover .rx-icon-wrap svg {
    color: var(--color-white);
}
.rx-card-featured .rx-icon-wrap { background: rgba(255,255,255,0.15); }
.rx-card-featured:hover .rx-icon-wrap {
    background: var(--color-accent);
}
.rx-card-featured .rx-icon-wrap svg { color: var(--color-accent); }
.rx-card-featured:hover .rx-icon-wrap svg { color: var(--color-white); }

/* Hidden detail: space always reserved to avoid layout shift */
.rx-hidden-detail {
    min-height: 2.25rem;
    margin-top: 0.75rem;
}
.rx-hidden-detail span {
    display: inline-block;
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity 0.35s var(--ease-standard), transform 0.35s var(--ease-standard);
}
.rx-card:hover .rx-hidden-detail span {
    opacity: 1;
    transform: translateY(0);
}

/* Featured card glow */
.rx-card-featured {
    box-shadow: 0 0 0 0 rgb(var(--opal-rgb) / 0);
    transition: box-shadow 0.6s var(--ease-standard);
}
.rx-callout.rx-active .rx-card-featured {
    box-shadow: 0 8px 40px rgb(var(--opal-rgb) / 0.12);
}
.rx-card-featured:hover {
    box-shadow: 0 12px 48px rgb(var(--opal-rgb) / 0.22);
}

/* ── CTA shine sweep ── */
.rx-cta {
    position: relative;
    overflow: hidden;
}
.rx-cta::after {
    content: '';
    position: absolute;
    top: 0; left: -100%;
    width: 60%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.25), transparent);
    transition: left 0.6s var(--ease-standard);
}
.rx-cta:hover::after {
    left: 120%;
}

/* ── Hero image / slider treatment ── */
.rx-img-wrap {
    position: relative;
}
.rx-img-wrap .rx-accent-shape {
    position: absolute;
    inset: -12px;
    background: linear-gradient(135deg, var(--color-mint) 0%, #E07A6A20 100%);
    border-radius: 2rem;
    transform: rotate(3deg);
    z-index: 0;
}
.rx-img-wrap img {
    position: relative;
    z-index: 1;
}

/* ── Hero slider ── */
.rx-hero-slider {
    position: relative;
    width: 100%;
    height: 380px;
}
@media (min-width: 768px) {
    .rx-hero-slider {
        height: 440px;
    }
}
.rx-hero-slider .rx-slide {
    position: absolute;
    inset: 0;
    border-radius: 1.5rem;
    overflow: hidden;
    opacity: 0;
    z-index: 1;
    transition: opacity 0.6s var(--ease-out-expo);
}
.rx-hero-slider .rx-slide.active {
    opacity: 1;
    z-index: 2;
}
.rx-hero-slider .rx-slide img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.rx-hero-slider .rx-slide-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding: 1.5rem;
    background: linear-gradient(to top, rgb(var(--midnight-eagle-rgb) / 0.75) 0%, transparent 50%);
    pointer-events: none;
}
.rx-hero-slider .rx-slide-overlay span {
    text-align: center;
    color: var(--color-white);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    text-shadow: 0 1px 2px rgba(0,0,0,0.3);
}
.rx-slider-dots {
    position: absolute;
    bottom: 1rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 20;
    display: flex;
    gap: 0.5rem;
}
.rx-slider-dots button {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-pill);
    border: none;
    background: rgb(var(--midnight-eagle-rgb) / 0.25);
    cursor: pointer;
    transition: background 0.3s var(--ease-standard), transform 0.2s var(--ease-standard);
}
.rx-slider-dots button:hover {
    background: rgb(var(--midnight-eagle-rgb) / 0.5);
}
.rx-slider-dots button.active {
    background: var(--color-midnight-eagle);
    transform: scale(1.2);
}

/* Floating badge on hero image */
@keyframes rx-float {
    0%, 100% { transform: translateY(0px); }
    50% { transform: translateY(-8px); }
}
.rx-float-badge {
    animation: rx-float 3.5s ease-in-out infinite;
}

/* ── Mobile: cards become a horizontal snap-scroll track ── */
@media (max-width: 767px) {
    .rx-cards-track {
        display: flex;
        gap: 1rem;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        padding-bottom: 1rem;
        scrollbar-width: none;
    }
    .rx-cards-track::-webkit-scrollbar { display: none; }
    .rx-cards-track > .rx-card {
        flex: 0 0 85%;
        scroll-snap-align: center;
    }
}

/* ── Reduced motion: kill reveal transforms + the float loop ── */
@media (prefers-reduced-motion: reduce) {
    .rx-callout.rx-ready .rx-eyebrow,
    .rx-callout.rx-ready .rx-headline,
    .rx-callout.rx-ready .rx-subline,
    .rx-callout.rx-ready .rx-cta-inline,
    .rx-callout.rx-ready .rx-hero-img,
    .rx-callout.rx-ready .rx-hero-accent,
    .rx-callout.rx-ready .rx-card,
    .rx-callout.rx-ready .rx-bottom-cta {
        opacity: 1;
        transform: none;
        clip-path: none;
        transition: none;
    }
    .rx-callout.rx-ready .rx-hero-accent { transform: rotate(3deg); }
    .rx-callout.rx-ready .rx-divider {
        width: 100%;
        transition: none;
    }
    .rx-float-badge { animation: none; }
    .rx-hero-slider .rx-slide { transition: none; }
}

/* ── Plan comparison (.plan-card / .plan-savings) ────────────────
   Promoted from the about page (task 27, audit + Cooper's "how can we
   componentize this section?"). about.html and financing.html each built
   this "membership vs pay-as-you-go" pair independently — near-identical
   Tailwind, real drift (financing's CTA was raw utilities instead of the
   canonical .btn; about forces a 3-col savings grid, financing collapses
   to 1 column on mobile).

   Scope call: only the CARD + STAT-BOX visual language is unified here.
   The two pages keep their own container strategy on purpose — about
   wraps its cards in a swipeable slider (.sp-slider, shared with its
   reviews slider, own JS), financing uses a plain grid that stacks on
   mobile. Neither is wrong; forcing one onto the other wasn't asked for.
   Same story for financing's savings count-up animation (progressive
   enhancement, page-owns-its-JS) — .plan-savings works with static
   numbers or a page's own data-count wiring, it doesn't require either.

   Glassmorphic-on-dark-teal is a distinct enough look from the plain
   .s-card system (solid surface, no blur) that this is its own
   self-contained component rather than an .s-card modifier — avoids
   retrofitting glass/blur onto a card system used elsewhere on solid
   light backgrounds. */
.plan-card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: rgba(255, 255, 255, 0.05);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: var(--radius-2xl);
    padding: 32px;
}
@media (min-width: 1024px) { .plan-card { padding: 40px; } }
.plan-card--featured { background: rgba(255, 255, 255, 0.12); border-color: rgba(255, 255, 255, 0.15); }
.plan-card__badge {
    position: absolute; top: 16px; right: 16px;
    display: inline-flex; align-items: center;
    font-size: 11px; font-weight: var(--weight-bold);
    text-transform: uppercase; letter-spacing: 0.06em;
    background: var(--color-accent); color: var(--color-white);
    border-radius: var(--radius-pill); padding: 4px 12px;
}
.plan-card__head { display: flex; align-items: center; gap: var(--space-4); margin-bottom: var(--space-6); }
.plan-card__icon {
    width: 48px; height: 48px; flex-shrink: 0;
    border-radius: var(--radius-xl);
    background: rgba(255, 255, 255, 0.10);
    border: 1px solid rgba(255, 255, 255, 0.10);
    display: flex; align-items: center; justify-content: center;
    color: rgba(255, 255, 255, 0.6);
}
.plan-card--featured .plan-card__icon { border-color: rgba(255, 255, 255, 0.15); color: var(--color-accent); }
.plan-card__icon svg { width: 24px; height: 24px; }
.plan-card__kicker { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.15em; color: rgba(255, 255, 255, 0.4); }
.plan-card__title { font-family: var(--font-heading); font-size: var(--text-2xl); font-weight: var(--weight-bold); color: var(--color-white); margin-bottom: var(--space-4); }
.plan-card__price-label { font-size: var(--text-sm); color: rgba(255, 255, 255, 0.5); }
.plan-card__price-value { font-family: var(--font-heading); font-size: var(--text-5xl); font-weight: var(--weight-bold); color: var(--color-accent); line-height: 1; }
.plan-card__price-value--muted { font-size: var(--text-3xl); color: rgba(255, 255, 255, 0.7); line-height: 1; }
.plan-card__price-unit { font-size: var(--text-sm); font-weight: var(--weight-medium); color: rgba(255, 255, 255, 0.4); }
.plan-card__price-note { font-size: var(--text-xs); color: rgba(255, 255, 255, 0.3); margin-top: 4px; }
.plan-card__list-intro { font-size: var(--text-sm); color: rgba(255, 255, 255, 0.5); margin-bottom: var(--space-4); }
.plan-card__divider { border-top: 1px solid rgba(255, 255, 255, 0.10); margin-top: var(--space-5); padding-top: var(--space-5); }
.plan-card__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; flex: 1; }
.plan-card__list li { display: flex; align-items: flex-start; gap: var(--space-3); font-size: var(--text-sm); color: rgba(255, 255, 255, 0.5); }
.plan-card__list li strong { color: var(--color-white); font-weight: var(--weight-semibold); }
.plan-card__list li.is-included { color: rgba(255, 255, 255, 0.8); }
.plan-card__list svg { width: 20px; height: 20px; flex-shrink: 0; margin-top: 1px; color: rgba(255, 255, 255, 0.25); }
.plan-card__list li.is-included svg { color: var(--color-accent); }
.plan-card__cta-row { margin-top: auto; padding-top: var(--space-8); }
.plan-card__cta-ghost {
    /* Padding matches .btn--sm's scale (0.65em, not the base .btn's 0.95em) so it
       reads as the same size as the coral .btn--coral.btn--sm it sits beside
       (Cooper 2026-07-10: was visibly chunkier despite sharing the same 14px text). */
    width: 100%; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
    background: rgba(255, 255, 255, 0.10); color: var(--color-white);
    border: 1px solid rgba(255, 255, 255, 0.20);
    padding: 0.65em 1.4em; border-radius: var(--radius-pill);
    font-family: var(--font-sans); font-size: var(--text-sm); font-weight: var(--weight-semibold);
    text-decoration: none;
    transition: var(--transition-colors), transform var(--duration-fast) var(--ease-standard);
}
.plan-card__cta-ghost:hover { background: rgba(255, 255, 255, 0.20); }

.plan-savings {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: var(--radius-xl);
    padding: 24px;
    max-width: 48rem; margin: 0 auto;
}
@media (min-width: 768px) { .plan-savings { padding: 32px; } }
.plan-savings__label { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.15em; color: rgba(255, 255, 255, 0.4); text-align: center; margin-bottom: var(--space-5); }
.plan-savings__grid { display: grid; grid-template-columns: 1fr; gap: 12px; text-align: center; align-items: stretch; }
@media (min-width: 640px) { .plan-savings__grid { grid-template-columns: repeat(3, 1fr); gap: var(--space-4); } }
/* Mobile: compact label/value row (financing's original treatment — nicer than stacking
   three full paragraphs). Desktop: stacked column, value flush to the grid's baseline. */
.plan-savings__stat { display: flex; flex-direction: row; align-items: baseline; justify-content: space-between; }
@media (min-width: 640px) { .plan-savings__stat { flex-direction: column; align-items: stretch; justify-content: flex-end; } }
.plan-savings__stat-label { font-size: var(--text-xs); color: rgba(255, 255, 255, 0.3); margin-bottom: 4px; }
.plan-savings__stat-value { font-family: var(--font-heading); font-size: var(--text-2xl); font-weight: var(--weight-bold); }
.plan-savings__stat-value--was { color: rgba(255, 255, 255, 0.6); text-decoration: line-through; text-decoration-color: rgb(var(--opal-rgb) / 0.5); }
.plan-savings__stat-value--now { color: var(--color-white); }
.plan-savings__stat-value--save { color: var(--color-accent); }
.plan-savings__note { font-size: var(--text-xs); color: rgba(255, 255, 255, 0.3); text-align: center; margin-top: var(--space-4); }


/* ── Regional pricing card (.region-card) — photo-header click-through card ──
   Promoted from membership.html (componentization audit 2026-07). Was previously
   built on .rx-card/.rx-card-inner — the SplootRx *callout*'s benefit-card classes,
   borrowed only for their hover-glow/reveal mechanics even though the visual (photo
   header, full-card link, region pricing) has nothing to do with SplootRx. Renamed
   to its own component rather than merged into .plan-card: .plan-card is a dark
   glass panel built for the membership-vs-pay-as-you-go comparison (see above) and
   has no media slot — forcing this photo-header pattern into it would be a visual
   regression, not a real dedupe. Card background/text-color stay page-local Tailwind
   utility classes (e.g. bg-sploot-cream/60 vs bg-sploot-teal text-white) since that's
   the one true per-region difference. */
.region-card {
    position: relative;
    cursor: pointer;
    text-decoration: none;
    opacity: 0;
    transform: translateY(50px) scale(0.96);
    transition: opacity var(--duration-base) cubic-bezier(0.16, 1, 0.3, 1),
                transform var(--duration-base) cubic-bezier(0.16, 1, 0.3, 1);
}
.region-card:focus-visible {
    outline: 3px solid rgba(224, 122, 106, 0.45);
    outline-offset: 3px;
}
/* Gradient hairline border + inner lift on hover — same feel as .rx-card, own rules */
.region-card::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(135deg, rgb(var(--opal-rgb) / 0.35), rgb(var(--midnight-eagle-rgb) / 0.15), transparent);
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
    opacity: 0;
    transition: opacity var(--duration-slow) var(--ease-standard);
}
.region-card:hover::before { opacity: 1; }
.region-card__body { transition: transform 0.5s var(--ease-out-expo); }
.region-card:hover .region-card__body { transform: translateY(-4px); }
.region-card:nth-child(1) { transition-delay: 0.15s; }
.region-card:nth-child(2) { transition-delay: 0.3s; }
.is-revealed .region-card {
    opacity: 1;
    transform: translateY(0) scale(1);
}
@media (prefers-reduced-motion: reduce) {
    .region-card { opacity: 1; transform: none; transition: none; }
}
@media (max-width: 767px) {
    .region-cards-track {
        display: flex;
        gap: 1rem;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        padding-bottom: 1rem;
        scrollbar-width: none;
    }
    .region-cards-track::-webkit-scrollbar { display: none; }
    .region-cards-track > .region-card {
        flex: 0 0 85%;
        scroll-snap-align: center;
    }
}

/* ── Service-page shell (.svc-page / .svc-section) ────────────────
   Shared chrome of the three service pages (emergency-services,
   primary-care, wellness-exams): page tokens, heading/paragraph
   defaults, the 1440px section container, the split hero (copy left,
   rotated framed photo right), the centered .why-head, and the .btn
   phone-glyph + subline adjuncts. Re-derived 2026-07-10 from the three
   pages' CURRENT css (the 2026-07-09 extraction was reverted on merge;
   this one starts from the post-sweep pages, so the canonical-.btn,
   coral-accent, and eyebrow fixes are baked in). Exactly the rule set
   that was byte-identical across all three pages — near-identical
   variants (h em accent color, .hero .subhead, sec-head cousins like
   .acc-head/.how-head) deliberately stay page-local.
   Markup contract: <main class="pc-page svc-page"> — the page class
   stays for page-specific rules; section wrappers are .svc-section. */
.svc-page {
    --color-eagle-muted:      #597776;
    --color-timberwolf-warm:  #F8EFEA;
    --color-timberwolf-cool:  #E7DFD9;
    --color-mint-deep:        #0AA370;
    --color-white:            #FFFFFF;
    --font-sans:              "Outfit", "Helvetica Neue", Arial, sans-serif;
    --radius-image:           16px;
    --r-lg:  16px;
    --shadow-xs:  0 1px 2px rgba(22, 67, 71, 0.06);
    --shadow-sm:  0 2px 6px rgba(22, 67, 71, 0.08);
    --shadow-md:  0 8px 20px rgba(22, 67, 71, 0.10);
    --shadow-lg:  0 20px 40px rgba(22, 67, 71, 0.14);
    --shadow-opal: 0 10px 24px rgba(239, 73, 83, 0.22);
    --ease-standard:  cubic-bezier(0.4, 0, 0.2, 1);
    --ease-out-soft:  cubic-bezier(0.22, 1, 0.36, 1);
    --dur-fast: 120ms;
    --dur-base: 200ms;
    --dur-slow: 360ms;
    color: var(--midnight-eagle-120);
}
.svc-page h1, .svc-page h2, .svc-page h3, .svc-page h4, .svc-page h5 {
    font-family: var(--font-heading);
    font-weight: 500;
    color: var(--midnight-eagle-120);
    margin: 0;
    line-height: 1.1;
    letter-spacing: -0.005em;
}
.svc-page p { margin: 0 0 12px; }
.svc-section {
    position: relative;
    /* Full-bleed section backgrounds: the section spans the full viewport width and
       its content is centered to a 1280px zone via padding — so tinted and dark
       sections no longer leave gutters of the page's base color on screens > 1440px.
       (Content width is unchanged from the old max-width:1440 + 80px padding.) */
    padding: 96px max(80px, calc((100% - 1280px) / 2));
    margin: 0 auto;
}
/* CTAs are the canonical .btn; only the phone glyph + italic subline live here. */
.svc-page .icon-square {
    width: 16px; height: 16px; background: currentColor; opacity: 1;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.79 19.79 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.37 1.9.72 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.35 1.85.59 2.81.72A2 2 0 0 1 22 16.92z'/></svg>") no-repeat center/contain;
            mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.79 19.79 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.37 1.9.72 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.35 1.85.59 2.81.72A2 2 0 0 1 22 16.92z'/></svg>") no-repeat center/contain;
}
.svc-page .btn-sub {
    font-size: 13px; color: var(--granite-100); margin-top: 10px;
    font-style: italic;
}
/* Split hero (copy left, rotated framed photo right) */
.svc-page .hero-section { padding-top: 64px; padding-bottom: 96px; }
.svc-page .hero {
    display: grid; grid-template-columns: 1.1fr 1fr;
    gap: 72px; align-items: center;
    padding-top: 0; padding-bottom: 0;
}
.svc-page .hero h1 {
    font-size: 72px; line-height: 1.02; margin-bottom: 22px;
    font-weight: 500; letter-spacing: -0.01em;
    color: var(--midnight-eagle-120);
}
.svc-page .hero-ctas { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 10px; }
.svc-page .hero-visual {
    position: relative;
    aspect-ratio: 5/6;
    padding: 0;
    max-width: 520px;
    margin-left: auto;
}
.svc-page .hero-visual::before {
    content: "";
    position: absolute;
    inset: 18px -14px -6px 14px;
    background: var(--color-accent);
    border-radius: var(--radius-image);
    transform: rotate(-2deg);
    z-index: 0;
}
.svc-page .hero-visual .hero-visual-inner {
    position: relative;
    z-index: 1;
    width: 100%; height: 100%;
    overflow: hidden;
    border-radius: var(--radius-image);
    background: var(--color-timberwolf-warm);
    transform: rotate(1deg);
    box-shadow: var(--shadow-lg);
}
.svc-page .hero-visual img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Centered section head (the shared one; .acc-head/.how-head cousins stay page-local) */
.svc-page .why-head { text-align: center; max-width: 760px; margin: 0 auto 56px; }
.svc-page .why-head h2 { font-size: 48px; margin-bottom: 14px; color: var(--midnight-eagle-120); }
@media (max-width: 1024px) {
    .svc-section { padding: 72px 40px; }
    .svc-page .hero { grid-template-columns: 1fr; gap: 48px; padding-top: 0; padding-bottom: 0; }
    .svc-page .hero-section { padding-top: 48px; padding-bottom: 72px; }
    .svc-page .hero h1 { font-size: 52px; }
    .svc-page .hero-visual { aspect-ratio: 16/9; max-width: 440px; margin: 0 auto; }
}
@media (max-width: 640px) {
    .svc-section { padding: 56px 20px; }
    .svc-page .hero-section { padding-top: 32px; padding-bottom: 56px; }
    .svc-page .hero { gap: 32px; }
    .svc-page .hero h1 { font-size: 38px; line-height: 1.05; }
    /* p.subhead (not .subhead) is deliberate: each page keeps its own BASE
       .XX-page .hero .subhead rule (they genuinely differ), and page <style>
       loads after this file — the type selector keeps this mobile override
       winning, as it did when it lived in the page blocks. */
    .svc-page .hero p.subhead { font-size: 16px; margin-bottom: 20px; }
    .svc-page .hero-visual { max-width: 100%; }
    .svc-page .eyebrow-wf { font-size: 11px; margin-bottom: 14px; }
    .svc-page .hero-ctas { flex-direction: column; align-items: stretch; }
    .svc-page .why-card h4 { font-size: 18px; }
}
