/* =====================================================================
   styles.css: Quick Release Bail Bonds, the home page prototype (2026-10-26).
   Tokens first, in :root: the starter's names holding the brand's values,
   then the design system's names that qr.css reads (aliases, and the DS
   palette names it still reads), then the names neither has. Then the
   page's layout and every change to a DS component, each named in
   MANIFEST.md. Loaded after qr.css. No colour appears outside :root.
   ===================================================================== */

:root {
  /* ---------- 1. The starter's names, holding the brand's values (refs/design-system-digest.md, section 2) ---------- */
  --surface-page: #ffffff;
  --surface-alt: #faf7f5;
  --surface-card: #faf7f5;
  --surface-sunken: #ebe3de;
  --surface-inverse: #03192c;
  --surface-deepest: #02101d;
  --text-primary: #382e27;
  --text-secondary: #68574b;
  --text-tertiary: #8a776a;
  --text-inverse: #ffffff;
  --text-inverse-secondary: #c9b4a7;
  --text-on-accent: #ffffff;
  --accent: #68574b;
  --accent-hover: #382e27;
  --accent-inverse: #b69f8f;
  --border-hairline: #c9b4a7;
  --border-inverse: #ffffff33;
  --border-field: #0b0c33;
  --focus-ring: #123161;
  --overlay-scrim: #03192cb8;

  --font-heading: Inter, "Inter Fallback", system-ui, sans-serif;
  --font-body: Inter, "Inter Fallback", system-ui, sans-serif;
  --font-accent: Oswald, "Oswald Fallback", "Arial Narrow", sans-serif;
  --fs-display: clamp(2.75rem, 1.6rem + 3.6vw, 4.875rem);
  --fs-h1: clamp(2.5rem, 1.45rem + 3.3vw, 4.0625rem);
  --fs-h2: clamp(2.125rem, 1.3rem + 2.4vw, 3.25rem);
  --fs-h3: clamp(1.75rem, 1.2rem + 1.6vw, 2.4375rem);
  --fs-h4: clamp(1.5rem, 1.1rem + 1.2vw, 2rem);
  --fs-lead: clamp(1.125rem, 0.95rem + 0.5vw, 1.375rem);
  --fs-body: clamp(1rem, 0.95rem + 0.15vw, 1.0625rem);
  --fs-small: 0.9375rem;
  --fs-caption: 0.75rem;
  --fs-label: 0.75rem;
  --lh-display: 1;
  --lh-heading: 1.1;
  --lh-snug: 1.35;
  --lh-body: 1.6;
  --ls-display: -0.04em;
  --ls-heading: -0.02em;
  --ls-body: 0;
  --ls-label: 0.22em;
  --fw-light: 300;
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
  --space-10: 128px;
  --section-y: clamp(4rem, 2rem + 6vw, 8.125rem);
  --gutter: clamp(1.25rem, -0.5rem + 6.5vw, 6.5rem);
  --container: 1800px;
  --measure: 36rem;
  --hairline: 1px;

  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --dur-fast: 220ms;
  --dur-base: 420ms;
  --dur-slow: 800ms;
  --dur-slower: 1200ms;
  --reveal-distance: 32px;
  --parallax-strength: .18;

  /* ---------- 2. The design system's names, which qr.css reads: aliases of the above ---------- */
  --surface: var(--surface-page);
  --surface-warm: var(--surface-alt);
  --surface-tint: var(--surface-sunken);
  --surface-dark: var(--surface-inverse);
  --surface-night: var(--surface-deepest);
  --scrim-nav: var(--overlay-scrim);
  --ink: var(--text-primary);
  --ink-strong: var(--text-strong);
  --ink-muted: var(--text-secondary);
  --ink-dim: var(--text-tertiary);
  --ink-on-dark: var(--text-inverse);
  --ink-on-dark-muted: var(--text-inverse-secondary);
  --ink-dim-on-dark: var(--text-inverse-tertiary);
  --action: var(--accent);
  --action-hover: var(--accent-hover);
  --on-action: var(--text-on-accent);
  --action-alt: var(--accent-alt);
  --accent-line: var(--border-accent);
  --line: var(--border-hairline);
  --line-soft: var(--border-soft);
  --line-on-dark: var(--border-inverse);
  --line-field: var(--border-field);
  --focus-ring-on-dark: var(--text-inverse);
  --success-surface: var(--accent);
  --error-surface: var(--surface-error);
  --error-line: var(--border-error);
  --error-ink: var(--text-error);
  --font-sans: var(--font-body);
  --font-display: var(--font-accent);
  --fs-hero: var(--fs-display);
  --container-max: var(--container);
  --container-max-wide: var(--container-wide);
  --timing-fast: var(--dur-fast);
  --timing-base: var(--dur-base);
  --timing-letter: var(--dur-base);
  --ease-out-circ: var(--ease-out);
  --ease-out-quart: var(--ease-out);
  --ease-in-out-circ: var(--ease-curtain);
  /* the DS palette names qr.css still reads */
  --white: #ffffff;
  --midnight-blue: #123161;
  --ink-violet: #12042c;
  --dim-grey: #68574b;

  /* ---------- 3. Names neither has ---------- */
  --surface-hero: #0b1116;
  --scrim-dark: #03192ce6;
  --accent-alt: #123161;
  --border-soft: #e4d9d1;
  --border-accent: #ecbd9c66;
  --text-strong: #201a16;
  --text-inverse-tertiary: #9a887b;
  --focus-halo: #ffffff;
  --text-error: #a4133c;
  --border-error: #c9184a;
  --surface-error: #ffccd5;
  --shadow-dropdown: 0 80px 100px -40px #0e131fb3;
  /* qr.css's raw colours, as tokens */
  --btn-light-line: #12042c33;
  --glass-fill: #c9b5a71a;
  --glass-fill-hover: #c9b5a740;
  --glass-line: #c9b5a780;
  --glass-line-hover: #c9b5a7bf;
  --pill-fill: #ffffff14;
  --pill-line: #ffffff80;
  --close-fill: #ffffffcc;
  --panel-glass: #ffffffe6;
  --track-line: #03192c4d;
  --location-glass: #ebe3dee6;
  --license-line: #03192c7d;
  --tile-scrim: #03192cb3;
  --tile-scrim-hover: #03192c99;
  --faq-line: #dde1e6;
  --faq-line-hover: #adb5bd;
  --footer-rule: #ffffff1a;

  --fs-overview: clamp(1.625rem, 1.15rem + 1.4vw, 2.1875rem);
  --fs-feature: clamp(3rem, 1.5rem + 4vw, 4.375rem);
  --fs-stat: clamp(3rem, 1.6rem + 3.2vw, 4.0625rem);
  --lh-lead: 1.7;
  --ls-nav: 0.1em;
  --ls-menu: 0.15em;
  --ls-menu-hover: 0.05em;
  --ls-eyebrow: 0.3em;
  --fw-bold: 700;

  --section-y-sm: clamp(3rem, 2rem + 2.5vw, 4rem);
  --container-wide: 2000px;
  --hit: 44px;
  --nav-topbar-h: 52px;
  --nav-row-h: 64px;
  --nav-h: 116px;
  --btn-pad-y: 18px;
  --btn-pad-x: 24px;
  --field-h: 56px;
  --callbar-h: 64px;
  --hero-min-h: min(100svh, 62rem);
  --radius-nav-pill: 20px;
  --radius-marker: 3px;
  --blur-nav: blur(14px);
  --blur-glass: blur(10px);
  --blur-close: blur(12px);
  --z-base: 1;
  --z-content: 10;
  --z-callbar: 990;
  --z-nav: 995;
  --z-menu: 999;
  --bp-phone: 480px;
  --bp-tablet: 768px;
  --bp-stage: 992px;
  --bp-nav: 1280px;
  --bp-wide: 1440px;

  --ease-curtain: cubic-bezier(.785, .135, .15, .86);
  --ease-linear: linear;
  --draw: 900ms;
  --reveal-rise: 115%;
  --stagger-word: 50ms;
  --stagger-item: 90ms;
  --scrub: .6;
  --settle-scale: 1.08;
  --curtain-travel: 101%;
  --ls-eyebrow-from: 0.6em;
  --header-solid-at: 80px;
  --callbar-at: .6;
  --smooth-lerp: .1;
  --smooth-wheel: 1;
  --ring-gap: 6px;
  --ring-from: .94;
  --nudge: 5px;
  --press: 1px;
  --js-fallback: 3000ms;

  /* ---------- 4. Round two: the menu and How It Works, as the live site has them (BRIEF-R2.md) ---------- */
  /* the menu: the photograph the backdrop, the frosted card over it, the links at the right, the Close strip at the left */
  --accent-tan: #847265;           /* the card's call button: the DS's grey (#927e70, the live tan) darkened along its hue until white labels reach AA */
  --menu-glass: #ffffff4d;         /* the card's white tint: 30% (live 11%, where the title reached 1.97:1); the least that brings the title to AA */
  --menu-glass-line: #ffffff99;    /* the card's border, white at 60% */
  --blur-card: blur(12px);         /* the card's frost, raised with its tint (live 5px) */
  --close-glass: #ffffff4d;        /* the Close strip's fill, white at 30% (live: none, where the word reached 3.16:1) */
  --menu-photo-share: 65%;         /* the photograph column's share of a wide screen; the links take the rest */
  --menu-photo-scale: 1.02;        /* the photograph, scaled as the live one is */
  --menu-close-w: 6.5rem;          /* the Close strip, 104px */
  --menu-card-w: 32.5rem;          /* the card, 520px */
  --menu-row-w: 23.375rem;         /* a link row, 374px */
  --menu-row-max: 8rem;            /* a link row's height when the window has room, 128px (live) */
  --menu-row-sm: 3.375rem;         /* a link row on a phone, 54px (live) */
  --menu-sign-w: 3.25rem;          /* the linen square, 52px */
  --fs-menu: 0.8125rem;            /* the links, 13px */
  --fs-menu-title: 1.1375rem;      /* Contact Us Today!, 18.2px */
  --ls-close: 0.4em;               /* the word Close */
  /* How It Works: a held video, a glass column scrolling over it */
  --steps-glass: #ffffff80;        /* the column, white at 50% */
  --steps-glass-line: #ffffffbf;   /* its border, white at 75% */
  --steps-title-strength: 90%;
  --steps-line-strength: 80%;      /* live 70%, which reached 4.02:1 over the video's darkest part; 80% holds AA */
  --steps-title-ink: color-mix(in srgb, var(--surface-deepest) var(--steps-title-strength), transparent);
  --steps-line-ink: color-mix(in srgb, var(--surface-deepest) var(--steps-line-strength), transparent);
  --steps-col-w: 50%;
  --steps-col-pad: 297px;
  --steps-col-margin: 260px;
  --steps-block-w: 325px;
  --steps-block-pad-y: 104px;      /* live 130px; tightened so five steps keep the section near 3.6 screens at 1440 by 900 */
  --steps-block-pad-x: 39px;
  --steps-part-gap: 19.5px;
  --fs-step-label: 4.0625rem;      /* 65px */
  --fs-step-title: 1.1375rem;      /* 18.2px */
  --fs-step-line: 0.975rem;        /* 15.6px */
  --ls-stat: -0.08em;              /* the DS's stat-number tracking */
  --video-wake: 50%;               /* the video pauses once its section is more than this share of a screen away */

  /* ---------- 5. Round three: experience, story and quality (BRIEF-R3.md) ---------- */
  --answer-row-w: calc(var(--measure) * 2 + var(--space-9)); /* the Answer's two-column row from --bp-stage: a measure each side and the gap */
  --steps-held-h: 100vh;           /* the steps' held layer, one window tall; the glass column pulls up over it by this much */
  --steps-still: url("img/texas-flag-poster-1280.jpg"); /* the still behind the steps' video from --bp-tablet; the 854 below it */

  /* ---------- 6. Round four: proof, pictures, headings (BRIEF-R4.md) ---------- */
  --star-size: 18px;               /* the proof strip's stars; the phone's size under --bp-tablet */
  --star-size-sm: 14px;            /* the phone's size; the office cards' stars at every width */
  --parallax-deep: .28;            /* a deeper plate: Glen's photograph and Start a Bond's; the hero and the cards keep --parallax-strength */
  --clip-from: inset(100% 0% 0% 0%); /* the clip reveal (Wells): the frame closed to its foot. Every side in % at both ends: GSAP */
  --clip-to: inset(0% 0% 0% 0%);      /* blends the two only when their units match (with bare zeros the frame jumped open at the end) */
  --proof-photo-ratio: 3 / 2;      /* the Proof photograph's tile under --bp-stage, the file's own shape */
  --track-tile-w: 85%;             /* a review tile's share of the track under --bp-stage, so the next one shows */

  /* ---------- 7. Round six, 2026-10-29: the figures under the hero and the carousel at every width ---------- */
  --stat-star: .42em;              /* the accent star after the strip's 4.9, a share of the figure's size */
  --stat-star-inset: .08em;        /* its gap from the figure and its drop from the figure's top, so it sits at the cap line */
  --track-tile-w-wide: 46%;        /* a review tile's share of the track from --bp-stage: two in view and the next one's edge */
}

