/*
 * Ultimate -- design pack for the oneclick theme.
 *
 * Loaded dead last in the cascade (functions.php oneclick_assets()), only
 * when oneclick_site('design_template') is 'ultimate'.
 *
 * HISTORY: PR #241 gave this pack its own full visual identity (directional
 * hero scrim, Instrument Serif + Inter type system, its own card language,
 * pill-chip kickers, alternating section bands, a footer accent). The owner
 * reversed that direction the same day (2026-09-01, "restore Home Services
 * look"): this file was reduced to just the Font Pairing mechanism below,
 * and Ultimate fell through to the shared theme CSS -- byte-identical to
 * Lightning. PR #241's full identity is preserved in git history and as an
 * unregistered reference copy at wp-theme/oneclick/templates/ultimate_archive/
 * (see that directory's own README.md).
 *
 * LATER THE SAME DAY, the owner reviewed a hand-built spec (a "Mock 1" home
 * page composition plus a component menu listing every candidate option per
 * part, current-vs-fresh) and picked a specific, named component for each
 * of eleven parts of the individual-site home page:
 *   N1  glass nav bar, condenses on scroll
 *   F1  floating-label request-a-quote form (templates/ultimate/parts/
 *       hero-form.php)
 *   B1  primary button -- pill, arrow, hover glow
 *   B2  secondary button -- outline that fills in on hover
 *   H1  hero stat card -- count-up years-in-business / rating, HONESTY
 *       GATE: renders only stats the brief can prove, absent entirely with
 *       neither
 *   R3  rating pill with stars (restyles the existing #236 honest-badge
 *       markup in place; never invents a count)
 *   S1  photo-top service cards, hover lift + underline sweep
 *   P1  circle-check about bullets
 *   P2  numbered how-we-work steps with a hairline connector
 *   Q1  smooth FAQ accordion, keyboard accessible
 *   T1  dark footer with a soft accent glow
 * This is a DIFFERENT pass from PR #241: it does not touch H1/H2/H3 type
 * scale, does not add chip-kicker eyebrows, does not retint the alternating
 * section bands, and reuses the theme's existing markup/classes wherever
 * one already exists (the FAQ trigger/answer/aria-expanded structure, the
 * about-bullet check-disc pseudo-elements, the commitments numbered-step
 * connector) rather than inventing parallel markup. Every value below is
 * translated into this pack's own idioms: --ocf-primary (never a hardcoded
 * hue -- always the brief's own brand color, bridged from --color-accent in
 * header.php), the existing --card-radius / --radius-* / --duration / --ease
 * tokens, and color-mix() in place of an rgba(accent-rgb, alpha) triple
 * (this codebase has no --accent-rgb variable; color-mix reaches the same
 * soft tints and glows without needing one). Manrope/Source Sans 3 (or a
 * brief's own Font Pairing preset, see the block directly below) are
 * unchanged -- no wording or copy changed anywhere, styling only. All
 * motion respects prefers-reduced-motion (see the block at the very end of
 * this file).
 *
 * The ONE thing kept from PR #241/#234's own pass: the Font Pairing preset
 * mechanism -- a brief can still choose a different heading/body pairing for
 * the ultimate template specifically (platform/public/create.html step 6,
 * tools/provision_brief.py resolves it into brand.font_heading/
 * brand.font_body -> a per-site tokens.css's --font-heading/--font-body,
 * loaded before this file). --ocf-font-heading/--ocf-font-body below read
 * that value first, falling back to Manrope/Source Sans 3 -- this pack's
 * own default, matching templates/lightning's hardcoded default in
 * header.php -- only when tokens.css hasn't set one at all (a render
 * outside the provisioning pipeline, e.g. a hand-built fixture).
 */

:root {
    --ocf-font-heading: var(--font-heading, 'Manrope', sans-serif);
    --ocf-font-body: var(--font-body, 'Source Sans 3', sans-serif);

    /* T1 footer tokens -- header.php's --ocf-footer-* bridge falls back to
       the tenant's light surface tokens by default (assets/tokens.css); this
       pack overrides all three to the fixed dark #141414 family, same fixed
       neutral the hero/CTA dark sections already use (--ocf-dark-bg family
       in header.php's own bridge), never the tenant's brand-derived light
       tokens. */
    --ocf-footer-bg: #141414;
    --ocf-footer-heading: #ffffff;
    --ocf-footer-body: color-mix(in srgb, #ffffff 66%, transparent);
}

/* ============================================================
   N1 -- glass nav bar, condenses on scroll
   (assets/components/header.css .nav-bar; JS: templates/ultimate/assets/
   ultimate.js toggles .is-condensed on scroll. No-JS fallback: the blur +
   translucent bar below renders on its own either way -- only the
   compacting on scroll needs the script.)

   SURFACE 2026-09-12 (skin/form-nav-cool, Hannah: "I want the contact
   form to match the nav bar ... the card and the nav must read as the
   same material"): border + shadow were set to the SAME recipe
   .hero-form-card (contact-form.css) used at the time -- var(--ocf-
   border-light) for the border (was a heading-tinted color-mix, a
   different token family than the card's own border) and the identical
   box-shadow formula.

   UNCHANGED by the later same-day "hero form card = same as our other
   cards" ruling: that ruling moved .hero-form-card onto the shared
   --card-radius/--card-shadow tokens every other card uses (see
   contact-form.css's own comment), which are a much smaller/tighter
   shadow than this nav bar's -- but per that brief's explicit
   instruction to keep the nav changes from this earlier commit as-is,
   the values below stay literal/fixed rather than switching to
   var(--card-shadow) too. The N1 blur/saturate intensity and background
   color-mix percentages are the 9/1 owner-approved component pick
   (test_ultimate_identity.py's N1-nav-glass-blur) and are intentionally
   left as-is -- Hannah asked for the same border/shadow language, not a
   different glass intensity.
   ============================================================ */
.nav-bar {
    background: color-mix(in srgb, var(--ocf-bg) 68%, transparent);
    -webkit-backdrop-filter: blur(10px) saturate(160%);
    backdrop-filter: blur(10px) saturate(160%);
    border-bottom-color: var(--ocf-border-light);
    box-shadow: 0 1.25rem 3rem color-mix(in srgb, var(--ocf-heading) 14%, transparent);
    transition: background var(--duration) var(--ease), box-shadow var(--duration) var(--ease);
}
.nav-bar.is-condensed {
    background: color-mix(in srgb, var(--ocf-bg) 95%, transparent);
    box-shadow: 0 1.25rem 3rem color-mix(in srgb, var(--ocf-heading) 14%, transparent);
}
.nav-inner {
    transition: min-height var(--duration) var(--ease);
}
.nav-bar.is-condensed .nav-inner {
    min-height: 3.75rem;
}
.nav-cta {
    border-radius: var(--radius-full);
}

/* ============================================================
   B1 -- primary buttons: pill, hover glow, arrow travel
   (base.css .btn-primary; ocf-global.css .nav-cta already pilled above;
   .mobile-cta; this pack's own .ultimate-b1-btn on the F1 form's submit)
   ============================================================ */
.btn-primary,
.ultimate-b1-btn,
.hero-form-card .form-submit-btn,
.mobile-cta {
    border-radius: var(--radius-full) !important;
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--ocf-primary) 50%, transparent);
    transition: box-shadow var(--duration) var(--ease), transform var(--duration) var(--ease), background var(--duration) var(--ease);
}
.btn-primary:hover,
.btn-primary:focus-visible,
.ultimate-b1-btn:hover,
.ultimate-b1-btn:focus-visible,
.hero-form-card .form-submit-btn:hover,
.hero-form-card .form-submit-btn:focus-visible {
    box-shadow: 0 0 0 8px color-mix(in srgb, var(--ocf-primary) 16%, transparent), 0 10px 22px -8px color-mix(in srgb, var(--ocf-primary) 55%, transparent);
    transform: translateY(-2px);
}
.btn-primary svg,
.ultimate-b1-arrow {
    transition: transform var(--duration) var(--ease);
}
.btn-primary:hover svg,
.btn-primary:focus-visible svg,
.ultimate-b1-btn:hover .ultimate-b1-arrow,
.ultimate-b1-btn:focus-visible .ultimate-b1-arrow {
    transform: translateX(3px);
}

