/* ============================================================================
 *  service.css - Page-scoped stylesheet for service-detail pages.
 *
 *  Loaded by service.php only. Holds the Tier 1 convergence styles:
 *    - Pricing (menu / consultation) per pricing_mode
 *    - Recent at K Bella prose
 *    - Active Special banner above form
 *    - Premium FAQ accordion enhancement
 *
 *  The hero uses the pillar svcs-hero component and the transformations wall
 *  uses ba-grid - both owned by style.css (shared with home + landings).
 *  Existing .svc-story / .svc-gallery / .svc-process / .svc-form / .svc-team
 *  base styles live in style.css and are not duplicated here.
 * ============================================================================ */

/* ============================================================================
 *  SECTION 03 - Gallery FALLBACK wall (only when the service + pillar lack
 *  3 before/after pairs for the ba-grid transformations wall)
 *  DOMINANT MOMENT: an editorial 4-up grid (3-up < 1100px, 2-up < 720px) with
 *  cards that hover-lift and reveal a "Book this look" affordance. Captions
 *  are intentionally minimal - no social-post body copy bleeding through.
 * ============================================================================ */

.svc-gallery {
    background: var(--color-bg);
    padding: clamp(3.5rem, 6vw, 5.5rem) 0;
    position: relative;
}
.svc-gallery__inner {
    max-width: 84rem;
    margin: 0 auto;
    padding: 0 clamp(1.5rem, 4vw, 4rem);
}
.svc-gallery__header {
    text-align: center;
    margin-bottom: clamp(2rem, 3.5vw, 3rem);
}
.svc-gallery__heading {
    font-family: var(--font-serif);
    font-size: clamp(2rem, 4vw, 3.25rem);
    font-weight: 370;
    line-height: 1.06;
    letter-spacing: -0.012em;
    color: var(--color-heading);
    margin: 0;
    text-wrap: balance;
}
/* DOMINANT MOMENT: aligned 3:4 wall with on-photo corner-split credits -
   .svc-gallery__wall (the /gallery/ grid language: aligned tops, one uniform
   gutter). The brides-wall stagger is retired here - at 3 rows the offset
   read as misalignment, not rhythm (Ben 2026-07-03). */
.svc-gallery__wall {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: clamp(0.9rem, 2vw, 1.5rem);
}
@media (min-width: 901px) {
    .svc-gallery__wall {
        grid-template-columns: repeat(3, 1fr);
        gap: clamp(1.1rem, 2.5vw, 1.75rem);
    }
}
.svc-gallery__cell {
    position: relative;
    margin: 0;
    aspect-ratio: 3 / 4;
    border-radius: 6px;
    overflow: hidden;
    background: var(--color-bg-alt);
    box-shadow:
        0 1px 0 rgba(58, 40, 40, 0.04),
        0 22px 44px -24px rgba(58, 40, 40, 0.3);
}
.svc-gallery__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
    .svc-gallery__img {
        transition: transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
    }
    .svc-gallery__cell:hover .svc-gallery__img {
        transform: scale(1.045);
    }
}
.svc-gallery__more {
    text-align: center;
    margin: clamp(2.25rem, 4.5vw, 3.5rem) 0 0;
    /* Global p measure caps this at 68ch - the button then centers inside a
       left-anchored 754px box, not the wall (Ben 2026-07-03: "not centered"). */
    max-width: none;
}

/* ============================================================================
 *  Photo lightbox triggers - hero frame/inset, story portrait, review photo
 *  open the shared /gallery/ lightbox. The anchor fills its frame so the
 *  whole photo is the hit area; credits stay separate links on top.
 * ============================================================================ */

.svc-photo-open {
    display: block;
    width: 100%;
    height: 100%;
}
@media (hover: hover) {
    .svc-photo-open {
        cursor: zoom-in;
    }
}

/* ============================================================================
 *  SECTION 04 - "Recent at K Bella" prose snippet (base bg, single sentence)
 *  DOMINANT MOMENT: A single typeset sentence with rose accent number.
 * ============================================================================ */

.svc-recent {
    padding: clamp(2.5rem, 5vw, 4rem) 0;
    background: var(--color-bg);
    text-align: center;
}
.svc-recent__inner {
    max-width: 52rem;
    margin: 0 auto;
    padding: 0 clamp(1.5rem, 4vw, 4rem);
}
/* DOMINANT MOMENT: airy serif proof figures - rose micro-label over an
   upright serif numeral, anchored by a left hairline (locked stat stack,
   pillars-header/brands__figure reference). */
.svc-recent__figures {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: clamp(2rem, 6vw, 5rem);
}
.svc-recent__figure {
    text-align: left;
    border-left: 1px solid color-mix(in srgb, var(--color-heading) 18%, transparent);
    padding-left: clamp(1rem, 2vw, 1.5rem);
    max-width: 15rem;
}
.svc-recent__figure-label {
    display: block;
    font-family: var(--font-display);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--color-rose-deep);
    margin-bottom: 0.4rem;
}
.svc-recent__figure-num {
    display: block;
    font-family: var(--font-serif);
    font-size: clamp(3rem, 6vw, 4.75rem);
    font-weight: 400;
    line-height: 1;
    color: var(--color-heading);
    margin-bottom: 0.45rem;
}
.svc-recent__figure-desc {
    display: block;
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 300;
    line-height: 1.45;
    color: var(--color-muted);
}

/* ============================================================================
 *  SECTION 05 - PRICING (Menu + Consultation modes)
 *  DOMINANT MOMENT (Menu): editorial menu lines with dotted leaders
 *  DOMINANT MOMENT (Consultation): oversized "Starting at $X" display price
 * ============================================================================ */

.svc-pricing {
    --svc-pricing-pad-y: clamp(4rem, 7vw, 6rem);
    --svc-pricing-pad-x: clamp(1.5rem, 4vw, 4rem);
    position: relative;
    background: var(--color-bg-alt);
    padding: var(--svc-pricing-pad-y) 0;
    overflow: hidden;
}

.svc-pricing__inner {
    max-width: 56rem;
    margin: 0 auto;
    padding: 0 var(--svc-pricing-pad-x);
}

.svc-pricing__header {
    text-align: center;
    margin-bottom: clamp(2.5rem, 4vw, 4rem);
}

.svc-pricing__title {
    font-family: var(--font-serif);
    font-size: clamp(2.5rem, 5vw, 4rem);
    font-weight: 370;
    /* 1.06 clipped the italic descender (the "Pricing" g) inside the
       split-reveal overflow:hidden line mask - 1.16 gives it room. */
    line-height: 1.16;
    letter-spacing: -0.012em;
    color: var(--color-heading);
    margin: 0 0 1rem;
    text-wrap: balance;
}

.svc-pricing__sub {
    font-family: var(--font-body);
    font-size: clamp(1rem, 1.15vw, 1.1rem);
    line-height: 1.55;
    color: var(--color-muted);
    margin: 0 auto;
    max-width: 36rem;
    text-wrap: pretty;
}

.svc-pricing__intro {
    margin: 0 0 1.5rem;
    color: var(--color-body);
}