/* The menu's card under 992px sits over a tighter crop of the photograph: its tint and frost go one step further to hold AA */
@media (max-width: 991.98px) {
  :root { --menu-glass: #ffffff66; --blur-card: blur(16px); }
}

/* How It Works on a phone, as the live phone has it but for the type: since round three the title 15px and the line 14px (TOKENS.md) */
@media (max-width: 767.98px) {
  :root {
    --steps-col-w: 66.667%;
    --steps-col-pad: 220px;
    --steps-col-margin: 110px;
    --steps-block-w: 100%;
    --steps-block-pad-y: 66px;
    --steps-block-pad-x: 31px;
    --steps-part-gap: 16.5px;
    --fs-step-label: 2.75rem;      /* 44px */
    --fs-step-title: var(--fs-small); /* 15px: raised in round three from the live proportions (14px here), to revert */
    --fs-step-line: 0.875rem;      /* 14px: raised in round three from 13px, likewise */
    --steps-still: url("img/texas-flag-poster-854.jpg");
    --star-size: var(--star-size-sm); /* round four: the strip's stars at the phone's size */
  }
}

/* Reduced motion: the tokens collapse, so CSS moves finish at once and nothing travels */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 1ms; --dur-base: 1ms; --dur-slow: 1ms; --dur-slower: 1ms; --draw: 1ms;
    --stagger-word: 1ms; --stagger-item: 1ms;
    --reveal-distance: 0px; --reveal-rise: 0%; --parallax-strength: 0; --settle-scale: 1;
    --ring-from: 1; --nudge: 0px; --press: 0px;
    --parallax-deep: 0; --clip-from: var(--clip-to); /* round four */
  }
}

/* Higher contrast: qr.css turns the DS's tan (--accent there) white; here --accent is the action colour, so it is restored and the tan goes white */
@media (prefers-contrast: more) {
  .qr { --accent: var(--dim-grey); --accent-inverse: var(--white); --text-secondary: var(--text-strong); --border-hairline: var(--text-secondary); }
  /* no glass: the menu's card and Close strip and the steps' column turn solid, as qr.css does for its own glass */
  html .qr .qr-menu__card, html .qr .qr-menu__close, html .qr .qr-scroll-steps__panel { background: var(--surface-page); -webkit-backdrop-filter: none; backdrop-filter: none; }
  /* round four: qr.css darkens --line-soft here, which would draw a rating's empty stars darker than its full ones */
  .qr .qr-stars__row { color: var(--surface-sunken); }
  .qr .qr-stars__row--fill { color: var(--text-strong); }
}