/* ============================================================
   B2 -- secondary/outline buttons: color sweeps in from the left on hover
   (base.css .btn-outline -- hero secondary CTA)
   ============================================================ */
.btn-outline {
    position: relative;
    z-index: 0;
    overflow: hidden;
    isolation: isolate;
    /* skin/radius-scale (2026-09-12): own token, not folded into
       --radius-button -- this near-square corner is a deliberately
       preserved measured V1-parity value, not a stray raw number. */
    border-radius: var(--radius-outline);
    transition: color var(--duration) var(--ease);
}
.btn-outline::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--ocf-primary);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 280ms var(--ease);
}
.btn-outline:hover,
.btn-outline:focus-visible {
    color: #fff;
    border-color: var(--ocf-primary);
}
.btn-outline:hover::before,
.btn-outline:focus-visible::before {
    transform: scaleX(1);
}

/* ============================================================
   Final CTA band -- Hannah's 2026-09-03 correction, ROUND 2 (live review
   of the round-1 fix in PR #303 rejected the flat brand-green band as
   "leprechaun green"). Round 1's problem (band = footer's own fixed
   #141414, the two blurred into one dark block) is still fixed here,
   just with a different resolution: instead of a flat brand-color band,
   this is now a light/white section of its own -- a soft brand-tinted
   radial glow anchored top-right on a white ground, with a thin neutral
   top seam -- reading as its own modern section sitting ABOVE the dark
   footer rather than matching or fighting it.
   Fix, scoped to this file only (loaded solely for design_template ===
   'ultimate', so it never reaches the frozen packs' shared cta.css
   rule):
   - .ocf-cta__shade (always-rendered per cta.css, normally a dark
     photo-dimming scrim) is neutralized to transparent, and the CTA
     image slot is hidden outright -- this band is a clean color
     surface, never a dark-over-photo treatment, regardless of whether
     a site happens to have set a CTA image.
   - .ocf-cta's own background carries the white-ground radial glow.
   - --cta-headline-color/--cta-body-color (the custom props
     .ocf-cta__headline/__body actually read, cta.css's own field-color
     fallback pattern) are repointed from the dark-tone alt tokens
     (--ocf-heading-alt/--ocf-body-alt, white-family -- correct on a
     dark band, wrong on this white one) to the normal light-surface
     tokens (--ocf-heading/--ocf-body) header.php's own bridge already
     defines for the page's default (non-dark) sections.
   - The eyebrow and primary button need NO override at all: cta.css's
     own dark-band eyebrow rule already defaults to var(--ocf-primary),
     and base.css/ocf-global.css's own .btn-primary is already the
     solid-primary-background/white-text pill (B1) -- both rules from
     round 1 existed only to fight the flat-green band, which no longer
     exists.
   - The phone link keeps round 1's no-box plain-link shape but swaps
     white text for the normal dark-surface text tokens.
   ============================================================ */
.ocf-cta > .ocf-cta__shade,
.ocf-cta .ocf-cta__shade {
    background: transparent !important;
    opacity: 0 !important;
}
.ocf-cta > .ocf-cta__image,
.ocf-cta .ocf-cta__image {
    display: none;
}
.ocf-cta {
    --cta-headline-color: var(--ocf-heading);
    --cta-body-color: var(--ocf-body);
    background: radial-gradient(60% 80% at 100% 0%, color-mix(in srgb, var(--ocf-primary) 12%, white), white) !important;
    border-top: 1px solid var(--ocf-border-light);
}
.ocf-cta .ocf-cta__phone {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    min-height: 3rem;
    padding: 0;
    padding-left: 0;
    border: 0;
    border-left: 0;
    color: var(--ocf-body);
    font-family: var(--ocf-font-heading), system-ui, sans-serif;
    font-weight: var(--font-weight-bold);
    text-decoration: none;
}
.ocf-cta .ocf-cta__phone:hover,
.ocf-cta .ocf-cta__phone:focus-visible {
    color: var(--ocf-body);
    text-decoration: underline;
}
.ocf-cta .ocf-cta__phone strong {
    color: var(--ocf-heading);
}