.svc-pricing__footnote {
    margin-top: clamp(2rem, 3vw, 2.5rem);
    font-family: var(--font-body);
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--color-muted);
    text-align: center;
    max-width: 38rem;
    margin-inline: auto;
}

/* ── Consultation mode ────────────────────────────────────────────────── */

.svc-pricing--consultation .svc-pricing__display {
    text-align: center;
    padding: clamp(2.5rem, 4vw, 4rem) 0;
    border-top: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
    position: relative;
}

.svc-pricing__from-label {
    font-family: var(--font-body);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: var(--color-eyebrow);
    margin: 0 0 1rem;
    /* global p{max-width:70ch} + margin:0 pinned this capped block LEFT, so
       its centered text sat left of page-center. Uncap so it fills + centers. */
    max-width: none;
}

/* DOMINANT MOMENT - oversized display price */
.svc-pricing__big-price {
    font-family: var(--font-display);
    font-size: clamp(4rem, 9vw, 7rem);
    font-weight: 900;
    line-height: 0.9;
    letter-spacing: -0.04em;
    color: var(--color-heading);
    margin: 0 0 1rem;
    font-variant-numeric: tabular-nums;
}
.svc-pricing__big-price-text {
    font-family: var(--font-display);
    font-size: clamp(2.25rem, 5vw, 3.5rem);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.025em;
    color: var(--color-heading);
    margin: 0 0 1rem;
}

.svc-pricing__display-helper {
    font-family: var(--font-body);
    font-size: clamp(1rem, 1.1vw, 1.1rem);
    line-height: 1.6;
    color: var(--color-body);
    margin: 0 auto 2rem;
    max-width: 34rem;
    text-wrap: pretty;
}

/* Consultation CTA carries the shared .btn--cta pill - no bespoke box.
   It does have to wrap, though: .btn is nowrap, and this button carries the
   long legacy label on /hair/wigs/ ("Book a Private Hair Replacement
   Consultation"), which is 507px on a 390px screen. It was not showing up in
   an overflow sweep because .svc-pricing sets overflow:hidden, so instead of
   extending the page it was silently CLIPPED at the section edge. */
/* Two classes on purpose. The global rule is `.btn.btn--cta` (specificity
   0,2,0), so a lone `.svc-pricing__cta` loses to it no matter which file loads
   last - the same trap that left the .svc-process__content fix dead for months.
   Matches the .svc-menu__intro .btn--cta precedent further down this file. */
.btn.svc-pricing__cta {
    white-space: normal;
    max-width: 100%;
    text-align: center;
    text-wrap: balance;
}

/* ============================================================================
 *  TWO-TIER CONSULTATION (services with more than one consultation to choose
 *  between - /hair/wigs/ carries topper and wig).
 *
 *  Deliberately NOT a pricing table. No "most popular" flag, no feature
 *  checklist, no highlighted recommended column. People arrive at this section
 *  anxious about hair loss; anything that reads as a conversion funnel costs
 *  trust that the rest of the page spent real effort earning. Two calm,
 *  equal-weight tiles that let someone recognise themselves.
 *
 *  Equal weight is the whole point. The moment one tile is visually louder it
 *  becomes the default, and the default is wrong for half the readers.
 *
 *  DOMINANT MOMENT: the paired "for" line above each price - the recognition
 *  beat that makes the number secondary - .svc-pricing__tier-for
 * ============================================================================ */

.svc-pricing__tiers {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(1rem, 2vw, 1.75rem);
    padding-top: clamp(2.5rem, 4vw, 3.5rem);
    border-top: 1px solid var(--color-border);
}
@media (min-width: 720px) {
    .svc-pricing__tiers { grid-template-columns: 1fr 1fr; }
}

.svc-pricing__tier {
    padding: clamp(1.5rem, 3vw, 2.25rem);
    background: var(--color-bg-elevated);
    border: 1px solid var(--color-border);
    border-radius: 4px;
    box-shadow: var(--shadow-md);
    transition: transform 250ms ease, box-shadow 250ms ease, border-color 250ms ease;
}
@media (hover: hover) {
    .svc-pricing__tier:hover {
        transform: translateY(-3px);
        box-shadow: var(--shadow-lg);
        border-color: var(--color-border-hover);
    }
}

.svc-pricing__tier-kicker {
    font-family: var(--font-display);
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-eyebrow);
    margin: 0 0 0.35rem;
    max-width: none;
}

/* Reads before the price on purpose. Someone with early thinning should meet
   "for thinning mainly on top" before they meet a number, so the number lands
   as information rather than as a verdict on whether they belong here. */
.svc-pricing__tier-for {
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    line-height: 1.4;
    color: var(--color-body);
    margin: 0 0 0.9rem;
    max-width: none;
    text-wrap: balance;
}

.svc-pricing__tier-price {
    font-family: var(--font-display);
    font-size: clamp(2.5rem, 5vw, 3.5rem);
    font-weight: 300;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--color-heading);
    margin: 0;
    font-variant-numeric: tabular-nums;
}

.svc-pricing__tier-duration {
    font-family: var(--font-display);
    font-style: italic;
    font-size: var(--text-base);
    color: var(--color-muted);
    margin: 0.25rem 0 1rem;
    max-width: none;
}

.svc-pricing__tier-body {
    font-family: var(--font-body);
    font-size: var(--text-base);
    line-height: 1.6;
    color: var(--color-body);
    margin: 0;
    max-width: none;
}

.svc-pricing__tiers-foot {
    text-align: center;
    padding-top: clamp(2rem, 3.5vw, 2.75rem);
}

.svc-pricing__tiers-helper {
    font-family: var(--font-body);
    font-size: clamp(1rem, 1.1vw, 1.1rem);
    line-height: 1.6;
    color: var(--color-body);
    margin: 0 auto 1.75rem;
    max-width: 38rem;
    text-wrap: pretty;
}

/* The anxiety-defuser under the button. Small, quiet, and last - it is the
   answer to "what if I book the wrong one", which is the cost of showing two
   prices at all. */
.svc-pricing__tiers-note {
    font-family: var(--font-body);
    font-size: var(--text-sm);
    line-height: 1.55;
    color: var(--color-muted);
    margin: 1.25rem auto 0;
    max-width: 34rem;
    text-wrap: pretty;
}

.svc-pricing__factors {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem;
    margin-top: clamp(2.5rem, 4vw, 3.5rem);
    max-width: 42rem;
    margin-inline: auto;
}
@media (min-width: 700px) {
    .svc-pricing__factors {
        grid-template-columns: repeat(3, 1fr);
        gap: 2rem;
    }
}
.svc-pricing__factor { text-align: center; }
.svc-pricing__factor-label {
    font-family: var(--font-body);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--color-eyebrow);
    margin: 0 0 0.5rem;
}
.svc-pricing__factor-text {
    font-family: var(--font-body);
    font-size: 0.95rem;
    line-height: 1.5;
    color: var(--color-body);
    margin: 0;
}