/* =====================================================================
   1. Base
   ===================================================================== */
html { scroll-padding-top: calc(var(--nav-row-h) + var(--space-4)); scrollbar-gutter: stable; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }
html.qr-menu-open { overflow: hidden; }
body { margin: 0; overflow-x: clip; }
.qr main:focus { outline: none; }
.qr :where(h1, h2, h3) { text-wrap: balance; }
.qr :where(p) { text-wrap: pretty; }

/* Placeholders: none is shown on the page since round four; the open facts are listed in the firm's README */

/* Masks: masked-lines' words (inline-blocks in their masks, LESSONS 2026-10-24) and the hero's two lines */
.qr .w { display: inline-block; overflow: hidden; vertical-align: top; padding: 0 .06em .14em 0; margin: 0 -.06em -.14em 0; }
.qr .wi { display: inline-block; }
.qr .qr-hl { display: block; overflow: hidden; padding: 0 .08em .12em 0; margin: 0 -.08em -.12em 0; }
.qr .qr-hli { display: block; }

/* Pre-hidden states: only with scripts, only with motion allowed. The head script sets html.js and lifts it if motion.js never starts */
.qr-curtain { display: none; }
@media (prefers-reduced-motion: no-preference) {
  html.js [data-reveal] { opacity: 0; }
  html.js .qr-hero .qr-hli { visibility: hidden; }
  html.js .qr-hero [data-hero-late], html.js .qr-hero .qr-eyebrow__text { opacity: 0; }
  html.js .qr-hero .qr-eyebrow__line { transform: scaleX(0); }
  html.js .qr-hero__media img { transform: scale(var(--settle-scale)); }
  html.js .qr-curtain { display: block; }
  html.js .proof-strip__rule { transform: scaleX(0); }   /* round four: the strip's hairlines, drawn as it arrives */
  html.js [data-clip] { clip-path: var(--clip-from); }  /* round four: Glen's photograph, opened as it arrives */
}

/* Two DS rules that mean a DS value the starter names otherwise (TOKENS.md, "A Note on Names") */
.qr .qr-eyebrow { color: var(--accent-inverse); }
.qr .qr-eyebrow--light { color: var(--ink-muted); }
.qr .qr-t-display { font-size: var(--fs-h1); }
.qr .qr-eyebrow__line:first-child { transform-origin: 100% 50%; }
.qr .qr-eyebrow__line:last-child { transform-origin: 0 50%; }

/* =====================================================================
   2. Hovers. Every pointer hover sits inside (hover: hover) and
   (pointer: fine); :focus-visible shows the same look at every width.
   ===================================================================== */
/* qr.css hovers this page replaces: off everywhere */
.qr .qr-eyebrow:hover .qr-eyebrow__text { letter-spacing: var(--ls-eyebrow); text-indent: var(--ls-eyebrow); }
.qr .qr-btn:hover { letter-spacing: var(--ls-label); }
.qr .qr-btn--nav, .qr .qr-btn--nav:hover { letter-spacing: var(--ls-nav); }
.qr .qr-nav__link:hover, .qr .qr-nav__link[aria-current] { border-top-color: transparent; text-decoration: none; }
.qr .qr-nav__toplink:hover { color: var(--surface-tint); border-bottom-color: transparent; text-decoration: none; }
.qr .qr-footer__link:hover { background: transparent; padding-inline: 0; }
.qr .qr-location__name:hover { color: var(--surface-dark); }
/* qr.css hovers this page keeps (fills): set back to rest on any pointer that is not fine, so nothing sticks after a tap */
@media not all and (hover: hover) and (pointer: fine) {
  .qr .qr-btn--primary:hover { --btn-bg: var(--action); }
  .qr .qr-btn--light:hover { --btn-bg: var(--surface); }
  .qr .qr-btn--outline:hover { --btn-bg: var(--surface-tint); --btn-line: var(--line); }
  .qr .qr-btn--nav:hover { --btn-bg: var(--pill-fill); --btn-ink: var(--on-action); }
  .qr .qr-nav__brand:hover { background: var(--surface); color: var(--surface-dark); }
  .qr .qr-nav__menu:hover { background: var(--surface); }
  .qr .qr-menu__link:not([aria-current]):hover { background: transparent; color: var(--ink-muted); letter-spacing: var(--ls-menu); }
  .qr .qr-menu__link--boxed:not([aria-current]):hover { background: var(--surface-alt); }
  .qr .qr-menu__contact-link:hover { background: var(--accent-tan); letter-spacing: var(--ls-nav); }
  .qr .qr-menu__contact-link--alt:hover { background: var(--action-alt); }
  .qr .qr-reviews__arrow:hover { border-color: var(--ink-muted); background: var(--surface); }
  .qr .qr-field:hover { border-color: transparent; border-bottom-color: var(--line-field); background: transparent; }
  .qr .qr-footer__tile:hover { background: transparent; }
}
/* the same fills on keyboard focus */
.qr .qr-btn--primary:focus-visible { --btn-bg: var(--action-hover); }
.qr .qr-btn--light:focus-visible { --btn-bg: var(--surface-tint); }
.qr .qr-btn--outline:focus-visible { --btn-bg: var(--surface-warm); --btn-line: var(--action); }
.qr .qr-btn--nav:focus-visible { --btn-bg: var(--line); --btn-ink: var(--surface-dark); }
.qr .qr-nav__brand:focus-visible { background: var(--action); color: var(--on-action); }
.qr .qr-nav__menu:focus-visible { background: var(--line); }
.qr .qr-menu__link:focus-visible { background: var(--surface-dark); color: var(--ink-on-dark); letter-spacing: var(--ls-menu-hover); }
.qr .qr-menu__link:focus-visible img { filter: none; opacity: 1; }
.qr .qr-menu__link:focus-visible::after { opacity: 1; transform: none; }
.qr .qr-menu__contact-link:focus-visible { background: var(--action-hover); }
.qr .qr-menu__contact-link--alt:focus-visible { background: var(--surface-dark); }
.qr .qr-reviews__arrow:focus-visible { border-color: var(--ink); background: var(--surface-tint); }
.qr .qr-footer__tile:focus-visible { background: var(--surface-tint); }

/* 1. Buttons: Wells' frame at radius 0. The fill moves to its hover colour; a hairline frame appears just outside, from --ring-from; the trailing icon slides; a press settles it */
.qr .qr-btn { overflow: visible; --btn-ring: var(--accent-hover); transition: background-color var(--dur-fast), border-color var(--dur-fast), color var(--dur-fast), transform var(--dur-fast) var(--ease-in-out); }
.qr .qr-btn::after { content: ""; position: absolute; inset: calc(var(--ring-gap) * -1); border: var(--hairline) solid var(--btn-ring); border-radius: inherit; opacity: 0; transform: scale(var(--ring-from)); transition: opacity var(--dur-base) var(--ease-in-out), transform var(--dur-base) var(--ease-in-out); pointer-events: none; }
.qr .qr-btn__icon { transition: transform var(--dur-base) var(--ease-in-out); }
.qr .qr-btn:active { transform: translateY(var(--press)); }
.qr .qr-btn--light { --btn-ring: var(--text-inverse); }
.qr .qr-btn--outline { --btn-ring: var(--accent); }
.qr .qr-on-dark .qr-btn--primary { --btn-ring: var(--text-inverse-secondary); }
.qr .qr-btn--nav { --btn-ring: var(--border-hairline); min-height: var(--hit); }
.qr .qr-btn--nav::after { border-radius: calc(var(--radius-nav-pill) + var(--ring-gap)); }
@media (hover: hover) and (pointer: fine) {
  .qr .qr-btn:hover::after { opacity: 1; transform: none; }
  .qr .qr-btn:hover .qr-btn__icon { transform: translateX(var(--nudge)); }
}
.qr .qr-btn:focus-visible::after { opacity: 1; transform: none; }
.qr .qr-btn:focus-visible .qr-btn__icon { transform: translateX(var(--nudge)); }
/* a long phone label wraps before the number, never inside it */
.qr .qr-btn__text { display: flex; flex-wrap: wrap; justify-content: center; column-gap: .5em; white-space: normal; text-align: center; }
.qr .qr-btn__text > span { white-space: nowrap; }