/* ============================================================
   F1 -- floating-label request form
   (this pack's own templates/ultimate/parts/hero-form.php; targets its
   .ultimate-f1-field wrapper -- input, then label, in source order, so a
   plain adjacent-sibling selector is enough)

   BOXED 2026-09-12 (skin/form-nav-cool, Hannah, verbatim): "the contact
   form I want to match this reference [the Atlantic hero card] ... inputs
   are NOT underline-only." This block used to draw a bare 2px
   border-bottom (underline-only, no left/right/top edge, no fill) -- now a
   full 1px box on all four sides, var(--ocf-bg-alt) fill (matches the
   reference contact form's own filled input: measured
   color(srgb .932 .938 .946) on 923d3b89-cedar-grove-family-dentistry...,
   same cool-grey family as this theme's own --ocf-bg-alt post-retint), and
   a 10px radius (kept as its own fixed value per this brief's "keep the
   boxed inputs from the earlier commit" instruction, unaffected by the
   later same-day ruling that moved the card's OWN radius onto the shared
   var(--card-radius) token -- see contact-form.css's .hero-form-card
   comment) so the fields read as their own consistent system. Padding/
   label geometry are unchanged --
   comfortable height was already right (this card already measures ~55px
   tall, matching the reference's 54.8px) -- only the border/fill/radius
   changed; the label still floats via the existing
   :not(:placeholder-shown) trick, just inset 1rem now to line up with the
   new horizontal padding instead of sitting flush against a bare
   underline.
   ============================================================ */
.ultimate-f1-field {
    position: relative;
}
.ultimate-f1-field input,
.ultimate-f1-field textarea {
    border: 1px solid var(--ocf-border-light) !important;
    border-radius: var(--radius-input) !important;
    background: var(--ocf-bg-alt) !important;
    padding: 1.15rem 1rem 0.45rem !important;
    box-shadow: none !important;
}
.ultimate-f1-field input:focus,
.ultimate-f1-field textarea:focus {
    border-color: var(--ocf-primary) !important;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--ocf-primary) 10%, transparent) !important;
}
.ultimate-f1-field label {
    /* z-index 2, ABOVE the input (contact-form.css's shared .ocf-field
       input rule sets z-index:1 + position:relative on the input itself).
       That z-index gap didn't matter for the old underline/transparent
       input -- you could see the label through it regardless of paint
       order -- but now that the input has an opaque --ocf-bg-alt fill
       (boxed, 2026-09-12), a positioned sibling with z-index:1 paints
       above one with z-index:auto no matter its DOM order, so without
       this the label was fully hidden behind the input (caught in this
       PR's own before/after proof capture, not the reference). */
    position: absolute;
    z-index: 2;
    left: 1rem;
    top: 1.15rem;
    color: var(--ocf-body);
    font-size: var(--font-body-size, 1rem);
    pointer-events: none;
    transition: transform 180ms ease, font-size 180ms ease, color 180ms ease;
    transform-origin: left top;
}
.ultimate-f1-field input:focus + label,
.ultimate-f1-field input:not(:placeholder-shown) + label,
.ultimate-f1-field textarea:focus + label,
.ultimate-f1-field textarea:not(:placeholder-shown) + label {
    transform: translateY(-1.1rem);
    color: var(--ocf-primary);
    font-size: 0.72rem;
}

/* ============================================================
   H1 -- hero stat card: overlaps the hero's bottom edge, count-up numbers
   (templates/ultimate/parts/home-hero.php's $ultimate_hero_stats block --
   absolutely positioned, so it never joins .ocf-hero's own CSS-grid layout;
   .ocf-hero gets a matching margin-bottom so the card has room to sit half
   in the hero photo, half over the section below, without covering either
   section's real content. HONESTY GATE lives in the PHP: this CSS only ever
   sees the block when at least one real stat exists.)
   ============================================================ */
.ocf-hero {
    overflow: visible;
    margin-bottom: 2.75rem;
}
.ultimate-hero-stats {
    position: absolute;
    left: 1.25rem;
    right: 1.25rem;
    bottom: -2.75rem;
    z-index: 2;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 2.4rem;
    max-width: 26rem;
    margin: 0 auto;
    padding: 0.9rem 1.25rem 1.5rem;
    background: var(--ocf-bg);
    border-radius: var(--card-radius);
    box-shadow: 0 16px 30px -14px color-mix(in srgb, var(--ocf-heading) 35%, transparent);
}
.ultimate-hero-stat {
    text-align: center;
}
.ultimate-hero-stat__num {
    display: block;
    color: var(--ocf-primary);
    font-family: var(--ocf-font-heading), system-ui, sans-serif;
    font-weight: 800;
    font-size: 1.5rem;
}
.ultimate-hero-stat__label {
    display: block;
    margin-top: 0.15rem;
    color: var(--ocf-body);
    font-size: 0.7rem;
}
@media (max-width: 640px) {
    .ultimate-hero-stats { gap: 1.4rem; }
}

/* ============================================================
   R3 -- rating pill (restyles the existing #236 honest-badge markup,
   .ocf-hero__rating, in place -- same real value/label it already
   computes, no new copy)
   ============================================================ */
.ocf-hero__rating {
    display: inline-flex;
    background: color-mix(in srgb, #ffffff 16%, transparent);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border-radius: var(--radius-full);
    padding: 0.5rem 1.1rem;
}
.ocf-hero__rating-value {
    font-family: var(--ocf-font-heading), system-ui, sans-serif;
    font-weight: 800;
}

/* ============================================================
   S1 -- photo-top service cards: hover lift (already the shared default
   via --card-transform-hover) + accent underline sweep under the title
   ============================================================ */
.ocf-svc-card-body h3 {
    position: relative;
    display: inline-block;
    padding-bottom: 0.15rem;
}
.ocf-svc-card-body h3::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: -2px;
    width: 0;
    height: 2px;
    background: var(--ocf-primary);
    transition: width 250ms var(--ease);
}
.ocf-svc-card:hover .ocf-svc-card-body h3::after,
.ocf-svc-card:focus-within .ocf-svc-card-body h3::after {
    width: 100%;
}

/* ============================================================
   P1 -- about bullets: soft accent disc + accent-colored check
   (about.css already draws the disc/check via --about-check-color /
   --about-check-mark-color pseudo-elements -- this pack only retints the
   two tokens, no new markup)
   ============================================================ */
.ocf-about {
    --about-check-color: color-mix(in srgb, var(--ocf-primary) 14%, var(--ocf-bg));
    --about-check-mark-color: var(--ocf-primary);
}