/* ── Premium-brand roster (consultation mode - the extension lines carried).
 * Editorial serif names, centered, flex-wrapped with a gap so a wrapped line
 * can never strand a separator (the old ::after middot dangled after the last
 * item of line 1). Sits under the pricing factors. */
.svc-pricing__brands {
    margin-top: clamp(2.5rem, 4vw, 3.5rem);
    padding-top: clamp(2rem, 3vw, 2.5rem);
    border-top: 1px solid var(--color-border);
    text-align: center;
}
.svc-pricing__brands-label {
    font-family: var(--font-body);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--color-eyebrow);
    margin: 0;
    /* same global p{max-width} trap as the from-label - uncap so it centers. */
    max-width: none;
}
.svc-pricing__brands-list {
    list-style: none;
    margin: clamp(1rem, 2vw, 1.4rem) auto 0;
    padding: 0;
    max-width: 48rem;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: baseline;
    gap: 0.4rem 1.75rem;
}
.svc-pricing__brand {
    font-family: var(--font-serif);
    font-size: clamp(1.1rem, 1.7vw, 1.4rem);
    font-weight: 400;
    color: var(--color-heading);
    white-space: nowrap;
    position: relative;
}
/* Rose dot BETWEEN names only - a flex-gap sibling can't strand it on wrap.
   Rendered in the gap to the left of every item except the first on its line
   is not achievable in pure CSS, so we omit separators and let the gap carry
   the rhythm (dangle-proof at every width). */

/* ── Menu mode: name-left / price-right rows with SOLID theme-aware
 * hairlines, two columns on desktop (the weddings a-la-carte recipe Ben
 * approved - the old dotted leaders read as low-contrast dots and the
 * dividers vanished in dark). Overrides the style.css .svc-menu base.
 */
.svc-pricing__menu-list {
    margin-top: clamp(1rem, 2vw, 1.5rem);
}
/* 2-col menus need more room than the 56rem prose column */
.svc-pricing--menu .svc-pricing__inner {
    max-width: 72rem;
}
.svc-pricing--menu .svc-menu {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 clamp(2.5rem, 5vw, 4rem);
    max-width: 44rem;
    margin: 0 auto;
}
@media (min-width: 900px) {
    /* minmax(0,...), not a bare 1fr: 1fr is minmax(auto,1fr), so each track is
       floored at its widest row's MIN-CONTENT width. A long nowrap service name
       ("Scalp Revitalization: Microneedling with Growth Factors & Exosomes")
       therefore widened its own track and shoved the second column off the
       page - /hair/trichology/ resolved to 780px + 398px inside a 1050px grid
       and clipped 209px of the right column at 1280 (Ben 2026-08-27). */
    .svc-pricing--menu .svc-menu {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: start;
        max-width: none;
    }
}
.svc-pricing--menu .svc-menu__item {
    display: block;
    padding: var(--space-sm) 0 var(--space-md);
    border-bottom: 1px solid color-mix(in srgb, var(--color-heading) 16%, transparent);
}
/* style.css pairs a -space-md margin-inline with matching padding-inline for
   the hover wash; the shorthand above zeroed that padding, leaving the hover
   background flush against (and the text out-dented past) the row edges. */
@media (hover: hover) and (min-width: 900px) {
    .svc-pricing--menu .svc-menu__item {
        padding-inline: var(--space-md);
    }
}
.svc-pricing--menu .svc-menu__name {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-md);
}
.svc-pricing--menu .svc-menu__dots {
    display: none;
}
.svc-pricing--menu .svc-menu__service {
    font-family: var(--font-display);
    font-size: clamp(1.05rem, 0.95rem + 0.45vw, 1.25rem);
    font-weight: var(--weight-bold);
    color: var(--color-heading);
    letter-spacing: -0.015em;
    /* .svc-menu__name is a flex row and style.css sets flex-shrink:0 on this
       span, so a long service name could not shrink and ran past the row -
       "Microneedling / Nanoneedling with Growth Factors" measured 406px inside
       a 312px row at 360px wide. It never showed up as page overflow because
       .svc-pricing sets overflow:hidden, so the name was CLIPPED at the section
       edge instead of extending the page.
       Shrink is only re-enabled below the 900px breakpoint where style.css
       switches the name to white-space:nowrap for the dot-leader layout - that
       desktop treatment is untouched. */
    min-width: 0;
    overflow-wrap: break-word;
    flex-shrink: 1;
}
/* Desktop keeps the shrink too. The earlier note here restored style.css's
   flex-shrink:0 on the grounds that it pairs with the white-space:nowrap set at
   this same breakpoint "for the dot-leader row" - but menu mode hides the
   leader entirely (.svc-pricing--menu .svc-menu__dots{display:none}), so that
   pair had no layout left to protect here. All it did was make long titles
   unbreakable, which is what widened the grid track above. The dot-leader
   treatment outside .svc-pricing--menu is genuinely untouched: both overrides
   below are scoped to menu mode. */
@media (min-width: 900px) {
    .svc-pricing--menu .svc-menu__name {
        min-width: 0;
    }
    .svc-pricing--menu .svc-menu__service {
        white-space: normal;
        text-wrap: pretty;
    }
}
.svc-pricing--menu .svc-menu__price {
    font-family: var(--font-display);
    font-size: clamp(1.1rem, 0.95rem + 0.5vw, 1.35rem);
    font-weight: var(--weight-extrabold);
    font-style: italic;
    letter-spacing: -0.02em;
    color: var(--color-rose-deep);
    white-space: nowrap;
}
.svc-pricing--menu .svc-menu__desc {
    margin: 0.5rem 0 0;
    max-width: 56ch !important;
    text-align: left;
    color: var(--color-body);
    font-size: var(--text-sm);
    line-height: 1.55;
}
.svc-pricing--menu .svc-menu__desc p:first-child { margin-top: 0; }
.svc-pricing--menu .svc-menu__desc p:last-child { margin-bottom: 0; }
/* Center the menusection __intro block (rendered inside the menu RM block,
   contains heading + paragraph + Meevo OBX button). The block ships with
   Bootstrap legacy classes so we override alignment + spacing here. */
.svc-pricing--menu .svc-menu__intro,
.svc-pricing--menu .svc-menu__intro.cms-content {
    text-align: center;
    max-width: 42rem;
    margin: 0 auto clamp(1.75rem, 3vw, 2.5rem);
}
/* A following menu's intro sat flush against the previous menu's last row -
   its closing border ran straight through the "Chemical Services" heading
   (Ben 2026-07-03). Clear air above every menu-to-menu transition. */
.svc-pricing--menu .svc-menu + .svc-menu__intro {
    margin-top: clamp(2.75rem, 5vw, 4rem);
}
.svc-pricing--menu .svc-menu + .svc-menu {
    margin-top: clamp(2.75rem, 5vw, 4rem);
}

/* CMS centerhead/menu-intro headings DEMOTED to a supporting lede - the
   section already opens with the serif H2; three stacked display headings
   before the first price was the audit's "heading pileup". */