/* 2 and 3. Text links and nav links: sliding-underline in CSS, so it works by keyboard. A hairline sweeps in from the left and leaves to the right; the current page keeps it */
.qr .qr-link { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--hit); font-size: var(--fs-small); font-weight: var(--fw-semibold); color: var(--text-primary); }
.qr .qr-link__icon { width: 1rem; height: 1rem; flex: none; transition: transform var(--dur-base) var(--ease-in-out); }
.qr .u-line { position: relative; }
.qr .u-line::after { content: ""; position: absolute; left: 0; right: 0; bottom: -.3em; height: var(--hairline); background: currentColor; transform: scaleX(0); transform-origin: 100% 50%; transition: transform var(--dur-base) var(--ease-in-out); }
.qr .qr-link .u-line::before, .qr .qr-cta__note-link .u-line::before { content: ""; position: absolute; left: 0; right: 0; bottom: -.3em; height: var(--hairline); background: var(--border-hairline); }
.qr .qr-cta__note-link .u-line::before { background: var(--text-inverse-secondary); }
.qr [aria-current] > .u-line::after { transform: scaleX(1); transform-origin: 0 50%; }
@media (hover: hover) and (pointer: fine) {
  .qr a:hover > .u-line::after { transform: scaleX(1); transform-origin: 0 50%; }
  .qr .qr-link:hover .qr-link__icon { transform: translateX(var(--nudge)); }
}
.qr a:focus-visible > .u-line::after { transform: scaleX(1); transform-origin: 0 50%; }
.qr .qr-link:focus-visible .qr-link__icon { transform: translateX(var(--nudge)); }

/* 4. Footer and bottom-row links: colour only, each with a 44px hit area, the text unmoved */
.qr .qr-hit { position: relative; }
.qr .qr-hit::before { content: ""; position: absolute; left: calc(var(--space-1) * -1); right: calc(var(--space-1) * -1); top: 50%; height: var(--hit); transform: translateY(-50%); }

/* 5. Cards: the office card's top hairline turns --accent; photographs never zoom */
@media (hover: hover) and (pointer: fine) {
  .qr .qr-location:hover { border-top-color: var(--accent); }
}
.qr .qr-location:has(:focus-visible) { border-top-color: var(--accent); }

/* =====================================================================
   3. Header (Navbar): glass over the hero, solid --scrim-dark past
   --header-solid-at with its top bar folded; it never hides
   ===================================================================== */
.qr .qr-nav__topbar { justify-content: space-between; padding-inline: var(--space-6); }
.qr .qr-nav__toplink { position: relative; }
.qr .qr-nav__toplink::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: var(--hit); transform: translateY(-50%); }
.qr .qr-nav__links { padding-left: var(--space-5); }
.qr .qr-nav__link { gap: var(--space-2); padding: 0 var(--space-3); }
@media (min-width: 992px) and (max-width: 1279.98px) { .qr .qr-nav__links { display: none; } }
.qr .qr-nav__item { position: relative; display: flex; }
.qr .qr-nav__chev { width: 1rem; height: 1rem; filter: invert(1); }
.qr .qr-nav__drop { position: absolute; top: 100%; left: 0; z-index: var(--z-content); min-width: 15rem; margin: 0; padding: var(--space-2) 0; list-style: none; background: var(--surface-inverse); border: var(--hairline) solid var(--border-inverse); box-shadow: var(--shadow-dropdown); visibility: hidden; opacity: 0; transition: opacity var(--dur-fast), visibility 0s linear var(--dur-fast); }
.qr .qr-nav__item:has(:focus-visible) .qr-nav__drop { visibility: visible; opacity: 1; transition: opacity var(--dur-fast); }
@media (hover: hover) and (pointer: fine) { .qr .qr-nav__item:hover .qr-nav__drop { visibility: visible; opacity: 1; transition: opacity var(--dur-fast); } }
.qr .qr-nav__droplink { display: flex; align-items: center; min-height: var(--hit); padding: 0 var(--space-5); font-size: var(--fs-label); font-weight: var(--fw-semibold); letter-spacing: var(--ls-nav); text-transform: uppercase; color: var(--text-inverse); }
.qr .qr-nav__droplink:focus-visible { outline-offset: -4px; }
/* on a narrow phone the wordmark, the pill and the Menu square must share 390px */
@media (max-width: 479.98px) {
  .qr .qr-nav__brand { min-width: 0; padding-inline: var(--space-3); }
  .qr .qr-nav__name, .qr .qr-nav__slogan { letter-spacing: var(--ls-nav); text-indent: var(--ls-nav); }
  .qr .qr-nav__row { padding-inline: var(--space-2); }
  .qr .qr-btn--nav { padding-inline: var(--space-3); }
}

/* Menu (FullscreenMenu), rebuilt in round two as the live site has it. Phone first: a linen Close bar, the links, then the photograph with
   the frosted card over it; the menu scrolls when it is taller than the window. Wide (992px and up): the photograph is the backdrop of the
   left --menu-photo-share with the card centred over it, the links stand in a white column at the right, a frosted Close strip runs down
   the left edge. Opening, in CSS so it needs no GSAP, on the tokens T reads: the white ground unrolls (--ease-curtain, --dur-slower); the
   links rise in turn (--stagger-item); a white curtain slides off the photograph to the right (--ease-curtain); then the card rises
   (--reveal-distance, --dur-slow). Closing plays back faster. Under reduced motion the tokens collapse: it appears and disappears. */
.qr .qr-menu { display: flex; flex-direction: column; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; visibility: hidden; clip-path: inset(0 0 100% 0); transition: clip-path var(--dur-base) var(--ease-curtain) var(--dur-fast), visibility 0s linear calc(var(--dur-base) + var(--dur-fast)); }
.qr .qr-menu.is-open { visibility: visible; clip-path: inset(0); transition: clip-path var(--dur-slower) var(--ease-curtain), visibility 0s; }

/* Close: on a phone a linen bar across the top, the whole bar the button; its word is its name, shown on a wide screen */
.qr .qr-menu__close { position: sticky; top: 0; right: auto; z-index: var(--z-content); flex: none; width: 100%; height: auto; min-height: var(--hit); gap: var(--space-5); background: var(--line-soft); -webkit-backdrop-filter: none; backdrop-filter: none; }
.qr .qr-menu__close img { width: 1.25rem; height: 1.25rem; }
.qr .qr-menu__close-text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* The links: tall rows, each a linen square holding its icon, then the label. The current row and a hovered row fill dark (the DS's hover) */
.qr .qr-menu__links { flex: none; display: grid; grid-auto-rows: minmax(var(--menu-row-sm), auto); padding: var(--space-6); overflow: visible; }
.qr .qr-menu__link { gap: var(--space-6); padding: var(--space-3); border-bottom: 0; font-size: var(--fs-menu); font-weight: var(--fw-semibold); line-height: var(--lh-display); }
.qr .qr-menu__sign { flex: none; align-self: stretch; display: flex; align-items: center; justify-content: center; width: var(--menu-sign-w); background: var(--surface-tint); border: var(--hairline) solid var(--line-soft); }
.qr .qr-menu__link img, .qr .qr-menu__link:hover img, .qr .qr-menu__link[aria-current] img { width: 1rem; height: 1rem; filter: none; opacity: 1; }
.qr .qr-menu__link--boxed { background: var(--surface-alt); border: var(--hairline) solid var(--line-soft); }
.qr .qr-menu__link--boxed .qr-menu__sign { background: var(--surface-page); }
.qr .qr-menu__link::after { background-image: url("img/icons/arrow-white.svg"); }
@media (hover: hover) and (pointer: fine) { .qr .qr-menu__link--boxed:hover { background: var(--surface-dark); } }

/* The photograph, the card over it, and the white curtain that slides off it */
.qr .qr-menu__photo { position: relative; isolation: isolate; flex: 1 0 auto; display: flex; align-items: center; justify-content: center; padding: var(--space-6); overflow: hidden; }
.qr .qr-menu__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; transform: scale(var(--menu-photo-scale)); }
.qr .qr-menu__card { position: relative; z-index: var(--z-base); width: min(var(--menu-card-w), 100%); display: grid; gap: var(--space-5); padding: var(--space-6); background: var(--menu-glass); border: var(--hairline) solid var(--menu-glass-line); -webkit-backdrop-filter: var(--blur-card); backdrop-filter: var(--blur-card); text-align: center; }
.qr .qr-menu__card-title { margin: 0 0 var(--space-2); font-size: var(--fs-menu-title); line-height: var(--lh-body); font-weight: var(--fw-bold); letter-spacing: var(--ls-nav); text-transform: uppercase; color: var(--line-field); }
.qr .qr-menu__contact-link { min-height: var(--field-h); padding: var(--btn-pad-y) var(--space-4); line-height: var(--lh-snug); background: var(--accent-tan); }
.qr .qr-menu__contact-link--alt { background: var(--action-alt); }
@media (hover: hover) and (pointer: fine) {
  .qr .qr-menu__contact-link:hover { background: var(--action-hover); }
  .qr .qr-menu__contact-link--alt:hover { background: var(--surface-dark); }
}
.qr .qr-menu__curtain { position: absolute; inset: 0; z-index: var(--z-content); background: var(--surface-page); pointer-events: none; }