/* ============================================================
   Ultimate about photo: short landscape crop, not full-height portrait
   (2026-09-08, Hannah: "our photo on the left here is very long and
   should be shorter"). The 2026-09-03 rule directly above this comment
   set the media box to the source photo's raw 2:3 portrait ratio, which
   at this column's rendered width stretched the box to ~830-920px tall
   -- nearly the full height of the text column next to it, reading as
   "very long." Measured against the reference product's home About photo
   (Playwright computed styles/bounding box, 1440 viewport,
   /Users/hannahopenclaw/Hermes/work/design-refs/about-photo-review-cards-2026-09-08/measure.py):
   716.0 x 477.3px rendered, aspect-ratio "3 / 2", border-radius 10px,
   object-fit cover, no box-shadow, vertically centered against the copy
   column (.ocf-about__grid's own align-items: center in about.css
   already matches this, unchanged here). This rule now crops the same
   portrait source to that measured 3:2 ratio instead of running it at
   its native 2:3 -- the photo is shorter, matching the reference and
   Hannah's ask, at the cost of cropping the portrait source (accepted
   per this brief: the ask is "shorter," not "uncropped"). This
   design.css file only ever loads for the ultimate pack (see this
   file's own header + functions.php's oneclick_assets()), so no extra
   scoping selector is needed for the frozen packs to stay zero-diff.
   ============================================================ */
.ocf-about__media img {
    /* 2026-09-10 (Hannah: "our image is not the right size in the about
       section"): re-measured against the reference product's build of the
       SAME business (Palmetto Shield pest pair, 1440 viewport): their About
       photo renders 666 x 599px, aspect-ratio 10 / 9, filling the media
       column's height beside the copy; ours at 3 / 2 rendered 612 x 408
       with empty space under it. 10 / 9 matches that measurement. */
    aspect-ratio: 10 / 9;
    object-fit: cover;
}

/* ============================================================
   about_detail_image (Hero+About fields, parity 2026-09-09): a small
   inset photo overlapping the team photo's corner -- only ever rendered
   when the field has a value (see templates/ultimate/parts/home-about.php's
   if-guard), so a site with no detail photo set gets zero new markup and
   zero visual change. .ocf-about__media already has position:relative
   (assets/components/about.css), which this positions against. The
   compound selector (".ocf-about__media img.ocf-about__detail") is needed
   to out-specificity the ".ocf-about__media img" 3:2 crop rule directly
   above, which would otherwise win on equal-specificity class+element
   selectors and force this photo into the wrong aspect ratio.
   ============================================================ */