.svc-pricing--menu .svc-menu__intro h2,
.svc-pricing--menu .svc-menu__intro h3,
.svc-pricing__intro h2,
.svc-pricing__intro h3 {
    font-family: var(--font-display);
    font-size: clamp(1.05rem, 1.4vw, 1.2rem);
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: 0.01em;
    color: var(--color-heading);
    margin: 0 0 0.75rem;
    text-wrap: balance;
    text-align: center;
}
.svc-pricing--menu .svc-menu__intro p {
    color: var(--color-body);
    line-height: 1.6;
    text-align: center;
}
/* Center the inline Meevo OBX CTA in the menu intro. The button now carries the
   redesign component (.btn--cta pill / .btn--outline) from style.css - RB-7. This
   used to be a brown "editorial" override (background var(--color-heading)) that
   masked the component; layout only here so the component's own colour, shape,
   type and hover win. */
.svc-pricing--menu .svc-menu__intro .btn {
    margin-top: 1.25rem;
}
.svc-pricing--menu .svc-menu__intro p:has(.btn) {
    text-align: center;
    margin-top: 0.5rem;
}

/* Long service titles make the dynamic "Schedule a [Service] Appointment" CTA
   overflow a narrow viewport (.btn--cta is white-space:nowrap globally). Let
   these in-content service CTAs wrap and never exceed their container. Scoped
   to service prose, so the global pill stays nowrap everywhere else. */
.svc-menu__intro .btn--cta,
.svc-story__content .btn--cta {
    white-space: normal;
    max-width: 100%;
}

/* Pricing entrance = GSAP scroll reveals (data-split-reveal on the title,
   data-reveal on sub/intro/list) - load-time CSS fades finished before the
   visitor ever scrolled here, which read as a dead page. */

/* ============================================================================
 *  SECTION 07 - FAQ editorial accordion (sticky title-left / accordion-right)
 *  DOMINANT MOMENT: Plus-to-minus animated icon (vertical bar rotates + scales
 *  to 0, leaving rose minus). Sliding rose underline reveals beneath the open
 *  question via scaleX(0) -> scaleX(1).
 *  Adapted from /mockup-service-detail/ Section 07 (Ben-approved 2026-05-13).
 * ============================================================================ */

/* Accordion open/close changes the FAQ column's height; browser scroll
   anchoring then shifts scrollTop to keep some node stable, which reads as
   the sticky left column "jumping" (Ben 2026-07-03). Scoping the opt-out to
   .svc-faq only pushed the anchor into the sections BELOW (staging still
   scrolled +195px on open) - it must live on the document scroller.
   service.css loads only on service pages, so this html rule is page-scoped. */
html {
    overflow-anchor: none;
}

.svc-faq {
    --svc-faq-pad-y: clamp(4rem, 7vw, 6rem);
    --svc-faq-pad-x: clamp(1.5rem, 4vw, 4rem);
    position: relative;
    background: var(--color-bg);
    padding: var(--svc-faq-pad-y) 0;
    overflow: hidden;
    isolation: isolate;
}

/* Atmosphere: rose bottom-left + accent top-right (inverted from hero) */
.svc-faq::before {
    content: '';
    position: absolute;
    inset: 0;
    /* style.css also styles .svc-faq::before as a 100px top fade strip; its
       height:100px survives this rule's inset:0 (over-constrained: top+height
       win over bottom), squeezing these radials into a hard-edged band at the
       section top (Ben's "floating gradient", 2026-07-03). Neutralize it. */
    height: auto;
    background:
        radial-gradient(
            ellipse 60% 50% at 0% 100%,
            color-mix(in srgb, var(--color-rose) 14%, transparent) 0%,
            transparent 65%
        ),
        radial-gradient(
            ellipse 55% 45% at 100% 0%,
            color-mix(in srgb, var(--color-accent-glow) 7%, transparent) 0%,
            transparent 60%
        );
    z-index: -2;
    pointer-events: none;
}
.svc-faq::after {
    content: '';
    position: absolute;
    inset: 0;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.227 0 0 0 0 0.157 0 0 0 0 0.157 0 0 0 0.5 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.6'/></svg>");
    opacity: 0.035;
    z-index: -1;
    pointer-events: none;
    mix-blend-mode: multiply;
}

.svc-faq__inner {
    max-width: 84rem;
    margin: 0 auto;
    padding: 0 var(--svc-faq-pad-x);
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(2.5rem, 5vw, 4.5rem);
}
@media (min-width: 900px) {
    .svc-faq__inner {
        grid-template-columns: minmax(0, 0.42fr) minmax(0, 0.58fr);
        gap: clamp(3rem, 6vw, 6rem);
        align-items: start;
    }
}

.svc-faq__header {
    max-width: 30rem;
}
@media (min-width: 900px) {
    .svc-faq__header {
        /* NOT sticky (overrides style.css's legacy sticky too). Frame-traced
           2026-07-03: during the accordion max-height crossfade the grid row
           transiently grows, and a sticky header rides the row's bottom edge
           down 56-80px and back on EVERY open - Ben's "left side jumps".
           Sticky also buys nothing here: the header column is taller than
           the 4-6 item list, so it never usefully pins. */
        position: static;
    }
}

/* DOMINANT MOMENT (header side): oversized serif title that anchors the column */
.svc-faq__title {
    font-family: var(--font-serif);
    font-size: clamp(2.75rem, 5.5vw, 4.5rem);
    font-weight: 350;
    line-height: 1.05;
    letter-spacing: -0.015em;
    color: var(--color-heading);
    margin: 0 0 1.5rem;
    text-wrap: balance;
}

.svc-faq__intro {
    font-family: var(--font-body);
    font-size: clamp(1rem, 1.1vw, 1.1rem);
    line-height: 1.6;
    color: var(--color-muted);
    margin: 0 0 1.5rem;
    text-wrap: pretty;
}

/* "View all FAQs" arrow link (replaces the admin-speak filter sentence). */
.svc-faq__all {
    --hit-expander: 1;
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-family: var(--font-body);
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--color-heading);
    text-decoration: none;
    border-bottom: 1px solid var(--color-border-hover);
    padding-bottom: 2px;
    transition: border-color 200ms ease;
}
.svc-faq__all::after {
    content: "";
    position: absolute;
    top: 50%; left: 0;
    transform: translateY(-50%);
    width: 100%; height: 100%;
    min-height: 44px;
}
.svc-faq__all-arrow {
    transition: transform 240ms cubic-bezier(0.16, 1, 0.3, 1);
}
@media (hover: hover) {
    .svc-faq__all:hover { border-bottom-color: var(--color-rose); }
    .svc-faq__all:hover .svc-faq__all-arrow { transform: translateX(4px); }
}

/* Kb monogram anchors the sticky column's negative space (desktop only) -
   same mask recipe as the reviews featured-mark. */
@media (min-width: 900px) {
    .svc-faq__header::after {
        content: '';
        display: block;
        width: clamp(8rem, 12vw, 11rem);
        aspect-ratio: 1;
        margin-top: clamp(2.5rem, 5vw, 4rem);
        background: var(--color-rose);
        opacity: 0.16;
        -webkit-mask: url(../images/k-bella-kb-no-ring-mono.svg) center / contain no-repeat;
        mask: url(../images/k-bella-kb-no-ring-mono.svg) center / contain no-repeat;
    }
}