/* Opening and closing */
.qr .qr-menu [data-qr-menu-link] { opacity: 0; transform: translateY(var(--reveal-distance)); transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out), background-color var(--dur-fast), color var(--dur-fast), letter-spacing var(--dur-base) var(--ease-out); }
.qr .qr-menu.is-open [data-qr-menu-link] { opacity: 1; transform: none; transition: opacity var(--dur-slow) var(--ease-out) calc(var(--dur-base) + var(--i) * var(--stagger-item)), transform var(--dur-slow) var(--ease-out) calc(var(--dur-base) + var(--i) * var(--stagger-item)), background-color var(--dur-fast), color var(--dur-fast), letter-spacing var(--dur-base) var(--ease-out); }
.qr .qr-menu__curtain { transform: none; transition: transform var(--dur-base) var(--ease-curtain); }
.qr .qr-menu.is-open .qr-menu__curtain { transform: translateX(var(--curtain-travel)); transition: transform var(--dur-slow) var(--ease-curtain) var(--dur-slow); }
.qr .qr-menu__card { opacity: 0; transform: translateY(var(--reveal-distance)); transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out); }
.qr .qr-menu.is-open .qr-menu__card { opacity: 1; transform: none; transition: opacity var(--dur-slow) var(--ease-out) var(--dur-slower), transform var(--dur-slow) var(--ease-out) var(--dur-slower); }

/* The menu without scripts (round three): the Menu controls are links to #site-menu, and Close a link to #main. Closed, the menu is not
   rendered; opened, it is the :target, shown in its open state with no transitions. With scripts html.js is on and none of this applies
   (and should motion.js fail and lift html.js, ui.js's is-open still shows it) */
html:not(.js) .qr .qr-menu:not(:target):not(.is-open) { display: none; }
html:not(.js) .qr .qr-menu:target { visibility: visible; clip-path: none; transition: none; }
html:not(.js) .qr .qr-menu:target [data-qr-menu-link], html:not(.js) .qr .qr-menu:target .qr-menu__card { opacity: 1; transform: none; transition: none; }
html:not(.js) .qr .qr-menu:target .qr-menu__curtain { transform: translateX(var(--curtain-travel)); transition: none; }

/* Wide: the photograph column at the left, the links column at the right, the Close strip down the left edge over the photograph */
@media (min-width: 992px) {
  .qr .qr-menu { display: grid; grid-template-columns: var(--menu-photo-share) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); grid-template-areas: "photo links"; overflow: hidden; }
  .qr .qr-menu__close { position: absolute; inset: 0 auto 0 0; width: var(--menu-close-w); min-height: 0; flex-direction: column; background: var(--close-glass); -webkit-backdrop-filter: var(--blur-close); backdrop-filter: var(--blur-close); }
  .qr .qr-menu__close-text { position: static; width: auto; height: auto; overflow: visible; clip: auto; writing-mode: vertical-rl; transform: rotate(180deg); font-size: var(--fs-label); line-height: var(--lh-display); font-weight: var(--fw-regular); letter-spacing: var(--ls-close); text-transform: uppercase; color: var(--action-alt); }
  .qr .qr-menu__links { grid-area: links; grid-auto-rows: minmax(var(--hit), var(--menu-row-max)); align-content: center; justify-items: center; width: auto; padding: var(--space-8) var(--space-6); overflow-y: auto; }
  .qr .qr-menu__link { width: min(var(--menu-row-w), 100%); }
  .qr .qr-menu__photo { grid-area: photo; width: auto; padding: var(--space-8) var(--space-7) var(--space-8) calc(var(--menu-close-w) + var(--space-7)); }
  .qr .qr-menu__card { padding: var(--space-7); }
}

/* Call bar (MobileCallBar), phones only */
.qr .qr-callbar { grid-template-columns: 1.4fr 1fr; visibility: hidden; transition: transform var(--dur-base) var(--ease-out), visibility 0s linear var(--dur-base); }
.qr .qr-callbar.is-visible { visibility: visible; transition: transform var(--dur-base) var(--ease-out), visibility 0s; }
.qr .qr-callbar__btn { position: relative; padding-inline: var(--space-3); text-align: center; transition: transform var(--dur-fast) var(--ease-in-out); }
.qr .qr-callbar__btn::after { content: ""; position: absolute; inset: var(--ring-gap); border: var(--hairline) solid var(--text-inverse); opacity: 0; transform: scale(var(--ring-from)); transition: opacity var(--dur-base) var(--ease-in-out), transform var(--dur-base) var(--ease-in-out); pointer-events: none; }
.qr .qr-callbar__btn:active { transform: translateY(var(--press)); }
@media (hover: hover) and (pointer: fine) { .qr .qr-callbar__btn:hover::after { opacity: 1; transform: none; } }
.qr .qr-callbar__btn:focus-visible::after { opacity: 1; transform: none; }

/* =====================================================================
   4. The nine beats (round four added the proof strip; round five took one out)
   ===================================================================== */
/* hero: the photograph's frame oversized by --parallax-strength (hero-intro) */
.qr .qr-hero__media { inset: auto 0; top: calc(-100% * var(--parallax-strength)); height: calc(100% * (1 + var(--parallax-strength))); }
.qr .qr-hero__media img { height: 100%; object-position: 50% 40%; }
.qr .qr-hero__title { max-width: none; }
.qr .qr-hero .qr-eyebrow__text { transition: none; }
@media (max-width: 479.98px) { .qr .qr-hero__actions .qr-btn { flex: 1 1 100%; } }

/* the star, defined once in the page's sprite (round four): a rating's five stars in --line-soft, the same five in --accent laid over them
   and clipped to the rating's share of five (--stars-fill, set on the row: data, not motion) */
.qr .qr-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.qr .qr-stars { position: relative; display: inline-flex; flex: none; }
.qr .qr-stars__row { display: flex; color: var(--line-soft); }
.qr .qr-stars__row--fill { position: absolute; inset: 0 auto 0 0; width: var(--stars-fill); overflow: hidden; color: var(--accent); }
.qr .qr-stars svg { flex: none; width: var(--star-size); height: var(--star-size); fill: currentColor; }