.ocf-about__media img.ocf-about__detail {
    position: absolute;
    right: -1.25rem;
    bottom: -1.25rem;
    width: 42%;
    max-width: 200px;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: var(--image-radius);
    border: 4px solid var(--ocf-bg, #fff);
    box-shadow: 0 12px 30px rgba(0, 0, 0, .18);
}

/* ============================================================
   P2 -- numbered how-we-work steps: lighter accent circle, hairline
   connector (commitments.css already draws the numbered circle + the
   connecting line via ::before/::after -- this pack only resizes the
   circle and re-centers the connector on the new size, no new markup)
   ============================================================ */
.ocf-commitment-num {
    inline-size: 2.5rem;
    block-size: 2.5rem;
    font-size: 0.85rem;
}
.ocf-commitments .ocf-commitment:not(:last-child)::before {
    top: calc(2.5rem - 1px);
    left: calc(1.25rem - 1px);
}
.ocf-commitments .ocf-commitment:not(:last-child)::after {
    left: calc(2.5rem + clamp(1rem, 2vw, 1.35rem));
}

/* ============================================================
   Q1 -- smooth FAQ accordion, keyboard accessible
   (faq.css already draws the trigger/chevron/answer structure with
   aria-expanded + .is-open -- this pack swaps display:none/:block for a
   grid-template-rows animation so open/close is smooth; JS:
   templates/ultimate/assets/ultimate.js toggles .is-open on click. Native
   <button> triggers stay keyboard-operable with no extra work.)

   2026-09-03 "skin corrections" (owner screenshot FAQ_Sloppy_Not_premium.png,
   fix/ultimate-faq-cards): the two-column hairline list read as sloppy --
   templates/ultimate/parts/home-faq.php now renders ONE column of FAQ
   items; this block turned each .ocf-faq-item into its own boxed card
   (rounded rectangle, light border, white card surface) instead of the
   shared faq.css's flat hairline-divider list. The two rules below with
   .ocf-faq-column/:first-child in their selector exist only to out-specify
   the equally- or more-specific shared faq.css rules they replace (the
   two-column grid, and the tinted first-child top border) -- nothing in
   assets/components/faq.css itself changes, so every other pack keeps the
   exact hairline look untouched.

   2026-09-12 "premium raised cards" (Hannah, skin/faq-premium, item 4 of
   the 9/12 list -- "let's make our FAQ feel more premium and 3d like the
   reference"): the 9/3 boxed card (hairline border, flat 8px --card-radius,
   medium-weight question, thin outline plus icon) still read as a form
   field, not a lifted card. Reference = the Professional Services FAQ
   (wordpress-1588483-6226559.cloudwaysapps.com, "Frequently Asked
   Questions"), measured live with Playwright:
     - card: 16px radius, 0 border, white bg, a soft two-layer drop shadow
       (rgba(50,50,93,.25) 0 10px 20px -6px, rgba(0,0,0,.3) 0 6px 12px -6px),
       question in the .bde-faq__title span specifically (not the h3
       wrapper, which reports a misleading 500) at font-weight 700 / 18px
       Montserrat -- i.e. genuinely bold, matching Hannah's own description.
     - icon: an 18x18 Font Awesome "circle-plus"/"circle-minus" solid glyph
       (a single-color filled circle with the plus/minus cut out of the
       fill), color rgb(30,143,94) (their accent green).
     - layout: two columns, 578px each, 48px column gap, 16px row gap,
       inside an ~1200px content column.
   What we did, and why it isn't a literal copy:
     - Shadow: instead of hand-copying the reference's fixed black-ish
       rgba recipe, this card reuses --shadow-card / --shadow-card-hover --
       the SAME per-skin card-lift tokens every other card on the site
       already consumes (see assets/skin.css's [data-skin='foundry'] .card,
       .review-card, .coverage-card etc.), so the FAQ card matches our own
       card language and stays correct under every brand skin instead of
       carrying one hardcoded shadow color. Visual effect (soft lift off
       the section's --ocf-bg-alt band) matches; the literal shadow color/
       layering does not, by design.
     - Icon: no new markup and no new icon asset. faq.css's existing
       plus-becomes-minus SVG (2 strokes, opacity-swapped via
       aria-expanded/.is-open -- untouched) is given a filled-circle
       treatment with CSS alone: explicit box-sizing:border-box width/
       height + padding shrinks the SVG's own viewBox-scaled content
       inside a var(--radius-full) circle painted with --ocf-primary (the
       brief's own brand color, never a hardcoded green -- this engine is
       multi-tenant, the reference is a single site), stroke recolored to
       --ocf-bg (white) via currentColor. Confirmed by local Playwright
       render (both plus and open/minus states) before landing -- see PR
       body. Because this is CSS-only, templates/ultimate/parts/
       home-faq.php and the batch mini's cloneFaqSection() in
       functions/_leadgen_render.ts (which emits the identical
       .ocf-faq-icon markup) both pick it up unmodified; only the
       byte-for-byte CSS sync (tools/sync_lg_theme.py) needed re-running
       for the mini engine to match. (parts/service-detail.php did NOT pick
       this up "for free" as first claimed here -- see the 2026-09-12
       second-pass note below the shadow/gap paragraphs: that file's FAQ
       block was still flat prose, not this component, until this PR.)
     - Layout: STAYS one column on our pages. The reference's two columns
       (578px + 48px gap = 1204px) would just fit our foundry skin's 1300px
       --container-max, but the 9/3 ruling above rejected two columns for
       exactly this section because it read as sloppy -- and our own FAQ
       answers (real per-brief copy, one to several sentences) are far less
       uniform in length than the reference's short, hand-picked answers,
       so a 578px-wide column would show visibly uneven card heights next
       to each other. The "premium/3d" ask is about the card treatment
       (radius, shadow, bold question, filled icon), not the column count,
       so this PR gets there without reopening the column ruling.
     - Padding/gaps: 1.125rem/1.25rem card padding and a 1rem (16px) list
       gap approximate the reference's ~18-20px padding and measured 16px
       row gap, rounded to this pack's existing rem scale rather than
       inventing new fractional tokens.

   2026-09-12 second pass, skin/faq-premium continued (PR #469):
     (a) Hannah, live on the rendered card: "lower the shadow slightly so
         it's not so in your face". The card dropped --shadow-card /
         --shadow-card-hover for a literal, roughly-60%-strength two-layer
         shadow instead of scaling those tokens down -- --shadow-card is the
         SAME token reviews/coverage/service cards use (this brief's own
         "do not touch" list), so shrinking the token would have shrunk
         every other card's lift too. Measured (foundry skin, the only skin
         these numbers were read against):
           before: 0 4px 16px rgba(0, 0, 0, 0.12)              (--shadow-card)
                   0 6px 22px rgba(0, 0, 0, 0.16)  hover/open   (--shadow-card-hover)
           after:  0 1px 2px rgba(15, 23, 42, .04), 0 6px 16px rgba(15, 23, 42, .06)
                   0 2px 4px rgba(15, 23, 42, .05), 0 8px 20px rgba(15, 23, 42, .08)  hover/open
         (the "after" base is Hannah's own example value from the brief;
         hover/open is "a touch stronger" than that, well under the old
         --shadow-card-hover.)
     (b) EVERYWHERE (common-everywhere-rules.md): parts/service-detail.php's
         FAQ block ("Common questions") rendered as flat prose (trailing h3
         Q + p A inside the .prose field), not this card component, on every
         service and service-area page -- confirmed 9/12, contradicting this
         docblock's own now-corrected claim below that it "gets the identical
         ... card treatment for free". That file now emits the same
         .ocf-faq-item/.ocf-faq-trigger/.ocf-faq-answer markup as home,
         pulled out of `.prose` into its own `.ocf-faq-columns` list (one
         column, same as home) so this CSS applies unchanged; the two rules
         below with an `h3` in the selector exist only because that file
         keeps the question as an `<h3>` for SEO (it was a real heading
         before) instead of home's plain `<span>` -- they reset the h3 to
         inherit the trigger button's own type/color so it is visually
         identical to the home cards. ultimate.js (the same click handler,
         unmodified) now loads on every page via footer.php instead of only
         the two home-hero parts -- see footer.php's own comment -- so the
         accordion is interactive there too, not just visually a card.
   ============================================================ */
.ocf-faq-columns {
    grid-template-columns: 1fr;
    gap: 1rem;
    margin-top: 1.75rem;
}
.ocf-detail-faqs .ocf-faq-columns {
    margin-top: 1.25rem;
}
.ocf-faq-column {
    gap: 1rem;
}
.ocf-faq-item {
    border: 0;
    /* skin/radius-scale (2026-09-12): was a raw 1rem; now the shared
       --card-radius token (16px, same value -- this PR unifies the FAQ
       card onto the same token hero/service/review cards use, no visual
       change here). */
    border-radius: var(--card-radius);
    background: var(--ocf-bg);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 6px 16px rgba(15, 23, 42, .06);
    padding: 1.125rem 1.25rem;
    transition: box-shadow var(--motion);
}
.ocf-faq-column .ocf-faq-item:first-child {
    border-top: 0;
}
.ocf-faq-trigger {
    padding: 0;
    font-weight: var(--font-weight-bold);
    font-size: 1.0625rem;
}
/* parts/service-detail.php keeps the question as an <h3> (SEO); make it
   look exactly like home's plain <span> by inheriting the trigger's type. */
.ocf-faq-trigger h3 {
    margin: 0;
    font: inherit;
    color: inherit;
}
.ocf-faq-icon {
    width: 1.75rem;
    height: 1.75rem;
    padding: 0.375rem;
    box-sizing: border-box;
    border-radius: var(--radius-full);
    background: var(--ocf-primary);
    color: var(--ocf-bg);
    transition: background var(--motion), box-shadow var(--motion);
}
.ocf-faq-answer {
    display: grid;
    grid-template-rows: 0fr;
    padding: 0;
    transition: grid-template-rows 320ms var(--ease);
}
.ocf-faq-item.is-open .ocf-faq-answer {
    display: grid;
    grid-template-rows: 1fr;
}
.ocf-faq-answer p {
    overflow: hidden;
    margin: 0;
    padding-top: 0.75rem;
}
.ocf-faq-item:hover {
    box-shadow: 0 2px 4px rgba(15, 23, 42, .05), 0 8px 20px rgba(15, 23, 42, .08);
}
.ocf-faq-item.is-open {
    box-shadow: 0 2px 4px rgba(15, 23, 42, .05), 0 8px 20px rgba(15, 23, 42, .08);
    background: color-mix(in srgb, var(--ocf-primary) 3%, var(--ocf-bg));
}

/* skin/radius-scale (2026-09-12), item requested alongside the radius
   sweep: parts/content-model.php still renders FAQs as plain native
   <details class="faq-item"> inside <section class="faq-section">, with
   NO matching CSS anywhere in the theme (assets/base.css only has
   .faq -- a bare hairline-divider row -- and .faq-item--v1, neither of
   which matches the ".faq-item" class this file actually prints; the
   result today is fully unstyled native <details> markup). This file is
   not called by any current template (single-service.php/single-
   service_area.php both moved to parts/service-detail.php's .ocf-faq-item
   card already), so nothing on a live site changes -- but the fix is a
   few lines of CSS-only alignment onto the SAME shared card tokens as
   every other FAQ card, so if/when content-model.php is wired back in it
   already matches instead of shipping the old unstyled/flat look. No
   markup change, no JS -- native <details>/<summary> disclosure. */
.faq-section .faq-item {
    border: 0;
    border-radius: var(--card-radius);
    background: var(--ocf-bg, #fff);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 6px 16px rgba(15, 23, 42, .06);
    padding: 1.125rem 1.25rem;
    margin-bottom: 1rem;
    transition: box-shadow var(--motion, 0.3s ease-in-out);
}
.faq-section .faq-item:last-child {
    margin-bottom: 0;
}
.faq-section .faq-item:hover,
.faq-section .faq-item[open] {
    box-shadow: 0 2px 4px rgba(15, 23, 42, .05), 0 8px 20px rgba(15, 23, 42, .08);
}
.faq-section .faq-item summary {
    cursor: pointer;
    font-weight: var(--font-weight-bold, 700);
    font-size: 1.0625rem;
    color: var(--ocf-heading, inherit);
    list-style-position: outside;
}
.faq-section .faq-item p {
    margin: 0;
    padding-top: 0.75rem;
    color: var(--ocf-body, inherit);
}

/* ============================================================
   T1 -- dark footer with a soft accent glow
   (footer.css .site-footer already consumes --ocf-footer-bg/-heading/-body
   -- set to the dark family at the top of this file; this block adds the
   radial glow + a matching dark hairline, content/links unchanged)
   ============================================================ */
.site-footer {
    position: relative;
    overflow: hidden;
    border-top-color: transparent;
}
.site-footer::before {
    content: "";
    position: absolute;
    top: -45%;
    left: 50%;
    z-index: 0;
    width: 75%;
    height: 85%;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--ocf-primary) 45%, transparent), transparent 70%);
    transform: translateX(-50%);
    pointer-events: none;
}
.footer-grid,
.footer-bottom {
    position: relative;
    z-index: 1;
}
.footer-bottom {
    border-top-color: color-mix(in srgb, #ffffff 15%, transparent);
}
/* Footer links inherit base.css's global `a { color: var(--color-accent) }`,
   which is unreadable on this pack's #141414 footer -- repoint them to the
   dark-footer tokens already set above (icons use stroke="currentColor" in
   footer.php so they follow along automatically). */
.footer-link-list a,
.footer-contact-links a,
.footer-bottom-links a {
    color: var(--ocf-footer-body);
}
.footer-link-list a:hover,
.footer-link-list a:focus-visible,
.footer-contact-links a:hover,
.footer-contact-links a:focus-visible,
.footer-bottom-links a:hover,
.footer-bottom-links a:focus-visible {
    color: var(--ocf-footer-heading);
}

/* ============================================================
   R4 -- reviews marquee: a continuous right-to-left row of review cards
   (owner correction, 2026-09-03, screenshot "Reviews_add_card_animation.
   png": the old two-static-card layout read as unfinished, not premium).
   The scroll mechanism itself -- assets/base.css's .reviews-marquee /
   .marquee-track (two identical flex rows sharing one 40s linear infinite
   translateX keyframe, so as the first tiles fully out of view the second
   is already positioned exactly where it started -- seamless loop, zero
   JS -- plus its own prefers-reduced-motion block that drops the
   animation and hides the duplicate row entirely) is untouched here, only
   read; parts/testimonials.php renders that duplicate second .marquee-
   track (aria-hidden + inert) even under 4 reviews so the track still
   fills the row. Cards reuse .ocf-testimonial-card (testimonials.css --
   existing border/radius/bg/padding); only the fixed marquee width, the
   12px radius and the new avatar/name/meta top row are added below. The
   avatar is a solid --ocf-primary disc with the reviewer's own first
   initial (base.css's own generic .avatar class only supplies size/shape;
   this pack fills it solid instead of a soft tint, per the reference).
   The meta line under the name is the honest per-review star row, or
   "Google review" ONLY when that review's own `source` field really is
   google (testimonials.php's honesty check, same rule parts/rating-
   badge.php already applies) -- never an invented source. Edge fades are
   the brief's own explicitly-optional touch: pure CSS, no JS, no new
   markup.
   ============================================================ */
.reviews-marquee.ocf-reviews-marquee {
    position: relative;
    /* 2026-09-08, Hannah: "these boxes look almost cut off at the shadow
       below." base.css's .reviews-marquee sets a plain `overflow: hidden`
       (both axes) so the track can slide horizontally without showing the
       looped duplicate row -- but the card's own box-shadow (measured
       here: 0 2.88px 8.8px, ~10.7px reach below the card) paints outside
       the card's border box, and since this container's height is exactly
       the card's height (auto, no built-in headroom), that shadow was
       clipped by the same overflow:hidden meant only for the horizontal
       loop. Fix: split the axes -- overflow-x: clip keeps the horizontal
       clip the marquee animation needs, overflow-y: visible (higher
       specificity than base.css's one-class rule, so this wins) lets the
       shadow render in full above/below the row. padding-block reserves
       room for that shadow inside the row's own box instead of relying on
       whatever whitespace happens to be below in the page flow;
       margin-block cancels the added height so the section's outer
       spacing is unchanged. padding-inline/margin-inline give the first
       and last card a small buffer of background before the edge-fade
       masks below start, instead of the fade eating straight into the
       card's own edge (same reason the first card read as "cut off" on
       the left -- flush against the container edge with no buffer). */
    overflow-x: clip;
    overflow-y: visible;
    padding-block: 1rem;
    margin-block: -1rem;
    padding-inline: 0.5rem;
    margin-inline: -0.5rem;
}
.reviews-marquee.ocf-reviews-marquee::before,
.reviews-marquee.ocf-reviews-marquee::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: 1;
    width: clamp(1.5rem, 6vw, 4rem);
    pointer-events: none;
}
.reviews-marquee.ocf-reviews-marquee::before {
    left: 0;
    background: linear-gradient(90deg, var(--ocf-bg), transparent);
}
.reviews-marquee.ocf-reviews-marquee::after {
    right: 0;
    background: linear-gradient(270deg, var(--ocf-bg), transparent);
}
.ocf-review-marquee-card {
    width: 340px;
    flex: none;
    /* skin/radius-scale (2026-09-12): was a raw 12px, one step off the
       hero/service/FAQ card radius; now the shared --card-radius token
       (16px) so the review card matches every other card on the site. */
    border-radius: var(--card-radius);
    padding: 20px;
}
/* Specificity note: testimonials.css's `.ocf-testimonials .ocf-testimonial-
   card { min-height: clamp(...) }` (two classes) outranks a plain single-
   class override, cascade order or not -- this one matches it so the
   marquee card's height stays content-driven instead of that clamp. */