/* List */
.svc-faq__list {
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid var(--color-border);
}
.svc-faq__item {
    border-bottom: 1px solid var(--color-border);
}

.svc-faq__q {
    all: unset;
    cursor: pointer;
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: start;
    gap: clamp(1rem, 2vw, 2rem);
    width: 100%;
    padding: clamp(1.4rem, 2vw, 1.8rem) 0;
    position: relative;
}
.svc-faq__q:focus-visible {
    outline: 2px solid var(--color-rose);
    outline-offset: 6px;
}

.svc-faq__q-text {
    font-family: var(--font-display);
    font-size: clamp(1.15rem, 1.4vw, 1.4rem);
    font-weight: 600;
    color: var(--color-heading);
    line-height: 1.3;
    letter-spacing: -0.01em;
    text-wrap: balance;
    position: relative;
    display: inline-block;
}
/* Sliding rose underline reveal when item is open */
.svc-faq__q-text::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -6px;
    height: 2px;
    background: var(--color-rose);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 480ms cubic-bezier(0.16, 1, 0.3, 1);
}
.svc-faq__item[data-open="true"] .svc-faq__q-text::after {
    transform: scaleX(1);
}

/* Plus-to-minus custom icon */
.svc-faq__icon {
    flex: 0 0 auto;
    width: 1.6rem;
    height: 1.6rem;
    position: relative;
    margin-top: 0.3rem;
}
.svc-faq__icon::before,
.svc-faq__icon::after {
    content: '';
    position: absolute;
    background: var(--color-heading);
    transition: transform 360ms cubic-bezier(0.16, 1, 0.3, 1),
                background-color 360ms ease;
}
.svc-faq__icon::before {
    /* horizontal rule */
    left: 0;
    right: 0;
    top: 50%;
    height: 2px;
    transform: translateY(-50%) scaleX(1);
    transform-origin: center;
}
.svc-faq__icon::after {
    /* vertical rule - rotates 90deg + scales to 0 on open */
    left: 50%;
    top: 0;
    bottom: 0;
    width: 2px;
    transform: translateX(-50%) rotate(0deg);
    transform-origin: center;
}
.svc-faq__item[data-open="true"] .svc-faq__icon::after {
    transform: translateX(-50%) rotate(90deg) scaleY(0);
    background: var(--color-rose);
}
.svc-faq__item[data-open="true"] .svc-faq__icon::before {
    background: var(--color-rose);
}

/* Answer panel - smooth open via max-height transition. (grid-template-rows
   0fr → 1fr trick computed to 0px in this layout context; falling back to
   max-height with a generous ceiling that still animates cleanly.) */
.svc-faq__a {
    max-height: 0;
    overflow: hidden;
    transition: max-height 480ms cubic-bezier(0.16, 1, 0.3, 1);
}
.svc-faq__item[data-open="true"] .svc-faq__a {
    max-height: 32rem;
}
.svc-faq__a-inner {
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity 320ms ease 80ms, transform 320ms ease 80ms;
}
.svc-faq__item[data-open="true"] .svc-faq__a-inner {
    opacity: 1;
    transform: translateY(0);
}
.svc-faq__a-body {
    padding: 0 0 clamp(1.5rem, 2.5vw, 2rem);
    font-family: var(--font-body);
    font-size: var(--text-base);
    line-height: 1.65;
    color: var(--color-body);
    max-width: 42rem;
}
.svc-faq__a-body p { margin: 0 0 0.85rem; }
.svc-faq__a-body p:last-child { margin: 0; }
.svc-faq__a-body strong { color: var(--color-heading); font-weight: 600; }

/* Hover gating */
@media (hover: hover) {
    .svc-faq__item:not([data-open="true"]) .svc-faq__q:hover .svc-faq__q-text {
        color: var(--color-heading);
    }
    .svc-faq__item:not([data-open="true"]) .svc-faq__q:hover .svc-faq__q-text::after {
        transform: scaleX(0.25);
        background: color-mix(in srgb, var(--color-rose) 60%, transparent);
    }
    .svc-faq__item:not([data-open="true"]) .svc-faq__q:hover .svc-faq__icon::before,
    .svc-faq__item:not([data-open="true"]) .svc-faq__q:hover .svc-faq__icon::after {
        background: var(--color-rose);
    }
}

/* FAQ entrance = GSAP scroll reveals (data attributes in the template). */


/* ============================================================================
 *  SECTION 09 - Featured review + photo (Tier 3-C, Treatment 1: side-by-side)
 *  DOMINANT MOMENT: a single editorial review pulled from the service-filtered
 *  Reviews collection, paired with a recent photo (preferring same stylist).
 *  3:4 portrait at native ratio; quote at Schibsted 500 mid-weight.
 * ============================================================================ */

/* Base bg (not cream) - the closing run alternates team(base) -> review(base
   w/ rose depth) -> form(cream); review sat cream-on-cream next to the form. */
.svc-review {
    --svc-review-pad-y: clamp(4rem, 7vw, 6rem);
    --svc-review-pad-x: clamp(1.5rem, 4vw, 4rem);
    position: relative;
    background: var(--color-bg);
    padding: var(--svc-review-pad-y) 0;
    overflow: hidden;
    isolation: isolate;
}
.svc-review::before {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(
        ellipse 60% 55% at 85% 15%,
        color-mix(in srgb, var(--color-rose) 12%, transparent) 0%,
        transparent 65%);
    z-index: -1;
    pointer-events: none;
}

.svc-review__inner {
    /* 76rem (was 84) + media justified toward the text: the viewport-capped
       photo left a dead band mid-section (Ben 2026-07-03: "too far apart").
       Photo and quote now read as one centered pair. */
    max-width: 76rem;
    margin: 0 auto;
    padding: 0 var(--svc-review-pad-x);
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(2rem, 4vw, 3.5rem);
    align-items: center;
}
@media (min-width: 768px) {
    /* DOMINANT MOMENT: the photo and quote as one centred pair - .svc-review__inner
       (restored in the tablet band, not changed)

       TABLET BAND, 768-899. Before this rule the section fell to the single `1fr`
       track above, and because both children carry their own max-width (media
       min(28rem,45svh), body 36rem) a capped item in a stretch track aligns to the
       track START - so the pair jammed left and the slack piled up on the right:
       gapL 35 / gapR 269 at 880, a 234px skew, measured on deployed staging.
       Content stayed 576px wide however much room it was given, so a wider tablet
       only made the void bigger. 18-19 service pages. Ben picked this fix from
       rendered frames 2026-08-12 (Option A of three).

       Two columns rather than centring the single one: side-by-side stops the photo
       and the quote stacking, which takes the section from 1016px to 595px at 880 -
       a whole extra section visible on a tablet. Centring alone fixed the skew but
       left a 576px column floating in 880 with 152px of dead air each side.

       The photo track is capped at 20rem here rather than left `auto` as it is at
       >=900. `auto` resolves to the media's own 448px cap, which plus the 40px gap
       leaves the quote only ~219px at 768 - a cramped measure. The media is
       `width: 100%` with `aspect-ratio: 3/4`, so it fills whatever track it is given
       and stays ratio-locked with no height anywhere; that is the safe form of a
       ratio-locked box (a cap WITHOUT `width: 100%` computes to 0x0 - see the
       2026-08-11 band sweep regression).

       `justify-content: center` keeps Ben's 2026-07-03 requirement intact: the pair
       reads as one centred unit and cannot drift apart. The >=900 block below is
       deliberately UNCHANGED, so desktop cannot move as a side effect of this. */
    .svc-review--side .svc-review__inner {
        grid-template-columns: minmax(0, 20rem) minmax(0, 36rem);
        justify-content: center;
        gap: clamp(2rem, 3vw, 4rem);
    }
}
@media (min-width: 900px) {
    /* Content-sized columns + centered pair: fr tracks left a dead band
       between the viewport-capped photo and the quote (Ben 2026-07-03,
       twice). auto = exactly the photo's width; the pair can't drift apart. */
    .svc-review--side .svc-review__inner {
        grid-template-columns: auto minmax(0, 36rem);
        justify-content: center;
        gap: clamp(2.5rem, 4vw, 4rem);
    }
}