/* the strip (round four; round six, 2026-10-29: the figures under the hero): a white band, a hairline at its top and its foot (drawn
   outward from the centre as it arrives; the foot one stands in for the Answer's top border). Four figures in the DS's stats row (About's
   "By the numbers"): two by two on a phone, one row of four from --bp-tablet, each figure at --fs-h2 and from --bp-nav at the DS's
   --fs-stat; Read the Reviews centred under them. A figure is a row of boxes one em tall, its digits and then its tail (the plus, or after
   4.9 an accent star at the cap line), so the odometer's columns (motion.js) take exactly the place of the digits they stand in for */
.qr .proof-strip { position: relative; padding-block: var(--space-7); background: var(--surface-page); }
.qr .proof-strip + .qr-section--warm { border-top-width: 0; }
.qr .proof-strip__rule { position: absolute; left: 0; right: 0; height: var(--hairline); background: var(--line-soft); transform-origin: 50% 50%; }
.qr .proof-strip__rule--top { top: 0; }
.qr .proof-strip__rule--foot { bottom: 0; }
.qr .proof-strip__row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6) var(--space-4); }
.qr .proof-strip .qr-stats-row__item { gap: var(--space-2); }
.qr .proof-strip__num { display: inline-flex; align-items: flex-start; font-size: var(--fs-h2); color: var(--text-primary); white-space: nowrap; }
.qr .proof-strip__num > [data-count], .qr .odo-cols { display: flex; }
.qr .proof-strip__tail, .qr .odo-char, .qr .odo-strip > span { display: block; height: 1em; line-height: var(--lh-display); }
.qr .proof-strip__star { width: var(--stat-star); height: var(--stat-star); margin: var(--stat-star-inset) 0 0 var(--stat-star-inset); fill: var(--accent); }
.qr .proof-strip .qr-stats-row__caption { color: var(--text-secondary); }
.qr .proof-strip__foot { display: flex; justify-content: center; margin-top: var(--space-5); }
/* the odometer (library/patterns/odometer.md): one column a digit, one em tall, its strip of faces moved by --d (motion.js tweens it) */
.qr .odo-col { height: 1em; overflow: visible; clip-path: inset(0 -0.25em); }   /* clips only top and bottom: the stat's -0.08em tracking lets each glyph run past its column, which overflow: hidden cut off */
.qr .odo-strip { display: flex; flex-direction: column; transform: translateY(calc(var(--d, 0) * -1em)); }
.qr .odo-strip > span { text-align: center; }
@media (min-width: 768px) {
  .qr .proof-strip { padding-block: var(--space-8); }
  .qr .proof-strip__row { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 1280px) { .qr .proof-strip__num { font-size: var(--fs-stat); } }

/* answer (round four): the DOM order is the heading, the eyebrow, the button, the statement, the paragraph in three beats. Under
   --bp-stage it all stacks, centred: the left box steps aside (display: contents) and the button shows last (order), so a phone reads
   the heading, the eyebrow, the statement, the beats, then the button. From --bp-stage a two-column grid, --space-9 apart, a measure each:
   the heading, the eyebrow and the button are one sticky box at the left while the statement and the beats scroll at the right (after
   the review: the heading alone was sticky and slid over a button below it). The statement and each beat ink with the scroll
   (scrubbed-word-ink); a hairline draws above each beat as it arrives */
.qr .answer-grid { display: grid; justify-items: center; gap: var(--space-5); text-align: center; }
.qr .answer-lead { display: contents; }
.qr .answer-lead .qr-eyebrow { max-width: var(--measure); }
.qr .answer-call { order: 1; }
.qr .answer-body { display: grid; justify-items: center; }
.qr .answer-statement { max-width: var(--measure); font-size: var(--fs-overview); line-height: var(--lh-snug); font-weight: var(--fw-medium); letter-spacing: var(--ls-heading); color: var(--text-primary); text-wrap: balance; }
.qr .answer-text { max-width: var(--measure); margin-top: var(--space-7); font-size: var(--fs-body); line-height: var(--lh-body); color: var(--text-primary); }
.qr .answer-beat { display: block; }
.qr .answer-beat + .answer-beat { margin-top: var(--space-5); font-size: var(--fs-lead); }
.qr .answer-beat__rule { display: block; height: var(--hairline); margin-bottom: var(--space-4); background: var(--line-soft); transform-origin: 0 50%; }
@media (min-width: 992px) {
  .qr .answer-grid { max-width: var(--answer-row-w); margin-inline: auto; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-areas: "lead body"; column-gap: var(--space-9); align-items: start; justify-items: start; text-align: left; }
  .qr .answer-lead { grid-area: lead; display: grid; justify-items: start; gap: var(--space-5); width: 100%; position: sticky; top: calc(var(--nav-h) + var(--space-6)); }
  .qr .answer-lead .qr-eyebrow__line:first-child { display: none; }
  .qr .answer-call { margin-top: var(--space-4); }
  .qr .answer-body { grid-area: body; justify-items: start; }
}

/* offices */
.qr .offices-title { max-width: 14em; margin-bottom: var(--space-8); }
.qr .qr-locations { grid-template-columns: minmax(0, 40rem); gap: var(--space-8); }
@media (min-width: 992px) { .qr .qr-locations { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-6); } }
@media (min-width: 1440px) { .qr .qr-locations { gap: var(--space-8); } }
.qr .qr-location { gap: var(--space-4); padding-top: var(--space-5); border-top: var(--hairline) solid var(--border-hairline); transition: border-color var(--dur-base) var(--ease-in-out); }
.qr .qr-location__details { display: grid; gap: var(--space-2); }
.qr .qr-location__office { font-weight: var(--fw-semibold); color: var(--text-primary); }
.qr .qr-location__address { max-width: 22em; }
/* round four: the rating line is itself the link (since round six, to the office's reviews on Google, in a new tab): the figure with its
   stars, then "Reviews on Google"; the figure and the words take the sliding underline on hover and focus. Then the license line, quiet,
   which ends the card (round five: the card's one other link is parked). Round five: the rating line takes the card's free space above it
   (margin-top: auto), so it and the license line sit at the card's foot and line up across the row whatever the addresses' lengths; the
   grid makes the cards as tall as the tallest, and stacked there is no free space, so nothing moves */
.qr .qr-location__rating { display: inline-grid; justify-items: start; row-gap: var(--space-2); align-self: flex-start; margin-top: auto; }
.qr .qr-location__score { display: inline-flex; align-items: center; gap: var(--space-3); }
.qr .qr-location__figure { font-size: var(--fs-h3); line-height: var(--lh-display); font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; color: var(--text-primary); }
.qr .qr-location__figure::after { bottom: 0; }
.qr .qr-location__count { font-size: var(--fs-small); line-height: var(--lh-snug); color: var(--text-secondary); }
.qr .qr-location__rating .qr-stars svg { width: var(--star-size-sm); height: var(--star-size-sm); }
@media (hover: hover) and (pointer: fine) { .qr .qr-location__rating:hover .u-line::after { transform: scaleX(1); transform-origin: 0 50%; } }
.qr .qr-location__rating:focus-visible .u-line::after { transform: scaleX(1); transform-origin: 0 50%; }
.qr .qr-location .qr-license { font-size: var(--fs-small); color: var(--text-secondary); }
/* round five: the license line stays on one line, its dash giving up the room (at 992px Rockwall's line was 13px longer than its card and
   wrapped; its dash is 19px there now and whole again from 1040px), so the three cards' foot blocks are the same height and line up across the row */
.qr .qr-location .qr-license > span { white-space: nowrap; }

/* steps: How It Works, rebuilt in round two as the live site has it, and the page's one signature. A still, full-screen video is held
   behind (sticky, no scrim: the words sit on the glass); the glass column scrolls up over it with the page, carrying the five steps.
   Nothing is pinned. The section is a flow root so the column's margins stay inside it. The held layer keeps its height in flow, so it
   stops at the section's end and leaves with it; the glass column pulls up over it by that height (round three: a negative bottom
   margin on the held layer, which did this before, let it run a full screen past the section, over Glen) */