.ocf-testimonials .ocf-review-marquee-card {
    min-height: auto;
}
.ocf-review-marquee-top {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}
/* skin/reviews-b (2026-09-12), review card option B: avatar restyled from a
   solid --ocf-primary disc to a soft-tint OUTLINED circle (options.json
   components.review_card.B: ".rv-avatar { background:#F7F7F5; color:#2A6F45;
   border:1px solid #DCEBE1; }") -- ported to tokens instead of the option's
   raw hex per the brief: #F7F7F5 is this theme's own --ocf-bg-alt value, and
   the border is a soft accent tint via the same color-mix() idiom
   ocf-global.css already uses for --gradient-primary-soft. */
.ocf-review-marquee-avatar.avatar {
    width: 40px;
    height: 40px;
    background: var(--ocf-bg-alt);
    color: var(--ocf-primary);
    border: 1px solid color-mix(in srgb, var(--ocf-primary) 20%, var(--ocf-bg-alt));
    font-family: var(--ocf-font-heading), system-ui, sans-serif;
    font-size: 0.95rem;
}
.ocf-review-marquee-who {
    display: grid;
    gap: 0.2rem;
}
.ocf-review-marquee-who strong {
    color: var(--ocf-heading);
    font-weight: 800;
}
.ocf-review-marquee-meta {
    color: var(--ocf-label);
    font-size: var(--font-label-size);
}
/* skin/reviews-b (2026-09-12): option B's stars are accent green everywhere
   (options.json review_card.B markup_sample: star <span> color:#2A6F45).
   The grid/slider variant's .ocf-testimonial-stars (testimonials.css) is
   already var(--ocf-primary) -- only the marquee's higher-specificity
   ".ocf-review-marquee-meta.ocf-testimonial-stars" override needed to move
   off the muted --ocf-label it inherited from the plain .ocf-review-marquee-
   meta ("Google review" text) rule above. */