/* No photo matches this service, so the testimonial carries the section alone.
   DOMINANT MOMENT: the quote centred on its own measure - .svc-review__quote

   Without this the body kept its left column position and left the photo's
   half of the section empty - the same held-open-track void the hero had. Six
   service pages render photoless today (facials, lashes, makeup, spray-tanning,
   waxing, trichology), and dropping the off-category stylist fallback in
   service.php means a page stays here rather than borrowing a wrong photo.

   Centred rather than merely collapsed: a testimonial is a pull-quote, and
   symmetric whitespace reads as intentional where a left-hugging block reads
   as a missing image. Resolves itself per page as soon as the category has a
   photo - nothing here to undo. */
.svc-review--no-media .svc-review__inner {
    /* Collapse to ONE track. Without this the body lands in the `auto` column
       (grid auto-placement fills track 1) and the empty minmax(0, 36rem) track
       still sits to its right - the void just moves instead of closing.
       Declared after the .svc-review--side rule: equal specificity, so source
       order is what carries it, and it must apply at every width. */
    grid-template-columns: minmax(0, 44rem);
    justify-content: center;
    justify-items: center;
    text-align: center;
}

.svc-review--no-media .svc-review__body {
    /* Body cap is 36rem; widen slightly so a centred quote does not run narrow
       and ragged in the middle of a full-width band. */
    max-width: 44rem;
    margin-inline: auto;
}

.svc-review--no-media .svc-review__stars,
.svc-review--no-media .svc-review__attr {
    justify-content: center;
}

.svc-review__media {
    position: relative; /* photoCredit overlay anchor */
    aspect-ratio: 3 / 4;
    background: var(--color-border);
    overflow: hidden;
    /* Ratio stays 3:4 (pillar photos never crop), so height is capped via
       width: 45svh wide = 60svh tall, keeping photo + section padding inside
       one viewport (Ben 2026-07-03: section was taller than the screen). */
    max-width: min(28rem, 45svh);
    width: 100%;
    margin: 0;
    border-radius: 6px;
    box-shadow:
        20px 20px 0 -8px color-mix(in srgb, var(--color-rose) 22%, var(--color-bg-alt)),
        0 1px 0 rgba(58, 40, 40, 0.04),
        0 24px 48px -24px rgba(58, 40, 40, 0.28);
}
.svc-review__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
}
@media (hover: hover) {
    .svc-review__media:hover .svc-review__img {
        transform: scale(1.03);
    }
}

.svc-review__body { max-width: 36rem; }

.svc-review__stars {
    display: flex;
    gap: 0.15rem;
    color: var(--color-rose-deep);
    margin: 0 0 1.25rem;
}

/* DOMINANT MOMENT: the quote itself, at display scale (grotesk mid-weight -
   long testimonials read terribly in the display serif, Ben's reviews rule). */
.svc-review__quote {
    font-family: var(--font-display);
    font-size: clamp(1.6rem, 2.8vw, 2.5rem);
    font-weight: 500;
    line-height: 1.28;
    letter-spacing: -0.02em;
    color: var(--color-heading);
    margin: 0 0 1.75rem;
    text-wrap: pretty;
    position: relative;
}

/* Attribution rail (homepage featured-card language: initial avatar, bold
   name, service tag, frosted Verified-Google chip). */
.svc-review__attr {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1rem;
    margin-bottom: 1.5rem;
}
.svc-review__initial {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 50%;
    background: color-mix(in srgb, var(--color-rose) 22%, var(--color-bg-alt));
    color: var(--color-rose-deep);
    font-family: var(--font-serif);
    font-size: 1.25rem;
    font-weight: 460;
    flex-shrink: 0;
}
.svc-review__attr-meta {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.svc-review__author {
    font-family: var(--font-display);
    font-size: 0.95rem;
    font-weight: 700;
    font-style: normal;
    color: var(--color-heading);
    letter-spacing: -0.005em;
}
.svc-review__service {
    font-family: var(--font-body);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--color-eyebrow);
}
.svc-review__verified {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.32rem 0.72rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    background: color-mix(in srgb, var(--color-bg-alt) 70%, transparent);
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    letter-spacing: 0.02em;
    color: var(--color-body);
}
.svc-review__verified-g {
    color: var(--color-muted);
    flex-shrink: 0;
}

.svc-review__more {
    font-family: var(--font-body);
    font-size: 0.85rem;
    margin: 0;
}
.svc-review__more a {
    --hit-expander: 1;
    position: relative;
    color: var(--color-heading);
    text-decoration: none;
    border-bottom: 1px solid var(--color-rose);
    padding-bottom: 1px;
    transition: opacity 200ms ease;
}
/* Vertical hit-expander: "Read more reviews" tap height to 44; link unchanged. */
.svc-review__more a::after {
    content: "";
    position: absolute;
    top: 50%; left: 0;
    transform: translateY(-50%);
    width: 100%; height: 100%;
    min-height: 44px;
}
@media (hover: hover) {
    .svc-review__more a:hover { opacity: 0.7; }
}

/* Review entrance = GSAP scroll reveals (data attributes in the template). */

/* ============================================================================
 *  SECTION 06 polish - "What to Expect" placeholder note
 *  Renders only when service_process is empty so authors see what's needed
 *  without breaking the section flow.
 * ============================================================================ */

.svc-process__placeholder {
    background: color-mix(in srgb, var(--color-rose) 5%, var(--color-bg));
    border-left: 3px solid var(--color-rose);
    padding: 1.25rem 1.5rem;
    border-radius: 4px;
    font-family: var(--font-body);
    font-size: 0.95rem;
    line-height: 1.55;
    color: var(--color-body);
    max-width: 44rem;
}
.svc-process__placeholder strong {
    color: var(--color-heading);
    font-weight: 700;
}

