/* css/scroll-patterns.css
 * Shared styles for the marketing scroll patterns: the sticky product bar,
 * peek carousels, the synced accordion and its figures, reveal-on-scroll.
 *
 * ⚠️ EXTRACTED SO TWO PAGES CANNOT DRIFT. index.html and coaching.html both
 * use these patterns, and a second inline copy would be two places to fix
 * every bug found in one of them.
 *
 * ⚠️ IT DEFINES NO TOKENS AND NO PAGE LAYOUT. It depends on the set every
 * marketing page declares in :root (--ember, --ember-deep, --ember-text,
 * --off-white, --warm-grey, --border, --green, --gold), and on --rail-bleed
 * for the carousel gutter. An earlier extraction swept up index.html's modal,
 * form and mobile rules by taking everything BETWEEN two markers; take the
 * marked blocks themselves.
 */

    /* ── STICKY PRODUCT BAR ──────────────────────────────────────────────
       Sits under the global nav once the hero scrolls away, so the demo ask is
       always one tap off without ever interrupting the page. Shown by
       js/scroll-patterns.js; hidden and inert until then. */
    /* ⚠️ visibility, NOT transform alone. Moving it off screen leaves its link
       and button in the TAB ORDER, so a keyboard user lands on an invisible
       bar, and aria-hidden over focusable content is itself a violation.
       visibility:hidden removes it from both the tab order and the
       accessibility tree, and the 0s delay lets the slide-out still play.
       Same fix the demo modal on sales.html needed. */
    .pbar {
      position:fixed; z-index:90; left:50%; top:68px;
      visibility:hidden;
      transform:translate(-50%,-180%);
      transition:transform .42s cubic-bezier(.22,.8,.3,1), visibility 0s .42s;
      width:min(880px, calc(100vw - 32px));
      display:flex; align-items:center; gap:10px;
      padding:8px 8px 8px 20px; border-radius:100px;
      background:rgba(30,42,53,0.82);
      border:1px solid var(--border);
      backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
      box-shadow:0 12px 36px rgba(0,0,0,0.42);
    }
    .pbar.show { visibility:visible; transform:translate(-50%,0); transition:transform .42s cubic-bezier(.22,.8,.3,1), visibility 0s 0s; }
    .pbar-name { font-weight:600; font-size:15px; color:var(--off-white); margin-right:auto; letter-spacing:-0.2px; }
    .pbar-ghost {
      font-size:13px; font-weight:500; color:var(--off-white); text-decoration:none;
      border:1px solid rgba(255,255,255,0.2); border-radius:100px; padding:8px 18px;
      transition:border-color .2s;
    }
    .pbar-ghost:hover { border-color:rgba(255,255,255,0.5); }
    .pbar-cta {
      font-family:'DM Sans',sans-serif; font-size:13px; font-weight:600; color:#fff;
      background:var(--ember-deep); border:none; border-radius:100px; padding:9px 20px;
      cursor:pointer; transition:background .2s;
    }
    .pbar-cta:hover { background:var(--ember-dk); }
    /* ── THE SWAP ─────────────────────────────────────────────────────────
       ⚠️ THE NAV IS position:fixed ON EVERY PAGE, so it never scrolls away.
       On the product pages it also carries Book a Demo AND Sign In — the same
       two controls the bar offers — so the bar read as a duplicate stacked
       under a nav that was still there. It now takes the nav's place.
       ⚠️ visibility, NOT opacity alone. An opacity:0 nav keeps every link in
       the tab order, which is the exact keyboard trap this bar already shipped
       once. visibility removes it from both the screen and the focus order. */
    html[data-pbar] nav {
      opacity:0; visibility:hidden; pointer-events:none;
      transition:opacity .28s ease, visibility 0s .28s;
    }
    nav { transition:opacity .28s ease, visibility 0s 0s; }

    /* ⚠️ NO SWAP ON A PHONE. The nav holds the hamburger, so hiding it there
       would leave a reader with no way to navigate at all — the bar has no
       menu. Below this width the bar simply never appears and the nav stays. */
    @media (max-width: 768px) {
      .pbar, .pbar.show { display:none; }
      html[data-pbar] nav { opacity:1; visibility:visible; pointer-events:auto; }
    }

    @media(max-width:700px) { .pbar { top:60px; padding-left:16px; } }
    @media(max-width:460px) { .pbar-ghost { display:none; } }

    /* ── PEEK CAROUSEL ───────────────────────────────────────────────────
       The half-visible neighbouring card is the only affordance telling a
       reader this scrolls, which is why there are no arrows. */
    .trust-rail {
      display:flex; gap:20px; overflow-x:auto; scroll-snap-type:x mandatory;
      margin-block:48px 0; padding-block:4px; text-align:left;
      /* ⚠️ THE BLEED MUST EQUAL THE PAGE GUTTER or the rail is wider than the
         viewport. index.html drops to 20px below 600 and coaching.html keeps
         24px at every width, so the page declares it. A hardcoded -24px
         overflowed index by exactly 4px once already. */
      margin-inline:calc(var(--rail-bleed, 24px) * -1);
      padding-inline:var(--rail-bleed, 24px);
      scroll-padding-inline:var(--rail-bleed, 24px);
      scrollbar-width:none; -ms-overflow-style:none;
    }
    .trust-rail::-webkit-scrollbar { display:none; }
    /* ⚠️ The bleed must equal the section padding exactly, or the rail is wider
       than the viewport. The mobile breakpoint drops section padding 24 → 20,
       so this has to follow it; a fixed -24px overflowed the page by 4px and
       render:site-fr caught it at 390. */
    /* ⚠️ THE CARD WIDTH IS WHAT MAKES THE SCROLL WORTH DOING. At a flat 320px,
       a desktop showed 3.4 of the 6 cards and the whole rail was 1.8 screens
       long, so swiping revealed almost nothing and the carousel read as
       decoration. Scaling with the viewport puts ~2.5 cards on screen and ~2.4
       screens in the rail, which is the ratio that makes a peek mean "there is
       more over here" rather than "this got clipped". render:patterns holds the
       RATIO, not this pixel value. */
    .trust-rail .trust-item {
      flex:0 0 auto; width:clamp(288px, 30vw, 430px); scroll-snap-align:center;
      display:flex; flex-direction:column; padding:30px 28px;
    }
    /* These were emoji when this rule was written, so it sized them as TYPE.
       They are stroke SVGs on both pages now; font-size does nothing to one. */
    /* The rail cards answer a pointer too. Shared, so coaching and sales
       behave the same way rather than one of them feeling dead. */
    .trust-rail .trust-item { transition:border-color .2s, transform .2s; }
    .trust-rail .trust-item:hover { border-color:rgba(231,76,60,0.3); transform:translateY(-3px); }
    @media (prefers-reduced-motion: reduce) {
      .trust-rail .trust-item:hover { transform:none; }
    }
    .trust-rail .trust-ico { width:38px; height:38px; margin-bottom:18px; }
    .trust-rail .trust-h { font-size:17px; margin-bottom:10px; }
    .trust-rail .trust-p { font-size:14px; }
    .rail-controls { display:flex; align-items:center; justify-content:center; gap:10px; margin-top:32px; }
    .rail-dots { display:flex; align-items:center; gap:2px; background:rgba(255,255,255,0.04); padding:2px 6px; border-radius:100px; }
    /* ⚠️ THE BUTTON IS 24x24; THE DOT INSIDE IT IS 7px. A 7px tap target fails
       WCAG 2.5.8, and the spacing exception does not rescue it either, because
       24px circles centred on 16px-apart dots overlap. The box carries the hit
       area and the ::before carries the look, so nothing changes visually. */
    .rail-dot {
      width:24px; height:24px; padding:0; border:none; background:none; cursor:pointer;
      display:flex; align-items:center; justify-content:center; border-radius:100px;
    }
    .rail-dot::before {
      content:''; display:block; width:7px; height:7px; border-radius:100px;
      background:rgba(255,255,255,0.38);
      transition:width .3s cubic-bezier(.22,.8,.3,1), background .3s;
    }
    .rail-dot[aria-current="true"]::before { width:18px; background:var(--off-white); }
    .rail-toggle {
      width:38px; height:38px; border-radius:100px; cursor:pointer;
      border:1px solid var(--border); background:rgba(255,255,255,0.04);
      color:var(--off-white); display:flex; align-items:center; justify-content:center;
      transition:background .2s;
    }
    .rail-toggle:hover { background:rgba(255,255,255,0.1); }
    .rail-toggle .ico-pause { display:block; }
    .rail-toggle .ico-play { display:none; }
    .rail-toggle.paused .ico-pause { display:none; }
    .rail-toggle.paused .ico-play { display:block; }
    .rail-toggle svg { width:12px; height:12px; fill:currentColor; }

    /* ── ACCORDION WITH A SYNCED PANEL ───────────────────────────────────
       Five capabilities in one screen's worth of height. A skimmer reads five
       labels; a buyer opens all five. The page never gets longer either way. */
    .closer { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:48px; align-items:start; margin-top:48px; text-align:left; }
    .closer-list { display:flex; flex-direction:column; gap:10px; }
    .closer-nav { display:flex; gap:16px; align-items:flex-start; }
    .closer-nav .closer-list { flex:1; min-width:0; }
    /* Hidden by default; the large-screen block turns it on. */
    .closer-steppers { display:none; flex-direction:column; gap:10px; position:sticky; top:120px; }
    .closer-step {
      width:38px; height:38px; flex-shrink:0; border-radius:100px; cursor:pointer;
      border:1px solid var(--border); background:rgba(255,255,255,0.04); color:var(--off-white);
      display:flex; align-items:center; justify-content:center; transition:background .2s, opacity .2s;
    }
    .closer-step:hover:not(:disabled) { background:rgba(255,255,255,0.1); }
    .closer-step:disabled { opacity:0.32; cursor:default; }
    .closer-step svg { width:16px; height:16px; display:block; }
    .closer-step:focus-visible { outline:2px solid var(--ember-text); outline-offset:3px; }
    .closer-chip {
      width:100%; text-align:left; cursor:pointer;
      font-family:'DM Sans',sans-serif; font-size:15px; font-weight:600; color:var(--off-white);
      background:rgba(255,255,255,0.03); border:1px solid transparent; border-radius:14px;
      padding:15px 18px; display:flex; align-items:center; gap:12px;
      transition:background .2s, border-color .2s;
    }
    .closer-chip:hover { background:rgba(255,255,255,0.06); }
    .closer-chip[aria-expanded="true"] { background:rgba(231,76,60,0.08); border-color:rgba(231,76,60,0.28); }
    .closer-sign {
      width:20px; height:20px; flex-shrink:0; border-radius:50%;
      border:1px solid rgba(255,255,255,0.18); color:var(--warm-grey);
      display:flex; align-items:center; justify-content:center;
      font-size:14px; line-height:1;
    }
    .closer-chip[aria-expanded="true"] .closer-sign { background:var(--ember-deep); border-color:transparent; color:#fff; }
    .closer-body { overflow:hidden; max-height:0; transition:max-height .38s cubic-bezier(.22,.8,.3,1); }
    .closer-body p { font-size:14px; color:var(--warm-grey); line-height:1.65; padding:14px 18px 6px; }

    /* The panel is decorative: every word lives in the accordion body above,
       so it carries aria-hidden and never becomes the only copy of a fact. */
    /* ⚠️ ONE GRID CELL, NOT ABSOLUTE POSITIONING. The figures used to be
       position:absolute with a fixed inset, so the box could not grow: adding a
       third and fourth turn to the practice figure made its content taller than
       the box and it SPILLED OUT over the chips above, covering them. Stacking
       all five in a single grid cell lets the panel take the height of the
       tallest one and nothing escapes it. */
    .closer-stage {
      display:grid; align-items:center;
      border:1px solid var(--border); border-radius:16px;
      background:rgba(255,255,255,0.02); padding:32px; min-height:300px;
    }
    /* ⚠️ visibility again, and for the same reason. Only one figure is on
       screen, but all five are in the DOM: with opacity alone a screen reader
       reads every one of them, and the pause control inside the Whisper figure
       would be tabbable while invisible. */
    .closer-fig {
      grid-area:1 / 1; display:flex; flex-direction:column; justify-content:center; gap:14px;
      opacity:0; visibility:hidden; pointer-events:none;
      transition:opacity .3s ease, visibility 0s .3s;
    }
    .closer-fig.on { opacity:1; visibility:visible; pointer-events:auto; transition:opacity .3s ease, visibility 0s 0s; }
    /* transcript bubbles.
       ⚠️ The turns arrive one at a time when the panel opens, and then STOP.
       Deliberately not a loop: a loop would be motion running indefinitely,
       which needs its own pause control under WCAG 2.2.2. Playing once on
       demand needs none, and it reads better anyway.
       The resting state is all four visible; js/scroll-patterns.js sets
       data-steps before it hides any of them, so no script means no blanks. */
    .fig-bubble { border-radius:14px; padding:11px 14px; font-size:13px; line-height:1.5; }
    html[data-steps] .closer-fig[data-panel="practice"] .fig-bubble {
      opacity:0; transform:translateY(6px);
      transition:opacity .42s ease, transform .42s ease;
    }
    html[data-steps] .closer-fig[data-panel="practice"] .fig-bubble.in { opacity:1; transform:none; }
    .fig-bubble .who { display:block; font-size:9px; letter-spacing:1.4px; text-transform:uppercase; color:var(--warm-grey); margin-bottom:5px; }
    .fig-bubble.them { background:rgba(255,255,255,0.05); margin-right:14%; color:var(--warm-grey); }
    .fig-bubble.you { background:rgba(231,76,60,0.14); margin-left:14%; color:var(--off-white); }

    /* framework score bars. Names, not placeholder blocks. */
    /* ── reconstructed product UI ────────────────────────────────────────
       ⚠️ THESE ARE REBUILT FROM THE COMPONENTS, NEVER DRAWN FROM MEMORY.
       Geometry, labels and colours come from app/src/coaching.jsx: the score
       ring is ScoreRing's own maths (r = 0.4 x size, stroke = 0.08 x size,
       numeral = 0.27 x size), the bars are the report's 8px track with
       bandColor, the history rows are its timeline, and the privacy banner is
       the Hard Guard's real wording. Shown in the app's DARK theme, which it
       genuinely ships, so the frame reads as the product rather than as a
       light screenshot dropped on a dark page. */
    .ui { border:1px solid var(--border); border-radius:12px; background:rgba(255,255,255,0.025); overflow:hidden; }
    .ui-bar { display:flex; align-items:center; gap:9px; padding:9px 13px; border-bottom:1px solid var(--border); background:rgba(255,255,255,0.02); }
    .ui-dot { width:7px; height:7px; border-radius:50%; background:rgba(255,255,255,0.18); flex:0 0 auto; }
    .ui-title { font-size:9.5px; font-weight:700; letter-spacing:1.1px; text-transform:uppercase; color:var(--warm-grey); }
    .ui-body { padding:14px 15px; display:flex; flex-direction:column; gap:11px; }
    .ui-cap { font-size:9px; font-weight:700; letter-spacing:1px; text-transform:uppercase; color:var(--warm-grey); }
    .ui-hero { display:flex; align-items:center; gap:15px; }
    .ui-ring { width:78px; height:78px; flex:0 0 auto; }
    .ui-ring text { font-family:'DM Sans',system-ui,sans-serif; fill:var(--off-white); }
    .ui-band { font-size:13px; font-weight:700; color:var(--off-white); margin-top:3px; }
    .ui-sub { font-size:11px; color:var(--warm-grey); line-height:1.45; margin-top:4px; }
    .ui-sub b { color:var(--off-white); font-weight:700; }
    .ui-score { flex:0 0 auto; width:26px; text-align:right; font-size:11.5px; font-weight:700; color:var(--off-white); }

    /* history timeline — the real rows, icon rail and all */
    .ui-item { display:flex; gap:11px; }
    .ui-rail { display:flex; flex-direction:column; align-items:center; flex:0 0 auto; }
    .ui-pip { width:22px; height:22px; border-radius:50%; background:rgba(231,76,60,0.16); flex:0 0 auto; }
    .ui-thread { width:2px; flex:1; min-height:10px; background:var(--border); margin:3px 0; }
    .ui-row { flex:1; display:flex; justify-content:space-between; gap:10px; align-items:flex-start;
              border-radius:10px; padding:9px 11px; background:rgba(255,255,255,0.04); }
    .ui-kind { font-size:9.5px; font-weight:700; color:var(--ember); }
    .ui-goal { font-size:11.5px; font-weight:600; color:var(--off-white); margin-top:2px; }
    .ui-date { font-size:9.5px; color:var(--warm-grey); margin-top:2px; }
    .ui-big { font-size:17px; font-weight:800; color:var(--off-white); line-height:1; text-align:right; }
    .ui-big span { font-size:9px; color:var(--warm-grey); }
    .ui-tap { font-size:8.5px; color:var(--warm-grey); margin-top:3px; text-align:right; }

    /* transcript audit */
    .ui-field { border:1px solid var(--border); border-radius:9px; padding:10px 12px; background:rgba(0,0,0,0.18);
                font-size:11.5px; color:var(--warm-grey); line-height:1.6; }
    .ui-alert { border-radius:9px; padding:10px 12px; background:rgba(231,76,60,0.14);
                font-size:11px; color:var(--off-white); line-height:1.55; }
    .ui-btn { align-self:flex-start; border-radius:8px; padding:7px 14px; background:var(--ember);
              color:#fff; font-size:11px; font-weight:700; }
    .ui-btn.off { background:rgba(255,255,255,0.08); color:var(--warm-grey); }
    .ui-pill { display:inline-block; font-size:8.5px; font-weight:800; letter-spacing:.6px; text-transform:uppercase;
               color:#B7791F; background:rgba(243,156,18,0.16); padding:3px 9px; border-radius:100px; }

    @media (max-width:768px) {
      .ui-title { font-size:11px; }
      .ui-cap { font-size:10.5px; }
      .ui-sub, .ui-goal, .ui-field, .ui-alert { font-size:13.5px; }
      .ui-kind, .ui-date, .ui-tap { font-size:11px; }
      .ui-btn { font-size:13px; }
    }

    .fig-bar { display:flex; align-items:center; gap:12px; }
    .fig-bar-label { width:42%; flex-shrink:0; font-size:12px; color:var(--warm-grey); line-height:1.3; }
    .fig-bar-track { flex:1; display:block; height:8px; border-radius:4px; background:rgba(255,255,255,0.08); overflow:hidden; }
    .fig-bar-fill { display:block; height:8px; border-radius:4px; }

    /* live voice: the ring pulses and the wave moves, because a still picture
       of "real time voice" argues against itself */
    .fig-mic { width:78px; height:78px; border-radius:50%; background:rgba(231,76,60,0.12); border:1px solid rgba(231,76,60,0.35); display:flex; align-items:center; justify-content:center; align-self:center; position:relative; }
    .fig-mic::after {
      content:''; position:absolute; inset:-1px; border-radius:50%;
      border:1px solid rgba(231,76,60,0.5);
      animation:micRing 2.2s ease-out infinite;
    }
    .fig-mic span { width:34px; height:34px; border-radius:50%; background:var(--ember); animation:micDot 2.2s ease-in-out infinite; }
    @keyframes micRing { 0% { transform:scale(1); opacity:.7; } 100% { transform:scale(1.55); opacity:0; } }
    @keyframes micDot  { 0%,100% { transform:scale(1); } 50% { transform:scale(1.14); } }
    .fig-wave { display:flex; align-items:flex-end; justify-content:center; gap:5px; height:34px; align-self:center; }
    .fig-wave i {
      width:4px; height:100%; border-radius:2px; background:rgba(255,255,255,0.32); display:block;
      transform-origin:bottom; animation:wave 1.05s ease-in-out infinite alternate;
    }
    @keyframes wave { from { transform:scaleY(0.22); } to { transform:scaleY(1); } }

    /* gold standard before/after */
    .fig-swap { border-radius:12px; padding:13px 15px; font-size:13.5px; line-height:1.5; }
    .fig-swap .who { display:block; font-size:9px; letter-spacing:1.4px; text-transform:uppercase; margin-bottom:5px; }
    .fig-swap.before { background:rgba(255,255,255,0.04); color:var(--warm-grey); }
    .fig-swap.before .who { color:var(--warm-grey); }
    .fig-swap.after { background:rgba(39,174,96,0.12); color:var(--off-white); }
    .fig-swap.after .who { color:var(--green); }

    /* ⚠️ The Whisper Coach still is a LIGHT asset (it is a screenshot of the
       real cards), so it gets its own light surface rather than being dropped
       straight onto the dark panel. object-fit crops the generous margins the
       source carries so the card itself fills the frame. */
    /* ⚠️ THE SOURCE CARRIES HUGE MARGINS — the card occupies roughly the middle
       58% x 38% of the 1200x675 frame. Shown whole it renders as an unreadable
       stamp on a phone, so the image is scaled to 171.4% of the box and centred:
       that makes the card exactly as wide as the frame, which is the largest it
       can be in this space. Box aspect 2.72 is the card plus its floor pill.
       If the asset is ever rebuilt at different margins, these two numbers move
       together. */
    .fig-shot { position:relative; width:100%; aspect-ratio:2.72; border-radius:12px; overflow:hidden; background:#EFEFEF; border:1px solid rgba(255,255,255,0.1); }
    .fig-shot img { position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); width:171.4%; height:auto; display:block; }
    /* ⚠️ WCAG 2.2.2. The card animation loops forever (11.8s a cycle), and
       anything that moves on its own for more than five seconds needs a way to
       stop it. prefers-reduced-motion is a good default, not that mechanism.
       js/scroll-patterns.js only reveals this button when it has actually
       started the animation, so it is never a control that does nothing. */
    .fig-motion {
      position:absolute; right:8px; bottom:8px; width:30px; height:30px;
      display:flex; align-items:center; justify-content:center;
      border-radius:100px; cursor:pointer; border:none;
      background:rgba(15,23,30,0.78); color:#fff;
    }
    /* ⚠️ An author display rule BEATS the hidden attribute, so display:flex
       above left a dead pause button on screen whenever the animation was
       switched off. The attribute has to win. */
    .fig-motion[hidden] { display:none; }
    .fig-motion:hover { background:rgba(15,23,30,0.92); }
    .fig-motion svg { width:11px; height:11px; fill:currentColor; }
    .fig-motion .ico-play { display:none; }
    .fig-motion[aria-pressed="true"] .ico-pause { display:none; }
    .fig-motion[aria-pressed="true"] .ico-play { display:block; }

    /* One visible, high-contrast focus style for everything new. The UA default
       is a 1px auto ring, which is weak on this ground and inconsistent with
       the rest of the site. */
    .pbar-ghost:focus-visible, .pbar-cta:focus-visible, .closer-chip:focus-visible,
    .rail-dot:focus-visible, .rail-toggle:focus-visible, .trust-rail:focus-visible,
    .fig-motion:focus-visible {
      outline:2px solid var(--ember-text); outline-offset:3px;
    }
    @media(max-width:820px) {
      .closer { grid-template-columns:1fr; gap:28px; }
      .closer-stage { min-height:240px; padding:24px; }
      .closer-steppers { display:none; }
    }

    /* ── LARGE SCREENS ──
       The reference for this section is Apple's "Take a closer look", and on a
       27" monitor theirs is enormous: big pill chips, a stepper beside them, and
       a panel that dominates the column. At the base sizes this read as a small
       widget on a wide screen, so everything scales up past 1200px. */
    @media(min-width:1200px) {
      .closer { grid-template-columns:minmax(0,0.85fr) minmax(0,1.15fr); gap:56px; margin-top:64px; }
      .closer-list { gap:12px; }
      .closer-steppers { display:flex; }
      .closer-chip { font-size:18px; padding:20px 24px; border-radius:18px; }
      .closer-sign { width:26px; height:26px; font-size:17px; }
      .closer-body p { font-size:15px; padding:16px 24px 8px; }
      .closer-stage { min-height:470px; padding:44px; border-radius:20px; }
      .closer-fig { gap:18px; }
      .fig-bubble { font-size:15px; padding:14px 18px; }
      .fig-swap { font-size:15px; padding:16px 18px; }
      .fig-bar-label { font-size:13.5px; }
      .fig-mic { width:96px; height:96px; }
      .fig-mic span { width:42px; height:42px; }
      .fig-wave { height:44px; }
      .fig-wave i { width:5px; }
    }

    /* ── REVEAL ON SCROLL ────────────────────────────────────────────────
       ⚠️ The resting state here is VISIBLE. js/scroll-patterns.js adds
       data-reveal to <html> before it hides anything, so a blocked or failed
       script leaves the whole page readable rather than blank. */
    html[data-reveal] .reveal {
      opacity:0; transform:translateY(18px);
      transition:opacity .55s cubic-bezier(.22,.8,.3,1), transform .55s cubic-bezier(.22,.8,.3,1);
    }
    html[data-reveal] .reveal.in { opacity:1; transform:none; }

    @media (prefers-reduced-motion: reduce) {
      .pbar, .pbar.show { transition:none; }
      .closer-body, .closer-fig, .rail-dot::before { transition:none; }
      html[data-reveal] .reveal { opacity:1; transform:none; }
      /* The voice figure stops moving, and the wave settles at its drawn
         heights rather than collapsing to the animation's start frame. */
      .fig-mic::after { animation:none; opacity:0; }
      .fig-mic span, .fig-wave i { animation:none; }
      .fig-wave i { transform:none; }
    }

    /* ── ADOPTION ── the worry, then what actually happens. ─────────────── */
    .adopt-row {
      display:grid; grid-template-columns: 0.85fr 1.15fr; gap:28px;
      padding:26px 0; border-top:1px solid var(--border); align-items:start; text-align:left;
    }
    .adopt-row:last-of-type { border-bottom:1px solid var(--border); }
    .adopt-worry { font-family:'Instrument Serif',serif; font-size:21px; line-height:1.3; color:var(--warm-grey); }
    .adopt-answer { font-size:15px; color:var(--off-white); line-height:1.7; }
    .adopt-answer b { color:var(--off-white); font-weight:700; }
    .adopt-foot { margin-top:26px; font-size:13.5px; color:var(--warm-grey); line-height:1.7; max-width:760px; text-align:left; }

    /* ── FAQ ── native <details>: keyboard-operable, no JS, no CSP hash. ── */
    .faq-list { max-width:820px; margin:0 auto; text-align:left; }
    .faq-item { border-bottom:1px solid var(--border); }
    .faq-item summary {
      list-style:none; cursor:pointer; padding:20px 34px 20px 0; position:relative;
      font-size:16.5px; font-weight:600; color:var(--off-white); line-height:1.45;
    }
    .faq-item summary::-webkit-details-marker { display:none; }
    .faq-item summary:hover { color:var(--ember-text); }
    .faq-item summary:focus-visible { outline:2px solid var(--ember-text); outline-offset:3px; border-radius:4px; }
    .faq-sign { position:absolute; right:4px; top:50%; transform:translateY(-50%); width:18px; height:18px; color:var(--warm-grey); }
    .faq-item[open] .faq-sign { color:var(--ember-text); }
    .faq-sign .bar-v { transition:opacity .18s; }
    .faq-item[open] .faq-sign .bar-v { opacity:0; }
    .faq-a { padding:0 34px 22px 0; font-size:14.5px; color:var(--warm-grey); line-height:1.75; }
    .faq-a a { color:var(--ember-text); text-decoration:underline; text-underline-offset:2px; }

    @media (max-width: 768px) {
      .adopt-row { grid-template-columns:1fr; gap:12px; padding:22px 0; }
      .adopt-worry { font-size:19px; }
      .faq-item summary { font-size:15.5px; }
    }