.qr .qr-scroll-steps { display: flow-root; background: var(--surface-page); }
.qr .qr-scroll-steps__held { position: sticky; top: 0; z-index: var(--z-base); height: var(--steps-held-h); overflow: hidden; }
/* the still (round three): the box's background, the 854 file under --bp-tablet and the 1280 from it; the video, with no file until
   ui.js sets one, is transparent over it until it plays, so scripts off and reduced motion show the still */
.qr .qr-scroll-steps__media { background: var(--steps-still) center / cover no-repeat; }
.qr .qr-scroll-steps__media video { display: block; }
/* the video renders only once ui.js has wired it (its control loses hidden): with scripts off a browser draws a source-less video as a
   grey box with its own controls, over the still. Tied to ui.js, not to html.js, so a motion library that is slow or blocked never hides
   a video ui.js plays */
.qr .qr-scroll-steps__held:has(> .qr-scroll-steps__toggle[hidden]) .qr-scroll-steps__media video { display: none; }
/* the video's Pause control (WCAG 2.2.2): a DS square at the lower left, clear of the phone's toolbar and call bar */
.qr .qr-scroll-steps__toggle { position: absolute; left: var(--gutter); bottom: calc(100vh - 100svh + var(--space-6)); z-index: var(--z-content); display: flex; align-items: center; justify-content: center; width: 3.5rem; height: 3.5rem; padding: 0; background: var(--surface-page); border: var(--hairline) solid var(--ink-muted); color: var(--surface-dark); transition: background-color var(--dur-fast), border-color var(--dur-fast); }
.qr .qr-scroll-steps__toggle[hidden] { display: none; }
.qr .qr-scroll-steps__icon { width: 1.5rem; height: 1.5rem; }
.qr .qr-scroll-steps__icon--play, .qr .qr-scroll-steps__toggle.is-paused .qr-scroll-steps__icon--pause { display: none; }
.qr .qr-scroll-steps__toggle.is-paused .qr-scroll-steps__icon--play { display: block; }
@media (hover: hover) and (pointer: fine) { .qr .qr-scroll-steps__toggle:hover { border-color: var(--ink); background: var(--surface-tint); } }
.qr .qr-scroll-steps__toggle:focus-visible { border-color: var(--ink); background: var(--surface-tint); }
@media (max-width: 767.98px) { .qr .qr-scroll-steps__toggle { left: var(--space-3); bottom: calc(100vh - 100svh + var(--callbar-h) + var(--space-3)); width: var(--hit); height: var(--hit); } }
/* the glass column and its steps */
.qr .qr-scroll-steps__panel { position: relative; z-index: var(--z-content); width: var(--steps-col-w); margin: calc(var(--steps-col-margin) - var(--steps-held-h)) auto var(--steps-col-margin); padding: 0 0 var(--steps-col-pad); background: var(--steps-glass); border: var(--hairline) solid var(--steps-glass-line); -webkit-backdrop-filter: var(--blur-glass); backdrop-filter: var(--blur-glass); text-align: center; color: var(--surface-night); }
/* round four: the heading is a section heading, in flow at the column's top, the page's one size (the DS's ScrollSteps sets its own);
   the explainer under it, in the step lines' ink, within a measure; the column's top padding is now the step blocks' own */
.qr .qr-scroll-steps__head { padding: var(--steps-block-pad-y) var(--space-4) 0; }
@media (min-width: 768px) { .qr .qr-scroll-steps__head { padding-inline: var(--space-7); } }
.qr .qr-scroll-steps__heading { margin: 0; font-size: var(--fs-h2); line-height: var(--lh-heading); font-weight: var(--fw-semibold); letter-spacing: var(--ls-heading); color: var(--surface-night); }
.qr .qr-scroll-steps__intro { max-width: var(--measure); margin: var(--space-5) auto 0; font-size: var(--fs-body); line-height: var(--lh-body); font-weight: var(--fw-medium); color: var(--steps-line-ink); }
.qr .qr-scroll-steps__list { display: block; margin: 0; padding: 0; list-style: none; }
.qr .qr-scroll-steps__step { display: flex; flex-direction: column; align-items: center; gap: var(--steps-part-gap); width: min(var(--steps-block-w), 100%); margin-inline: auto; padding: var(--steps-block-pad-y) var(--steps-block-pad-x); }
.qr .qr-scroll-steps__num { margin: 0; font-size: var(--fs-step-label); line-height: var(--lh-display); font-weight: var(--fw-bold); letter-spacing: var(--ls-stat); text-transform: uppercase; font-variant-numeric: tabular-nums; color: var(--surface-night); }
.qr .qr-scroll-steps__title { margin: 0; font-size: var(--fs-step-title); line-height: var(--lh-snug); font-weight: var(--fw-semibold); color: var(--steps-title-ink); }
.qr .qr-scroll-steps__text { margin: 0; max-width: none; font-size: var(--fs-step-line); line-height: var(--lh-snug); font-weight: var(--fw-medium); color: var(--steps-line-ink); }
.qr .qr-scroll-steps__cta { display: flex; justify-content: center; padding-inline: var(--space-5); }

/* glen: the statement (a p since round four: a statement, not a heading), then the split; the photograph a clip reveal, then a deep plate.
   Every plate's photograph is oversized by its travel: --parallax-strength, or --parallax-deep where the frame says deep (round four) */
.qr .glen-statement { margin-bottom: var(--space-9); }
.qr .qr-feature__text { color: var(--text-primary); text-wrap: balance; }
[data-plate] img { position: absolute; left: 0; top: 0; width: 100%; height: calc(100% * (1 + var(--parallax-strength))); object-fit: cover; }
[data-plate="deep"] img { height: calc(100% * (1 + var(--parallax-deep))); }

/* proof (round four; round six, 2026-10-29: the carousel at every width). Under --bp-stage: the head; the hug photograph full
   width; the nine reviews in ui.js's track, each 85% of its width (--track-tile-w) and its own height, the track taking the height of the
   one in view (ui.js, .is-fit); the arrows and the bar; the links to each office's reviews on Google, stacked. From --bp-stage two
   columns, a third and two thirds: the hug as tall as the track beside it (its plate travels), two reviews in view and the next one's
   edge (--track-tile-w-wide), every review as tall as the tallest so the names line up; the arrows and the bar under the track and the
   links under the photograph. A mouse drags the track at every width */
.qr .proof-head { display: grid; justify-items: center; gap: var(--space-5); text-align: center; margin-bottom: var(--space-8); }
.qr .proof-head .qr-eyebrow { max-width: 40rem; }
.qr .proof-wall { display: grid; gap: var(--space-5); }
.qr .proof-wall__hug { aspect-ratio: var(--proof-photo-ratio); }
.qr .proof-wall__track { grid-auto-columns: var(--track-tile-w); gap: var(--space-4); }
/* round five, part two: under --bp-stage the track follows its content. Each tile is its own height (align-items: start), and ui.js sets
   the track's height to the tile in view's and adds .is-fit, which clips the taller tiles and eases the height (--dur-base, --ease-in-out;
   none under reduced motion). Scripts off: no class and no height, so the track keeps its natural height and nothing is clipped */
@media (max-width: 991.98px) {
  .qr .proof-wall__track { align-items: start; }
  .qr .proof-wall__track.is-fit { overflow-y: hidden; transition: height var(--dur-base) var(--ease-in-out); }
}
@media (max-width: 991.98px) and (prefers-reduced-motion: reduce) { .qr .proof-wall__track.is-fit { transition: none; } }
/* a review tile (the DS's ReviewCard): white on the warm ground in its hairline frame; the stars drawn above the quote, 5 of 5; the
   words as written, or shortened with an ellipsis; then the writer's first name, under a hairline, in the DS's small capitals */