/* ============================================================================
 *  SERIF VOICE - level rule from the elevation kit (H1/H2 = Fraunces + rose
 *  italic em accent; grotesk holds H3-down). Overrides here win over the
 *  style.css base blocks because service.css loads after it.
 * ============================================================================ */

/* The "Your {Service} Experience" dead-space fix used to live here as
   `.svc-process__content { max-width: 46rem; margin-inline: auto }`. It never
   took effect at 768px and up: one class loses to `.svc-process .cms-content`
   (two classes) in style.css, and media queries add no specificity. The
   diagnosis was right, the selector just could not win, so the section kept
   its ~270px of bare right edge for months.
   Now fixed at the source in style.css:
     - `.svc-process .cms-content ol { max-width: none }` uncaps the timeline
     - `.svc-process .cms-content:not(:has(ol))` caps the prose variant
   Nothing is needed here. Do not re-add a single-class override; it will look
   like it works in the file and do nothing in the browser. */

.svc-process__heading,
.svc-team__heading,
.svc-form__heading {
    font-family: var(--font-serif);
    font-weight: 370;
    line-height: 1.06;
    letter-spacing: -0.012em;
}

.svc-gallery__heading em,
.svc-pricing__title em,
.svc-faq__title em,
.svc-process__heading em,
.svc-team__heading em,
.svc-form__heading em {
    font-style: italic;
    font-weight: 460;
    color: var(--color-rose-deep);
}

/* ============================================================================
 *  STORY - editorial split (CMS body; classes are stable, content varies per
 *  service). Credited 3:4 portrait LEFT (style.css owns .svc-story__frame),
 *  left-aligned prose right with serif CMS H2s, enlarged lede, and CMS bullet
 *  lists as the weddings signature checklist. Centered variant + drop cap
 *  retired (Ben 2026-07-03: read as a blob, not editorial).
 *  DOMINANT MOMENT: sticky credited portrait against a 60ch prose measure -
 *  .svc-story__frame
 * ============================================================================ */

/* Mirror style.css's 60/40: media is DOM-first here, so narrow column left. */
@media (min-width: 900px) {
    .svc-story__inner {
        grid-template-columns: 0.42fr 0.58fr;
    }
}

/* No spare portrait: a single left-aligned measure at the container edge
   (the weddings "How bookings work" language). */
.svc-story--no-media .svc-story__inner {
    grid-template-columns: 1fr;
}
.svc-story--no-media .svc-story__content {
    max-width: 60ch;
}

.svc-story__frame {
    margin: 0;
}

.svc-story__content h2 {
    font-family: var(--font-serif);
    font-weight: 370;
    line-height: 1.06;
    letter-spacing: -0.012em;
}

.svc-story__content > p:first-of-type {
    font-size: clamp(1.1rem, 1.4vw, 1.3rem);
    line-height: 1.6;
}

/* CMS <ul> -> rose checklist (weddings signature-list recipe): two even
   columns at md+, each item its own cell, icon color is the section's one
   persistent accent. */
.svc-story__content ul.svc-story__checklist {
    list-style: none;
    padding: 0;
    margin-block: var(--space-lg);
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.55rem 1.5rem;
}
@media (min-width: 700px) {
    .svc-story__content ul.svc-story__checklist {
        grid-template-columns: 1fr 1fr;
    }
}
.svc-story__content .svc-story__checklist li {
    display: flex;
    align-items: flex-start;
    gap: 0.55em;
    margin: 0;
    padding: 0;
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    line-height: 1.45;
    color: var(--color-body);
}
/* The check-circle IS the marker - suppress the global cms-content rose
   diamond that would double it. */
.svc-story__content .svc-story__checklist li::before {
    content: none;
}
.svc-story__content .svc-story__checklist .ph-icon {
    color: var(--color-rose);
    flex-shrink: 0;
    margin-top: 0.15em;
}

/* ============================================================================
 *  CLOSING FORM - the weddings inquiry recipe: editorial aside left (eyebrow,
 *  serif title, reassurance, proof stats, phone), conversion surface right.
 *  Replaces the centered stack (Ben 2026-07-03: "way too much wasted space").
 *  DOMINANT MOMENT: oversized serif "Let's plan your visit." against the
 *  conversion panel - .svc-form__heading
 * ============================================================================ */

.svc-form__shell {
    display: grid;
    /* minmax(0, 1fr), not 1fr. A bare `1fr` is minmax(AUTO, 1fr), and that auto
       minimum sizes the TRACK to its content - so the FormBuilder fields inside
       held the single column at 350px against a 328px container and pushed
       every service page 6px into horizontal scroll at 360px wide.
       min-width:0 on the item alone could not fix this: the track was the thing
       refusing to shrink. The 900px+ rule below already uses minmax(0, ...). */
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(2.5rem, 5vw, 4.5rem);
    align-items: center;
}
/* BATCH 3 EXCEPTION - this gate STAYS at 900. Tried at 768 and reverted 2026-08-20,
   with the frame that proves it.
   At 768 the tracks resolve 354/327, and 327px is below this panel's min-content floor:
   the frame showed the phone and email inputs clipped mid-placeholder, the Turnstile
   widget (a fixed ~300px third-party iframe) cut off at the panel edge, and the nowrap
   "REQUEST MY CONSULTATION" button running past it. The base rule above already documents
   this exact floor - "a grid ITEM still defaults to min-width:auto, so it refuses to
   shrink below its min-content and simply overflows the track it was given" - which is
   what the 900 gate has been protecting all along. It is a considered floor, not a default.
   hero-parity PASSED the move (desktop unmoved, band moved). A track comparison cannot
   see a clipped input; only the frame could.
   The defect the sweep filed here is REAL but is an ALIGNMENT problem, not a gate problem:
   .svc-form__aside is capped 34rem with no margin-inline while .svc-form__body is capped
   40rem WITH margin-inline:auto, so the two children disagree about their left edge by
   94px. That is Batch 4's ".svc-form__body vs __aside" item and must be fixed by making
   the two caps agree - NOT by giving the form its own track. */
@media (min-width: 900px) {
    .svc-form__shell {
        grid-template-columns: minmax(0, 0.52fr) minmax(0, 0.48fr);
    }
}