.ocf-review-marquee-meta.ocf-testimonial-stars {
    gap: 0.15rem;
    color: var(--ocf-primary);
}
.ocf-review-marquee-meta.ocf-testimonial-stars svg {
    width: 0.85rem;
    height: 0.85rem;
}

/* ============================================================
   R5 -- static reviews grid (brief-fix-home-section-bands, 2026-09-11,
   item 3: with 3 or fewer real reviews on file, parts/testimonials.php
   renders this plain grid instead of the R4 marquee above -- looping the
   same 1-3 cards in a continuous scroll read as broken, not premium, on a
   thin review count. Cards reuse .ocf-testimonial-card verbatim (same
   quote-icon/blockquote/stars/author markup the non-ultimate slider
   branch already uses, testimonials.css -- existing border/radius/bg/
   padding, no new card styling needed), this rule only supplies the grid
   layout itself. No fixed card width (unlike the marquee's 340px) -- a
   grid of 1-3 cards should fill the row, not float a fixed-width island.
   ============================================================ */
.ocf-reviews-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 1.5rem;
}

/* ============================================================
   Hannah's 2026-09-03 correction -- inner-page text: smaller, tighter,
   premium (screenshot "Inner_page_text_sloppy:large_not_premium.png", a
   service-area page). Before this, both prose containers on ultimate's
   inner pages fell all the way through to base.css's raw h1..h4/p
   defaults with zero per-container override: parts/service-detail.php's
   .prose (service + service-area detail pages) and page-about.php's
   .ocf-about-story__content (About's rich-text story) -- so body copy
   read 18px/1.68 (--font-body-size) and section h2 read
   clamp(1.5rem,3.2vw,2.1rem), both oversized and loose at desktop widths,
   and every section printed a plain <hr> divider right above its h2.
   Deliberately literal rem values below, NOT var(--font-body-size) /
   var(--font-h2-size) / var(--font-h3-size) -- those tokens also drive
   the HOME page and every other pack's body copy, which stays untouched
   per the brief ("do NOT change --font-body-size globally"). This file
   only loads for design_template "ultimate" (functions.php's
   oneclick_assets()), so none of this reaches Lightning/Pacific/etc.
   ============================================================ */
.prose,
.ocf-about-story__content {
    max-width: 68ch;
    /* 2026-09-05 (fix/theme-tokens-apply): wrapped in
       var(--oc-owner-font-body-size, ...) so a Text Styles Body-size token
       reaches this container -- falls back to the exact 17px this file
       chose over --font-body-size when no owner token is set. */
    font-size: var(--oc-owner-font-body-size, 1.0625rem); /* 17px, was --font-body-size (18px) */
    line-height: 1.6;     /* was 1.68 (.prose) / base.css's 1.65 (about) */
}
.prose > * + *,
.ocf-about-story__content > * + * {
    margin-top: 1.1em;
}
.prose h2,
.ocf-about-story__content h2 {
    margin: 0 0 0.5em;
    font-size: var(--oc-owner-font-h2-size, 1.75rem); /* 28px, was clamp(1.5rem, 3.2vw, 2.1rem) up to 33.6px */
    line-height: 1.25;
}
/* Same specificity as the ".prose h2" rule above (one class + one type each
   -- the ">" combinator adds no specificity of its own), so source order
   is what makes this one win on margin-top only; every prose h2 is a
   direct child of .prose / .ocf-about-story__content (service-detail.php
   nests nothing between them), so this reaches all of them. */