.qr .proof-review { background: var(--surface-page); }
.qr .proof-review__stars { display: flex; }
.qr .proof-review .qr-review__quote { font-size: var(--fs-lead); line-height: var(--lh-body); font-weight: var(--fw-medium); color: var(--text-primary); }
.qr .proof-review .qr-review__name { padding-top: var(--space-4); border-top: var(--hairline) solid var(--line-soft); }
.qr .proof-wall__more { margin-top: 0; }
.qr .proof-wall__links { display: flex; flex-direction: column; align-items: flex-start; }
.qr .qr-reviews__controls { flex-wrap: wrap; }
.qr .qr-reviews__track.is-dragging { scroll-snap-type: none; user-select: none; cursor: grabbing; }
@media (hover: hover) and (pointer: fine) { .qr .qr-reviews__track { cursor: grab; } }
@media (min-width: 992px) {
  .qr .proof-wall { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); grid-template-areas: "hug track" "links more"; gap: var(--space-6) var(--space-5); align-items: start; }
  .qr .proof-wall__hug { grid-area: hug; align-self: stretch; aspect-ratio: auto; }
  .qr .proof-wall__track { grid-area: track; grid-auto-columns: var(--track-tile-w-wide); gap: var(--space-5); }
  .qr .proof-review .qr-review__quote { font-size: var(--fs-body); }
  .qr .proof-wall__more { grid-area: more; }
  .qr .proof-wall__links { grid-area: links; }
}

/* call: the DS's CallToAction. Round four: its title takes the page's one heading size (the DS sets --fs-h4 at 500) */
.qr .qr-cta__title { font-size: var(--fs-h2); line-height: var(--lh-heading); font-weight: var(--fw-semibold); letter-spacing: var(--ls-heading); }
.qr .qr-cta__text { max-width: 24em; }
.qr .qr-cta .qr-btn { min-height: 3.75rem; }
.qr .qr-cta .qr-btn__text { flex-direction: column; align-items: center; row-gap: var(--space-2); }
/* round three: the line under the three buttons, centred under them at every width; its number a link in white, the sliding underline
   over a resting line, with a 44px hit area */
.qr .qr-cta__note { margin-top: var(--space-3); font-size: var(--fs-small); line-height: var(--lh-body); color: var(--text-inverse-secondary); }
.qr .qr-cta__note-link { color: var(--text-inverse); white-space: nowrap; }

/* start: the DS's CtaForm; Submit sends nothing and shows its line (round five, below). The number in the sub line and in that line is underlined */
.qr .qr-form-card__sub a, .qr .start-sent__text a { text-decoration: underline; text-underline-offset: .15em; text-decoration-thickness: var(--hairline); white-space: nowrap; }
/* round three: What to Have Ready, in the card's intro column, so the list reads before the fields (beside them from --bp-stage). Items on
   their own lines, a quiet hairline between them, each marked with a small square in the DS's shape */
.qr .start-ready { display: grid; gap: var(--space-4); width: 100%; max-width: var(--measure); margin: var(--space-4) auto 0; text-align: left; }
.qr .start-ready__title { font-size: var(--fs-h4); line-height: var(--lh-snug); font-weight: var(--fw-semibold); letter-spacing: var(--ls-heading); color: var(--text-primary); }
.qr .start-ready__list { padding: 0; list-style: none; font-size: var(--fs-body); line-height: var(--lh-snug); color: var(--text-primary); }
.qr .start-ready__list li { display: flex; align-items: center; gap: var(--space-3); padding-block: var(--space-3); }
.qr .start-ready__list li + li { border-top: var(--hairline) solid var(--border-soft); }
.qr .start-ready__list li::before { content: ""; flex: none; width: var(--space-2); height: var(--space-2); background: var(--accent); }
.qr .start-ready__note { font-size: var(--fs-small); color: var(--text-secondary); }
/* round five, preview only: the line under Submit. The form has no backend here, so a submit shows it (ui.js removes its hidden; its wrapper is
   a polite live region, so it is announced; scripts off it stays hidden). It sits in the warm card, not on the section's dark ground, so it
   reads in --text-primary on --surface-alt, with its number a link (the page's 44px hit area, underlined as the sub line's is). It eases in
   on the reveal tokens, which collapse under reduced motion. No display is set on it, so its hidden holds */
.qr .start-sent__text { max-width: var(--measure); margin-top: var(--space-4); font-size: var(--fs-body); line-height: var(--lh-body); font-weight: var(--fw-medium); color: var(--text-primary); animation: start-sent-in var(--dur-slow) var(--ease-out); }
@keyframes start-sent-in { from { opacity: 0; transform: translateY(var(--reveal-distance)); } }
.qr .qr-fieldwrap .qr-select { margin-top: 0; }
.qr .qr-check { align-items: center; min-height: var(--hit); }
.qr .qr-check input { margin-top: 0; }
/* 6. Form fields: on focus the bottom border and the label turn --focus-ring; labels are always visible */
.qr .qr-field, .qr .qr-select { transition: min-height var(--dur-base) var(--ease-out), background-color var(--dur-fast), border-color var(--dur-fast), box-shadow var(--dur-fast); }
.qr .qr-field:focus, .qr .qr-field:focus-visible { border-color: transparent; border-bottom-color: var(--focus-ring); box-shadow: inset 0 calc(var(--hairline) * -1) 0 var(--focus-ring); }
.qr .qr-select:focus, .qr .qr-select:focus-visible { border-bottom-color: var(--focus-ring); box-shadow: inset 0 calc(var(--hairline) * -1) 0 var(--focus-ring); }
.qr .qr-form__label { transition: color var(--dur-fast); }
.qr .qr-fieldwrap:focus-within .qr-form__label { color: var(--focus-ring); }

/* =====================================================================
   5. Footer: the three tiles, the offices' lines, the bottom row
   ===================================================================== */
.qr .qr-footer__tile-line { display: block; }
.qr .qr-footer__brand-slogan { max-width: 22em; text-align: center; line-height: var(--lh-snug); }
.qr .qr-footer__bottom { padding-block: var(--space-7) var(--space-6); }
.qr .qr-footer__offices { display: grid; gap: var(--space-5); padding-bottom: var(--space-6); border-bottom: var(--hairline) solid var(--footer-rule); }
@media (min-width: 768px) { .qr .qr-footer__offices { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.qr .qr-footer__office { display: grid; gap: var(--space-1); }
/* round three: each office in two lines, the county, phone and license, then its rating (round five: no date beside it; round six:
   "Rated 4.9 out of 5 on Google", a link to the office's reviews, in a new tab, styled as the footer's other links) */
.qr .qr-footer__office-line { display: flex; flex-wrap: wrap; column-gap: var(--space-3); }
.qr .qr-footer__rating { font-size: var(--fs-small); }
.qr .qr-footer__office-name { font-weight: var(--fw-medium); color: var(--surface-tint); }
.qr .qr-footer__row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-6); padding-top: var(--space-5); }
.qr .qr-footer__links { gap: var(--space-2) var(--space-5); }
.qr .qr-footer__link { position: relative; padding: 0; color: var(--text-inverse-secondary); transition: color var(--dur-fast); }
.qr button.qr-footer__link { font-size: inherit; }
.qr .qr-footer__credit { margin-left: auto; font-weight: var(--fw-light); }
.qr .qr-footer__credit a { font-weight: var(--fw-semibold); color: var(--surface-tint); transition: color var(--dur-fast); }
@media (hover: hover) and (pointer: fine) {
  .qr .qr-footer__link:hover, .qr .qr-footer__office a:hover, .qr .qr-footer__credit a:hover { color: var(--text-inverse); }
}
.qr .qr-footer__link:focus-visible, .qr .qr-footer__office a:focus-visible, .qr .qr-footer__credit a:focus-visible { color: var(--text-inverse); }
.qr .qr-footer__office a { color: inherit; transition: color var(--dur-fast); }
@media (max-width: 767.98px) { .qr .qr-footer__bottom { padding-bottom: calc(var(--space-6) + var(--callbar-h)); } }