/* Batch 4 ".svc-form__body vs __aside" - the two children disagreed about their
   LEFT EDGE. The aside is capped 34rem with no margin-inline, and grid stretch plus
   a max-width leaves it flush left. style.css caps the form card 40rem WITH
   margin-inline:auto, which CENTRES it. Stacked - every width below the 900 gate -
   that put the card's left edge 94px inside the aside's at 880, so the heading and
   the card it belongs to started in different places.

   MECHANISM. The sweep filed this as "make the two caps agree". Equalising them at
   34rem does align the edges, but the 880 frame showed the cost: the card then wraps
   "FIRST TIME OR RETURNING?" and the textarea placeholder onto two lines and grows
   the section 18px. The defect is the LEFT EDGE, not the width, and two flush-left
   columns of different widths are ordinary editorial layout. So the card keeps its
   roomier 40rem and ONLY its inline alignment changes, released back to auto at 900
   where each child owns its own track and a shared edge is no longer what aligns
   them. Same fix, no form legibility cost, section height unchanged at 1179.

   Scoped `.svc-form__shell >` on purpose: `.svc-form__body` is shared with careers,
   resource-form and basic-page form cards, which are NOT in this two-child layout
   and must keep the centred 40rem card. Only margin-inline is set here, never
   max-width, so this cannot fight `.svc-form__body:has(.svc-form__fallback) {
   max-width: none }` further down the file - and on that fallback panel
   margin-inline is inert anyway, because a box with no max-width has no slack to
   distribute.

   WARNING, learned by shipping it broken on 2026-08-21: this block is ONE comment.
   An earlier revision closed it early with a stray comment-close delimiter after the
   scoping paragraph (never write that two-character sequence inside a comment - doing
   so while describing this very bug reproduced it once already) and then continued in
   bare text, which put `.svc-form__aside` inside an invalid selector prelude and
   silently DELETED its `max-width: 34rem` from the built CSS.
   It parsed, it rendered, and hero-parity could not see it because `.svc-form__aside`
   matches none of that harness's selectors. If you extend this comment, do not
   re-close it. */
.svc-form__aside {
    max-width: 34rem;
}
.svc-form__shell > .svc-form__body {
    margin-inline: 0;
}
/* Two columns again: each child owns its own track, so a shared cap is no longer
   what aligns them. Restored to the exact pre-Batch-4 values so >=900 cannot move. */
@media (min-width: 900px) {
    .svc-form__shell > .svc-form__body {
        margin-inline: auto;
    }
}
.svc-form__eyebrow {
    margin-bottom: var(--space-md);
}
/* Left-align the shared heading (style.css centers the old header layout)
   and let it lead the aside at display scale. */
.svc-form__heading {
    text-align: left;
    margin: 0 0 var(--space-lg);
    font-size: clamp(2.5rem, 5vw, 4rem);
    text-wrap: balance;
}
.svc-form__reassurance {
    font-family: var(--font-body);
    font-size: var(--text-base);
    font-weight: var(--weight-light);
    line-height: 1.7;
    color: var(--color-body);
    margin: 0 0 var(--space-xl);
    max-width: 44ch;
}

/* Proof stats: serif numerals over muted labels (weddings form-stats). */
.svc-form__stats {
    list-style: none;
    display: flex;
    /* Two 12rem items plus the gap need ~408px of min-content, but a 360px
       viewport only offers ~328px inside the container - so this row pushed
       every service page 6px into horizontal scroll on small Androids. It
       stayed invisible at 390px and up, which is why it survived earlier
       sweeps. Wrapping is the honest answer: the second stat drops to its own
       line only on the narrowest screens and the row is unchanged everywhere
       else. */
    flex-wrap: wrap;
    gap: clamp(1.5rem, 3vw, 2.5rem);
    padding: 0;
    margin: 0 0 var(--space-xl);
}
.svc-form__stats li {
    border-left: 1px solid color-mix(in srgb, var(--color-heading) 18%, transparent);
    padding-left: clamp(0.9rem, 1.5vw, 1.25rem);
    max-width: 12rem;
}
.svc-form__stat-num {
    display: block;
    font-family: var(--font-serif);
    font-size: clamp(1.9rem, 3vw, 2.6rem);
    font-weight: 400;
    line-height: 1.1;
    color: var(--color-heading);
}
.svc-form__stat-label {
    display: block;
    margin-top: 0.3rem;
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 300;
    line-height: 1.45;
    color: var(--color-muted);
}

.svc-form__phone {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    text-decoration: none;
    color: var(--color-heading);
}
.svc-form__phone .ph-icon {
    color: var(--color-rose-deep);
    flex-shrink: 0;
}
.svc-form__phone-kicker {
    display: block;
    font-size: var(--text-xs);
    font-weight: 300;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-muted);
}
.svc-form__phone-number {
    display: block;
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    letter-spacing: -0.01em;
}
@media (hover: hover) {
    .svc-form__phone {
        transition: transform 220ms ease;
    }
    .svc-form__phone:hover {
        transform: translateY(-2px);
    }
}

/* ── Fallback panel (also the intake gateway panel on /hair/wigs/) ── */
/* Both columns, every service page. A grid ITEM defaults to min-width:auto and
   so refuses to shrink below its min-content, overflowing its track instead.
   Here the split-reveal line masks in the aside heading set a 350px floor
   against a 328px track at 360px wide, pushing every service page 6px into
   horizontal scroll. Scoping this to the fallback body only (as it first was)
   fixed /hair/wigs/ and left the other nine still overflowing. */
.svc-form__shell > * {
    min-width: 0;
}

.svc-form__body:has(.svc-form__fallback) {
    max-width: none;
    /* min-width:0 is the fix for a real horizontal-scroll bug between 900px and
       1024px. .svc-form__shell sizes its TRACKS with minmax(0, .52fr/.48fr),
       but a grid ITEM still defaults to min-width:auto, so it refuses to shrink
       below its min-content and simply overflows the track it was given (385px
       track, 471px item at 900px). The min-content floor was the nowrap CTA
       (309px) plus this panel's padding.
       This panel used to be a never-rendered fallback for a missing FormBuilder
       form, so the bug sat dormant until /hair/wigs/ made it the primary path. */
    min-width: 0;
}
.svc-form__fallback {
    text-align: left;
}
/* Belt to the min-width braces: let the CTA wrap so it can never re-establish a
   min-content floor wider than the column, whatever label it carries. */
.svc-form__fallback .btn {
    white-space: normal;
    text-align: center;
    text-wrap: balance;
}
.svc-form__fallback-eyebrow {
    margin-bottom: var(--space-md);
}
.svc-form__fallback-lead {
    font-family: var(--font-body);
    font-size: var(--text-lg);
    font-weight: 300;
    line-height: 1.6;
    color: var(--color-body);
    max-width: 34ch;
    margin: 0 0 var(--space-lg);
}
.svc-form__fallback-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
    margin: 0 0 var(--space-lg);
}
.svc-form__fallback-note {
    font-size: var(--text-xs);
    font-weight: 300;
    color: var(--color-muted);
    margin: 0;
}

/* ============================================================================
 *  DARK THEME - section atmosphere glows at light-theme strengths render as
 *  bright smears on the near-black bg (Ben 2026-07-03: "bright highlight for
 *  no reason"). Halve them in dark; geometry unchanged.
 * ============================================================================ */

[data-theme="dark"] .svc-faq::before {
    background:
        radial-gradient(
            ellipse 60% 50% at 0% 100%,
            color-mix(in srgb, var(--color-rose) 7%, transparent) 0%,
            transparent 60%
        ),
        radial-gradient(
            ellipse 55% 45% at 100% 0%,
            color-mix(in srgb, var(--color-accent-glow) 3%, transparent) 0%,
            transparent 55%
        );
}
[data-theme="dark"] .svc-review::before {
    background: radial-gradient(
        ellipse 60% 55% at 85% 15%,
        color-mix(in srgb, var(--color-rose) 6%, transparent) 0%,
        transparent 60%);
}