.prose > h2,
.ocf-about-story__content > h2 {
    margin-top: 2.5rem;
}
.prose h3,
.ocf-about-story__content h3 {
    font-size: var(--oc-owner-font-h3-size, 1.25rem); /* 20px, was base.css's flat 1.2rem -- kept, restated
                            in rem so it never drifts with body's raw h3 rule */
    line-height: 1.3;
}
/* service-detail.php prints a plain <hr> above every section h2 (and above
   the trailing FAQ block's "Common questions" h2) -- Hannah's correction:
   remove it, the 2.5rem top margin above already separates sections. */
.prose hr {
    display: none;
}

/* ============================================================
   2026-09-08 correction -- inner-page "text wall": Hannah's follow-up ask
   ("the inner pages of [the reference] template look much nicer and more
   premium than ours ... match the premium look of the text wall: spacing,
   sizing and format", side card stays put) measured against the reference's
   computed styles at 1440px (brief:
   .superpowers/sdd/alpha-2026-09-08/brief-inner-page-text-wall.md). Scoped
   to service-detail.php's .ocf-detail-content .prose (the ONLY template
   that uses the bare .prose class -- page-about.php's
   .ocf-about-story__content is untouched and still reads the 2026-09-03
   block above; the home page, hero, FAQ block markup, sidebar card
   (.ocf-detail-aside/.ocf-detail-sticky-*) and footer use none of these
   selectors either). Two classes + type beats both the 2026-09-03 block's
   one class + type above AND skin.css's [data-skin='foundry'] h1..h4 rule
   (one attribute + type) on specificity alone, so this wins regardless of
   file load order without an !important anywhere. Colors read the site's
   own tokens (--ocf-heading / --ocf-border-light via header.php's
   --color-heading / --color-border-light) rather than the reference's
   literal hex, so every brand palette keeps working.
   ============================================================ */
.ocf-detail-content .prose,
.ocf-detail__content .prose {
    color: var(--ocf-heading); /* darkest ink token, not the muted --ocf-body this container inherited before */
}
.ocf-detail-content .prose h2,
.ocf-detail__content .prose h2 {
    margin: 48px 0 16px;
    font-size: 30px;
    font-weight: 600;
    line-height: 1.22;
    text-transform: none;
}
.ocf-detail-content .prose > h2,
.ocf-detail__content .prose > h2 {
    /* same child-combinator specificity trick as the 2026-09-03 block above --
       restates margin-top so an intervening bare ".prose h2" rule (any skin
       or future pack) can never win it back on source order. */
    margin-top: 48px;
}
.ocf-detail-content .prose h3,
.ocf-detail__content .prose h3 {
    margin: 36px 0 12px;
    font-size: 23px;
    font-weight: 600;
    line-height: 1.2;
    text-transform: none;
}
.ocf-detail-content .prose p {
    margin: 0 0 18px;
    font-size: 18px;
    font-weight: 400;
    line-height: 1.72;
}
.ocf-detail-content .prose ul,
.ocf-detail-content .prose ol,
.ocf-detail__content .prose ul,
.ocf-detail__content .prose ol {
    margin: 16px 0 22px;
    padding-left: 27px;
}
.ocf-detail-content .prose li,
.ocf-detail__content .prose li {
    margin-bottom: 9px;
    font-size: 18px;
    font-weight: 400;
    line-height: 1.68;
}
.ocf-detail-content .prose li::marker,
.ocf-detail__content .prose li::marker {
    color: var(--ocf-heading);
}
.ocf-detail-content .prose strong,
.ocf-detail__content .prose strong {
    font-weight: 700;
    color: var(--ocf-heading);
}
/* Reference shows a real visible divider above each section h2 (the
   2026-09-03 block's hr display:none above is now overridden here for the
   detail content column only -- About's rich-text story still gets no
   divider, unchanged). */
.ocf-detail-content .prose hr,
.ocf-detail__content .prose hr {
    display: block;
    margin: 34px 0;
    border: 0;
    border-top: 1px solid var(--ocf-border-light);
}

/* Sidebar "book now" card (detail-page.css's .ocf-detail-sticky-*): the
   heading was wrapping awkwardly at --font-h3-size (20px) in a 320px-wide
   card at some sites' brand-token sizes -- restated as an explicit,
   slightly smaller literal so it never inherits a per-site
   --ocf-font-h3-size override. Button + phone row untouched. */
.ocf-detail-sticky-heading {
    font-size: 1.25rem; /* 20px */
    line-height: 1.3;
}
.ocf-detail-sticky-desc {
    font-size: 0.9375rem; /* 15px, was --font-label-size (16px) */
}

/* HTML sitemap page (page-sitemap.php, /sitemap/) -- plain heading + link
   list per page type. No new tokens: reuses --ocf-primary for the link
   color (same accent every other in-body link on this pack uses) and the
   existing card-radius/spacing rhythm via simple margins, nothing novel. */
.ocf-sitemap-page {
    max-width: 48rem;
}
.ocf-sitemap-group + .ocf-sitemap-group {
    margin-top: 2.5rem;
}
.ocf-sitemap-list {
    list-style: none;
    margin: 1rem 0 0;
    padding: 0;
    display: grid;
    gap: 0.625rem;
}
.ocf-sitemap-list a {
    color: var(--ocf-primary);
    text-decoration: none;
}
.ocf-sitemap-list a:hover,
.ocf-sitemap-list a:focus-visible {
    text-decoration: underline;
}

/* ---------- Reduced motion: every effect above still WORKS, it just snaps
   instead of animating (component-menu.html's own ".is-still" idiom) ---------- */
@media (prefers-reduced-motion: reduce) {
    .nav-bar,
    .nav-inner,
    .btn-primary,
    .btn-primary svg,
    .ultimate-b1-btn,
    .ultimate-b1-arrow,
    .hero-form-card .form-submit-btn,
    .btn-outline,
    .btn-outline::before,
    .ocf-cta .ocf-cta__phone,
    .ultimate-f1-field label,
    .ultimate-f1-field input,
    .ultimate-f1-field textarea,
    .ocf-svc-card,
    .ocf-svc-card-body h3::after,
    .ocf-faq-answer {
        transition: none !important;
    }
    .btn-primary:hover,
    .btn-primary:focus-visible,
    .ultimate-b1-btn:hover,
    .ultimate-b1-btn:focus-visible,
    .hero-form-card .form-submit-btn:hover,
    .ocf-svc-card:hover {
        transform: none !important;
    }
}
