/* =========================================================================
   CAPIERRE.COM — b_theme.css
   THE bi-chrome design layer for every PUBLIC page (homepage, FAQ, Gallery,
   Detailed Quote, the 8 service pages, Scheduled Services, Thank-You,
   Check-Email, Client login). Loaded AFTER css/styles.css, which keeps doing
   all structural work; this file only re-maps that sheet's design tokens and
   restyles its components.

   THE TWO CHROMATICS — nothing else is coloured:
     ORANGE  #FB4D1A (styles.css --sm-orange) = every action & accent:
             all buttons, all icon chips, headline rules, stars, markers.
     KLEIN   #002FA7 (styles.css --klein)     = emphasised TEXT only:
             headings, eyebrows, field labels. Plus the footer surface.
     Everything else is white / warm neutral.

   HARD RULES baked in here (owner, 2026-07-27) — do not reintroduce variants:
     · ONE button style. No ghost/outline secondary variant.
     · ONE page background (white). No alternating tinted section bands.
     · No inverted dark colour band mid-page. Dark = footer / call bar only.
     · EVERY block headline carries the same orange rule beneath it; every
       h2 carries the orange bar. Applied BY SELECTOR below so a block
       cannot exist without one.
     · Same element kind = same treatment, page-wide and site-wide.

   The homepage-only components (hero tile, fix-it quiz, compare sliders,
   gallery lightbox) live here too; their selectors simply do not match on
   the other pages. Page behaviours are in js/b_theme.js.

   Requires: body class="b-page" on the page. PRO dashboard/admin pages are
   deliberately NOT themed by this file.
   ========================================================================= */

  /* ---- 1 · PALETTE + TOKEN REMAP -------------------------------------- */
  body.b-page {
    /* PIN THE TWO CHROMATICS — html[data-theme="oil-rubbed-bronze"]
       (styles.css §skins, line ~1565) overwrites --sm-orange/--klein with
       bronze at the <html> level, so referencing them alone would render
       bronze. Re-declaring them here (same values as styles.css :root)
       restores the true brand hues for THIS page only. Tokens the skin
       flattens through var() chains at html level (--color-heading,
       --fx-orange, --color-success) are re-pointed too. */
    --sm-orange: #FB4D1A;        /* = styles.css :root --sm-orange      */
    --sm-orange-dark: #DD3D0E;   /* = styles.css :root --sm-orange-dark */
    --sm-gold: #FB4D1A;          /* gold slots follow the orange        */
    --sm-gold-dark: #DD3D0E;
    --klein: #002FA7;            /* = styles.css :root --klein          */
    --klein-deep: #001F7A;       /* = styles.css :root --klein-deep     */
    --color-heading: var(--klein);
    --fx-orange: var(--sm-orange);
    --color-success: var(--klein);
    --color-surface: #FFFFFF;

    /* BI-CHROME palette — Home-Depot-style orange + International Klein
       Blue, everything else neutral. The old multi-hue names below all
       resolve to one of the two chromatics so every component follows. */
    --b-ocean:      var(--klein);          /* Klein blue             */
    --b-ocean-deep: var(--klein);          /* headings               */
    --b-sand:       #FFFFFF;   /* page background — white            */
    --b-sand-2:     #F6F0E7;   /* warm tan band                      */
    --b-coral:      var(--sm-orange);      /* THE orange             */
    --b-coral-deep: var(--sm-orange-dark); /* orange pressed/hover   */
    --b-sun:        var(--sm-orange);      /* (was yellow) → orange  */
    --b-sun-deep:   var(--sm-orange-dark);
    --b-ink:        #333333;   /* charcoal body text — 12.63:1 on white, AAA */
    /* AAA PASS 2026-08-01 (owner pre-approved, public site only — the PRO
       dashboard is deliberately untouched). Was #6D665D = 5.66:1, under the
       7:1 AAA minimum for normal text. #5B5650 measures 7.26:1 and keeps the
       warm, blue-cast-free grey the palette calls for. */
    --b-muted:      #5B5650;   /* secondary text — 7.26:1 on white, AAA */
    /* Orange used as TEXT needs its own darker value: the brand orange
       #FB4D1A is 3.40:1 on white — fine as a non-text accent (3:1 rule:
       bullets, rules, borders, chip fills) but far under AAA for words.
       #9A2A05 = 7.76:1. Brand orange itself is unchanged. */
    --b-orange-text: #9A2A05;

    /* remap the shared styles.css tokens so EVERY existing component
       (header, buttons, cards, footer, call bar) tans along automatically */
    --color-navy:        var(--klein);
    --color-navy-deep:   var(--klein-deep);
    --color-navy-darker: var(--klein-deep);
    --color-amber:       var(--b-coral);
    --color-amber-dark:  var(--b-coral-deep);
    --color-teal:        var(--klein);
    --color-teal-dark:   var(--klein-deep);
    --color-gold:        var(--b-sun);
    --color-gold-dark:   var(--b-sun-deep);
    --color-ink:         var(--b-ink);
    --color-muted:       var(--b-muted);
    --color-line:        #EBD5C2;   /* the ONE tile/chip border          */
    --color-bg:          #FFFFFF;
    --color-bg-alt:      #FFFFFF;   /* alt sections match — ONE background page-wide */
    --color-star:        var(--b-sun-deep);
    --tint-line:         #E6C7AE;   /* the ONE input/choice border       */

    /* BUTTON FILL — the ONE place the button gradient is defined.
       Deliberately a shade darker than the brand orange: white text on
       --sm-orange (#FB4D1A) measures only 3.4:1, below the WCAG AA minimum of
       4.5:1 for text this size. These stops were chosen as the SMALLEST
       darkening that clears AA, so buttons stay visually close to the brand.
       Measured with white text — top stop is the lightest, so it is the
       worst case: base 4.75:1 / 5.97:1, hover 4.52:1 / 5.59:1. All pass.
       The brand orange itself is untouched everywhere else (icon chips,
       rules, stars) — those are large or non-text and not contrast-bound. */
    /* AAA PASS 2026-08-01 (owner pre-approved). These stops were previously
       tuned to the AA minimum (white text 4.75:1 / 5.97:1). AAA needs 7:1,
       and the arithmetic is unforgiving: even PURE BLACK on the brand orange
       #FB4D1A measures only 6.18:1, so no ink of any colour can pass AAA on
       brand orange — the fill itself has to darken. These clear it with
       white text: 7.39:1 / 8.54:1. Hover goes DARKER (was lighter) because
       any lighter stop drops back under 7. The brand orange is untouched
       everywhere it is non-text. */
    --b-btn-1:  #A02B06;   --b-btn-2:  #8F2704;   /* rest  — white text 7.39 / 8.54 */
    --b-btn-1h: #8F2704;   --b-btn-2h: #7F2103;   /* hover — white text 8.54 / 9.90 */
    --fx:        var(--sm-orange);
    --fx-soft:   #FF7A45;
    --fx-bright: #FFA57E;
    --fx-ink:    #4A1503;
    --band-orange: var(--sm-orange);
    --accent-stripe: linear-gradient(to bottom,
      var(--sm-orange) 0 5px,
      var(--klein)     5px 9px);

    /* friendlier type: rounded display face + a slightly larger, airier body */
    --font-head: "Poppins", "Segoe UI", Arial, sans-serif;   /* Baloo 2 is reserved for the H1 only */
    --fs-hero: clamp(1.9rem, 2.6vw + 0.9rem, 2.9rem);
    --fs-h2:   clamp(1.55rem, 2.2vw + 0.9rem, 2.35rem);
    --fs-h3:   clamp(1.05rem, 0.9vw + 0.8rem, 1.3rem);
    --fs-lead: clamp(0.98rem, 0.5vw + 0.85rem, 1.15rem);
    --fs-body: 0.95rem;
    --fs-small: 0.82rem;

    /* rounder, softer everything */
    --radius: 22px;
    --radius-sm: 14px;
    --shadow-sm: 0 2px 8px rgba(33, 30, 28, 0.10);
    --shadow-md: 0 10px 30px rgba(33, 30, 28, 0.14);
    --shadow-lg: 0 18px 55px rgba(33, 30, 28, 0.20);
    --tile-shadow: 0 8px 24px rgba(33, 30, 28, 0.13), 0 2px 6px rgba(33, 30, 28, 0.08);
    /* KEYBOARD FOCUS RING — rebuilt 2026-07-29 (accessibility bug).
       The old ring was 40%-transparent ORANGE, which is invisible against the
       orange hero tile and the orange buttons themselves: a keyboard visitor
       tabbing through the hero had no idea where they were. This ring is a
       white spacer plus a SOLID Klein outline, so it stays visible on all
       three surfaces the page actually has — white cards, the orange tile,
       and the Klein call bar. styles.css:157 applies it to :focus-visible
       globally, so this one token fixes every control on every b-page. */
    --ring: 0 0 0 3px #fff, 0 0 0 6px var(--klein);

    /* bigger, friendlier controls (styles.css sizes every pill from these) */
    --control-h: 46px;
    --control-pad-x: 1.5rem;
    --control-fs: 0.95rem;

    background: var(--b-sand);
    font-size: var(--fs-body);
    line-height: 1.7;
    color: var(--b-ink);
  }
  /* kill the browser's default BLUE tap-flash on buttons/links (mobile) */
  .b-page, .b-page * { -webkit-tap-highlight-color: transparent; }

  /* ---- 2 · BUTTONS: bigger, bouncier, sunnier ------------------------- */
  .b-page .btn { font-weight: 700; letter-spacing: 0.01em; }
  .b-page .btn:hover  { transform: translateY(-3px); box-shadow: 0 12px 26px rgba(221, 61, 14, 0.26); }
  .b-page .btn:active { transform: translateY(0) scale(0.97); box-shadow: 0 4px 10px rgba(221, 61, 14, 0.25); }
  /* ONE BUTTON STYLE, PERIOD (owner 2026-07-27): every pill button on the
     page — primary AND former "ghost" secondaries — is the same solid orange
     with white text. The 2px white border is part of the one style: it reads
     as nothing over white sections and separates the button on the orange
     hero tile, so no per-context variant exists. */
  /* The inset bevel pair matches the icon chips' machined edge (2026-08-01,
     owner: "uniformize buttons... same as icons effects scheme") — chips
     and buttons now share one lit-from-above treatment, so an orange pill
     and an orange chip read as the same material. Text stays WHITE: the
     requested blue-on-orange measures 2.25:1 against this fill, far under
     the 4.5:1 AA minimum, while white measures 4.75:1. */
  .b-page .btn--primary, .b-page .btn--ghost {
    background: linear-gradient(180deg, var(--b-btn-1), var(--b-btn-2));
    color: #fff; border: 2px solid #fff;
    box-shadow: inset 0 1.5px 0 rgba(255,255,255,0.45),
                inset 0 -2px 3px rgba(0,0,0,0.20),
                0 6px 16px rgba(221, 61, 14, 0.30);
  }
  .b-page .btn--primary:hover { background: linear-gradient(180deg, var(--b-btn-1h), var(--b-btn-2h)); border-color: #fff; color: #fff; }

  /* ====== TWO BUTTON STYLES · OWNER-AUTHORIZED 2026-07-29 ================
     SUPERSEDES the "ONE BUTTON STYLE, PERIOD" rule of 2026-07-27, by explicit
     owner authorization to make documented exceptions where they improve UX.

     WHY: with every action painted as the same solid orange pill, groups of
     actions had NO hierarchy — "Get in Touch" showed four identical pills,
     and the contact form ended with "Send Request" and "Add details" as
     visual twins. A visitor could not see which action was the intended one,
     which is exactly the moment a service business loses a lead.

     THE SYSTEM IS STILL CLOSED — there are exactly TWO styles, and the
     class name IS the role, site-wide, no per-context variants:
       .btn--primary  = solid orange. THE action of its group. One per group.
       .btn--ghost    = solid KLEIN BLUE. Every alternative path in the same
                        group. (RESKINNED 2026-08-01, owner: "use the blue as
                        an accent — use it for some buttons instead of the
                        white background inside the pills." The old white
                        fill read as inactive next to the orange primary;
                        blue makes the secondary a real, branded button while
                        keeping the primary/secondary hierarchy — the two
                        brand chromatics ARE the two roles now.)
     Defined ONCE here, so both roles stay identical everywhere they appear
     (hero quick row, Get in Touch, contact form, call bar, gallery CTA).
     .btn--ghost-dark (PRO/admin surfaces, §11 below) is a separate class and
     is deliberately NOT changed by this.
     Contrast, measured: white text on --klein #002FA7 = 8.6:1 and on
     --klein-deep #001F7A = 12.6:1 — both clear AA (4.5:1) and AAA (7:1).
     The 2px white border matches the primary's, so the pair reads as one
     button family on every surface (white sections, orange hero tile,
     orange call bar). */
  .b-page .btn--ghost {
    background: linear-gradient(180deg, var(--klein), var(--klein-deep));
    color: #fff; border: 2px solid #fff;
    box-shadow: 0 6px 16px rgba(0, 31, 122, 0.30);
  }
  /* Hover fixed 2026-08-01 (owner: "fix it to match the orange ones") — was
     a flat single-color drop (var(--klein)), while primary's hover is a
     LIGHTER two-stop gradient (--b-btn-1h/--b-btn-2h). color-mix derives
     the lighter blue stops from the same --klein/--klein-deep tokens
     rather than hardcoding two new hex values — matches primary's "a touch
     lighter" hover exactly, just in blue. */
  .b-page .btn--ghost:hover {
    background: linear-gradient(180deg,
      color-mix(in srgb, var(--klein) 88%, white),
      color-mix(in srgb, var(--klein-deep) 88%, white));
    color: #fff; border-color: #fff;
  }

  /* ---- 2c · SKIP LINK (accessibility, 2026-07-29) ----------------------
     The header carries ~15 nav links, so a keyboard or screen-reader visitor
     had to tab through all of them on every page load before reaching the
     content. Off-screen until focused, then it drops into the top-left. */
  .b-page .b-skip {
    position: absolute; left: 0.75rem; top: -100px; z-index: 200;
    background: #fff; color: var(--klein); font-weight: 700;
    padding: 0.7rem 1.1rem; border-radius: 0 0 var(--radius-sm) var(--radius-sm);
    border: 2px solid var(--sm-orange); box-shadow: var(--shadow-md);
    /* Deliberately NOT transitioned: a skip link must appear the instant it
       takes focus. Animating it in over 180ms means a keyboard visitor tabs
       once and sees nothing yet — the delay reads as "focus went nowhere". */
  }
  .b-page .b-skip:focus { top: 0; }

  /* ---- 3 · HEADER on cream -------------------------------------------- */
  .b-page .site-header { background: rgba(255, 255, 255, 0.94); }

  /* ---- 4 · HERO: animated SoCal-light gradient + decorations ---------- */
  .b-page .hero {
    position: relative;
    color: var(--b-ink);
    background: #fff;   /* white page — the orange lives on the contained tile */
    padding-block: 1.4rem 0.4rem;
  }
  /* the contained Home-Depot-style orange tile around the hero content —
     replaces the old full-bleed orange field (too harsh edge-to-edge) */
  .b-page .hero .hero-grid {
    position: relative;
    /* MUST be `clip`, never `hidden` (bug fixed 2026-07-29): `overflow:hidden`
       makes this tile a SCROLL CONTAINER, and the ::before decoration below
       (inset:-30%) overflows it by ~913px. Because #quoteSimple sits INSIDE
       this tile, clicking an in-page link like "Email us" scrolled THE TILE
       instead of the page — the hero content slid up inside its own clipped
       box and the wheel could never bring it back (window stayed at scrollY 0,
       so the page looked frozen mid-hero). `clip` gives identical visual
       clipping of the rounded corners but creates NO scroll container, so the
       tile can never be scrolled by anything. */
    overflow: clip;
    background: linear-gradient(160deg, #FC6B34 0%, var(--sm-orange) 45%, var(--sm-orange-dark) 100%);
    border-radius: clamp(22px, 3vw, 34px);
    padding: clamp(1rem, 1.8vw, 1.5rem);
    box-shadow: 0 16px 44px rgba(221, 61, 14, 0.22);
  }
  /* the white cards FILL the tile (owner 2026-07-27: no wide orange bands) —
     the base sheet caps the columns at 410/510px and centers them, leaving
     big orange side areas + an up-to-5rem orange gutter; fr tracks + a tight
     gap leave only the tile padding showing orange */
  @media (min-width: 720px) {
    .b-page .hero-grid { grid-template-columns: minmax(250px, 1fr) minmax(270px, 1.1fr); gap: clamp(1.1rem, 1.6vw, 1.6rem); }
    .b-page .hero-copy { max-width: none; }
    .b-page .hero .lead { max-width: 60ch; }
  }
  .b-page .hero .hero-grid > * { position: relative; z-index: 1; }
  /* soft drifting light inside the tile (the muted looping background —
     pure CSS, no video file, stops fully under reduced-motion) */
  .b-page .hero .hero-grid::before {
    content: ""; position: absolute; inset: -30%; z-index: 0; pointer-events: none;
    background:
      radial-gradient(40% 36% at 80% 16%, rgba(255, 255, 255, 0.28), transparent 70%),
      radial-gradient(52% 46% at 12% 90%, rgba(221, 61, 14, 0.50), transparent 75%);
  }
  @media (prefers-reduced-motion: no-preference) {
    .b-page .hero .hero-grid::before { animation: bSunDrift 16s ease-in-out infinite alternate; }
  }
  @keyframes bSunDrift { from { transform: translate3d(-2%, -1%, 0) scale(1); } to { transform: translate3d(2%, 2%, 0) scale(1.06); } }

  /* hero text now sits on LIGHT — override the dark-hero colors */
  /* eyebrows are ONE color everywhere — Klein, like every other heading kind
     (the base sheet flips hero/cta-band eyebrows to a second hue; undone) */
  .b-page .hero .eyebrow, .b-page .cta-band .eyebrow { color: var(--color-heading); text-shadow: none; }
  .b-page .hero h1 { color: var(--b-ocean-deep); font-size: var(--fs-hero); line-height: 1.16; font-family: "Baloo 2", var(--font-head); }
  .b-page .hero .lead { color: var(--b-muted); }
  /* the Quote·Call·Chat row is a direct grid child spanning the FULL tile
     width (owner request 2026-07-27) — three equal buttons, roomier gap */
  /* B-CHANGED 2026-07-30: hero quick-action row now shows visual hierarchy.
     Quote button (primary action) is larger; Call/Chat stay secondary size. */
  .b-page .hero-grid > .hero-quick { grid-column: 1 / -1; gap: 0.7rem; margin-bottom: 0.3rem; display: flex; align-items: center; justify-content: center; flex-wrap: wrap; }
  /* EQUAL WIDTH (2026-08-01, owner: "PILL ONE 'CALL', PILL TWO 'QUOTE',
     PILL THREE 'CHAT' — see what i mean?" — three pills sized to their own
     text/icon made "Call" and "Chat" visibly narrower than "Quote" even
     though all three carry equal weight as actions. One min-width, sized
     to the widest label (Quote + its icon), applied to all three so they
     render as one uniform row regardless of word length. Order is Call,
     Quote, Chat in the markup — see index.php/b_index.php. */
  .b-page .hero-quick > .btn { flex: 0 1 auto; min-width: 8.5rem; justify-content: center; }
  /* the padded tile eats ~80px of width, so the two-column hero starts at
     720px here instead of styles.css's 600px — between 600–719px the columns
     were squeezed to their 250/270px floors and everything wrapped badly */
  @media (min-width: 600px) and (max-width: 719px) {
    .b-page .hero-grid { grid-template-columns: 1fr; }
    .b-page .hero-copy { max-width: none; }
  }
  /* marker highlight behind "superhero" — a paintable stripe (the animation
     in the sophistication layer grows background-size 0% → 100%) */
  .b-page .hero h1 .b-hl {
    padding: 0 0.12em; border-radius: 8px;
    background-image: linear-gradient(rgba(251, 77, 26, 0.30), rgba(251, 77, 26, 0.30));
    background-repeat: no-repeat;
    background-size: 100% 42%;
    background-position: 0 68%;
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
  }

  /* the rounded glass card behind the headline (replaces .hero-scrim) */
  .b-hero-card {
    position: relative;
    background: rgba(255, 255, 255, 0.96);
    -webkit-backdrop-filter: blur(10px) saturate(140%);
    backdrop-filter: blur(10px) saturate(140%);
    border: 2px solid var(--color-line);
    border-radius: clamp(20px, 3vw, 30px);
    padding: 1.2rem 1.3rem 1.4rem;
    margin: 0.2rem 0 1.2rem;
    box-shadow: 0 16px 44px rgba(33, 30, 28, 0.16);
  }

  /* date pill — white glass instead of dark bronze */
  .b-page .hero-pill {
    background: rgba(255, 255, 255, 0.95);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border: 2px solid var(--color-line);
    color: var(--b-ink);
    box-shadow: 0 8px 22px rgba(33, 30, 28, 0.10);
  }
  .b-page .hero-pill-date { color: var(--b-ocean-deep); }
  /* ============ ONE HEADLINE RULE FOR EVERY BLOCK (owner 2026-07-27) ======
     "AN ORANGE LINE BELOW EACH HEADLINE PER BLOCK." Defined ONCE here and
     applied by selector to every block that carries a title, so a block
     cannot exist without its rule. Section headings (h2) already carry the
     centred orange bar from the sophistication layer — that is the same
     rule at section scale. */
  .b-page .hero-pill-date::after,        /* date card                      */
  .b-page .b-hero-card .eyebrow::after,  /* hero headline card             */
  .b-page .hero-box > h3::after,         /* Get in Touch · Contact Request */
  .b-page .b-rev-head::after,            /* What Neighbors Say (grid head) */
  .b-page .card h3::after,               /* service cards                  */
  .b-page .contact-tile h3::after,       /* contact tiles                  */
  .b-page .why-item h3::after,           /* Why Us items                   */
  .b-page .b-quiz-q::after,              /* quiz card                      */
  .b-page .site-footer h4::after,
  .b-page .site-footer .footer-h::after { /* footer columns (h2 since 2026-07-29) */
    content: ""; display: block; height: 3px; border-radius: 2px;
    /* width:100% is explicit because the generic ".b-page h2::after" rule
       below sets width:64px — the footer titles are h2 now, and without this
       declaration the 64px bar would win on the width property. */
    width: 100%;
    background: var(--sm-orange); margin: 0.5rem 0 0.75rem;
  }
  /* ====== CALL BAR · ORANGE (owner 2026-08-01: "background is orange —
     use the blue as an accent"). Was Klein (--color-navy-darker resolves to
     --klein-deep on b-page); now the same AA-measured dark-orange gradient
     the buttons use (--b-btn-1/--b-btn-2: white text 4.75:1 / 5.97:1).
     The primary keeps its orange fill (2px white border separates it, same
     precedent as the Quote pill on the orange hero tile) and the ghost
     phone pill is Klein — orange-primary / blue-secondary, like every other
     button group on the site. */
  .b-page .callbar {
    background: linear-gradient(180deg, var(--b-btn-1), var(--b-btn-2));
  }

  /* ====== FOOTER · MATCHES THE HEADER (owner 2026-08-01: "same look as the
     header, adjust content color accordingly"). Same translucent white
     glass + blur as .site-header (css/styles.css), not a dark band — so the
     page now opens and closes on the identical surface. Every footer text
     rule that assumed a dark bg (styles.css: white brand/headings, 78%-
     white body/links) gets its light-bg equivalent here; --b-ink/--b-muted
     are the SAME tokens the rest of the page's body text already uses, not
     new ones. */
  .b-page .site-footer {
    background: rgba(255,255,255,0.92);
    -webkit-backdrop-filter: saturate(180%) blur(10px);
    backdrop-filter: saturate(180%) blur(10px);
    color: var(--b-muted);
  }
  .b-page .site-footer .brand { color: var(--klein); }
  .b-page .site-footer h4,
  .b-page .site-footer .footer-h { color: var(--klein); }
  /* :not(.phone-pill) added 2026-08-01 fix — .phone-pill isn't tagged
     class="btn", so this rule (meant for plain footer text links) was ALSO
     matching it and overriding its white text with muted footer-gray —
     nearly unreadable on the pill's dark blue fill. */
  .b-page .site-footer a:not(.btn):not(.phone-pill) { color: var(--b-muted); }
  .b-page .site-footer a:not(.btn):not(.phone-pill):hover { color: var(--b-orange-text); }
  /* li > svg, not just svg (2026-08-01 fix): the bare descendant selector
     also caught the phone glyph INSIDE the .phone-pill anchor, painting it
     orange on the orange pill. The standalone mail/pin/help icons are
     direct children of their <li>; the pill's glyph is not — the child
     combinator separates them exactly. */
  .b-page .footer-contact li > svg { color: var(--sm-orange); }

  /* ====== AAA TEXT OVERRIDES (2026-08-01, owner pre-approved: "pass AAA
     for the entire site except the PRO zone"). Everything here re-points a
     shared-sheet rule that sets ORANGE AS TEXT — legal at AA, under the 7:1
     AAA floor. All are .b-page-scoped, so the PRO dashboard keeps its own
     treatment untouched, exactly as instructed. Measured values in each
     note; the brand orange itself is unchanged wherever it is non-text
     (bullets, rules, borders, chip fills — those need only 3:1 and pass). */
  /* --fx-soft #FF7A45 = 2.59:1 on white — the worst pair on the site. */
  .b-page .hero h1 .accent,
  .b-page .hero-trust .ht-num,
  .b-page .site-footer a:hover { color: var(--b-orange-text); text-shadow: none; }
  /* the required-marker asterisk carries meaning (which fields are
     mandatory), so it is text: 3.40 -> 7.76 */
  .b-page .required-marker { color: var(--b-orange-text); }
  /* matched substring inside the city autocomplete: 3.40 -> 7.76 */
  .b-page .ac-option strong { color: var(--b-orange-text); }
  /* inline FAQ/section links that rode --color-gold-dark */
  .b-page .section-head p a:not(.btn) { color: var(--b-orange-text); }

  /* TEXT-BEARING CHIPS. The icon chips hold a GLYPH (a graphic — 3:1 floor,
     and --fx-ink clears it at 3.39 worst-case, so they keep the bright
     brand gradient). These two hold NUMERALS, which are text and need 7:1 —
     the brand gradient tops out at 3.39 there, so they take the darkened
     button gradient with white ink: 7.39:1 / 8.54:1. Same machined bevel,
     so they still read as the same family. */
  .b-page .next-steps li::before,
  .b-page .wiz-dot.is-active {
    background: linear-gradient(155deg, var(--b-btn-1), var(--b-btn-2));
    color: #fff;
    box-shadow: inset 0 1.5px 0 rgba(255,255,255,0.45),
                inset 0 -2px 3px rgba(0,0,0,0.20),
                0 0 0 1px color-mix(in srgb, var(--b-btn-2) 70%, transparent),
                0 4px 14px color-mix(in srgb, var(--b-btn-2) 45%, transparent);
  }
  /* the orange rule under footer column titles already reads correctly on
     white (--sm-orange, set site-wide above) — no override needed here */
  .b-page .footer-bottom { border-top-color: var(--color-line); color: var(--b-muted); }
  .b-page .footer-bottom .license { color: var(--b-muted); }
  /* .phone-pill recoloured ORANGE 2026-08-01 (owner: "make it orange" —
     was blue via --color-navy = --klein on b-page). Fill + glow ring both
     switched to --sm-orange so they stay matched to each other (the
     glow-ring fix earlier that day was specifically about the ring
     matching whatever the pill's OWN fill is — that principle holds, the
     fill itself just changed color). */
  /* [data-theme] prefix is REQUIRED, not decorative (2026-08-01): the
     shared "every primary pill glows" rule in css/styles.css is written
     `[data-theme] .phone-pill:hover` and sets transform: translateY(1px)
     (a downward press). A plain `.b-page .phone-pill:hover` ties it on
     specificity (0,2,0) and LOSES on source order, so the pill looked
     completely dead on hover — pressing down instead of lifting, with the
     old --fx ring reasserted. Matching [data-theme] + .b-page (0,3,0)
     wins cleanly. */
  /* CONTRAST FIX 2026-08-01 (owner: "cannot read"). Two compounding bugs:
     (1) fill was raw --sm-orange #FB4D1A — the ONE orange this file
         documents as failing AA with text (white on it = 3.4:1). Now the
         --b-btn-1/--b-btn-2 gradient every other orange button uses, whose
         stops were chosen precisely so white text clears AA: 4.75:1.
     (2) `.site-footer a` (0,1,1) outranks `.phone-pill` (0,1,0), so inside
         the footer the pill's own `color:#fff` lost to the footer link
         colour — translucent 78% white, dragging it to ~2.6:1. The explicit
         colour below, at (0,3,0), settles it.
     `color` is repeated on the hover rule on purpose: `.site-footer a:hover`
     also exists and would otherwise recapture it mid-interaction. */
  /* EXACTLY the .b-page .btn--primary recipe, property for property
     (2026-08-01, owner: "the pill at the top is not to code" — my previous
     version invented its own ring/border variant instead of copying the
     button style verbatim). Only differences allowed: none. The [data-theme]
     prefix keeps (0,3,0) specificity so styles.css's [data-theme] pill-glow
     rule and .site-footer a can't recapture any property. */
  [data-theme] .b-page .phone-pill,
  .b-page .phone-pill {
    background: linear-gradient(180deg, var(--b-btn-1), var(--b-btn-2));
    color: #fff; border: 2px solid #fff;
    box-shadow: 0 6px 16px rgba(221, 61, 14, 0.30);
  }
  [data-theme] .b-page .phone-pill:hover,
  .b-page .phone-pill:hover {
    background: linear-gradient(180deg, var(--b-btn-1h), var(--b-btn-2h));
    border-color: #fff; color: #fff;
    box-shadow: 0 6px 16px rgba(221, 61, 14, 0.30);
    transform: none;
  }
  [data-theme] .b-page .phone-pill:active,
  .b-page .phone-pill:active { transform: translateY(1px); }

  /* "What happens next" step numbers (2026-08-01, owner: "why are the
     bullets... so plain") — this component never got the bichrome pass
     everyone else did: flat 24px --color-amber (= flat --sm-orange on
     b-page) disc, no depth, next to icon chips that are all gradient +
     glow. Same gradient as the buttons/footer/invoice band, same glow
     recipe as .phone-pill above, sized up to read at the same visual
     weight as the 34–40px icon chips elsewhere on the page. */
  /* Fill/glow lines removed 2026-08-01 — the paint now comes from the ONE
     unified chip recipe (styles.css [data-theme] block, which this size-up
     composes with). Only the sizing stays local. */
  .b-page .next-steps li::before { width: 28px; height: 28px; font-size: var(--fs-body); }

  /* the eyebrow is an inline span in the base sheet — block it so its rule
     spans the card instead of hugging the text */
  .b-page .b-hero-card .eyebrow { display: block; }
  /* the reviews head is a 2-column grid (title + "›") — span both columns */
  .b-page .b-rev-head::after { grid-column: 1 / -1; margin-bottom: 0.25rem; }
  /* the gallery dialog's head keeps its divider — recoloured to THE rule */
  .b-page .b-gal-head { border-bottom-color: var(--sm-orange); }
  .b-page .hero-pill-text { color: var(--b-muted); }

  /* B-NEW: benefit-focused core-service list with doodle icons.
     B-CHANGED 2026-07-29: each item now links to its service page (owner
     decision) — the <li> stays the visual box (flex + a light tan card, so
     the five lines read as distinct tappable rows instead of blurring
     together); the <a> inside is display:contents so it adds click/keyboard
     behaviour without becoming a second layout box. */
  .b-benefits { display: grid; gap: 0.55rem; margin-top: 1.1rem; list-style: none; }
  .b-benefits li { display: block; }
  /* The <a> IS the row (was `display: contents` — replaced 2026-07-29). Two
     reasons: `display: contents` on an interactive element has a history of
     dropping it out of the accessibility tree, and a link with no box of its
     own cannot show a focus ring. Now the whole row is one real hit target
     that keyboard focus can outline. */
  .b-benefits li > a {
    display: flex; align-items: flex-start; gap: 0.65rem;
    font-size: var(--fs-lead); line-height: 1.5; color: inherit; text-decoration: none;
    padding: 0.6rem 0.75rem; border-radius: var(--radius-sm);
    /* SURFACE UNIFICATION 2026-07-29: these rows were filled tan (--b-sand-2),
       which put FOUR different background values in the left column within
       ~400px (orange tile / white card / tan rows / white stat tiles). They
       now wear the SAME white + hairline-border treatment as the stat tiles
       directly below them, so the whole card reads as one family of tiles. */
    background: #fff; border: 2px solid var(--color-line);
    transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
  }
  .b-benefits li > a:hover {
    transform: translateY(-2px); border-color: var(--sm-orange); box-shadow: var(--shadow-sm);
  }
  .b-benefits strong { color: var(--b-ocean-deep); }
  /* color:#fff removed 2026-08-01 — same flattener cleanup as .b-page .icon
     above: glyph ink comes from the unified chip recipe (--fx-ink), so the
     doodles match the glossy look the owner pointed at. Its box-shadow is
     also gone — the recipe's bevel/ring/glow replaces it. */
  .b-doodle { flex: none; width: 30px; height: 30px; margin-top: 0.1rem; border-radius: 10px; display: grid; place-items: center; }
  .b-doodle svg { width: 17px; height: 17px; }
  /* the chips hold a Material Symbol since 2026-07-30 (the rows became
     editable, so the icon is now a name the owner types, not inline SVG).
     Sized to match the 17px SVG the chip was built around. */
  .b-doodle .material-symbols-outlined { font-size: 18px; line-height: 1; }
  /* COLOR-ROLE RULE (owner 2026-07-27): every icon chip on the page gets the
     SAME treatment — orange fill, white glyph. No alternation, no exceptions. */
  /* tone-class flat fills DELETED 2026-08-01 — .b-doodle now wears the ONE
     unified chip recipe (styles.css [data-theme] block), same as every
     other icon chip on the site. */

  /* B-NEW 2026-07-29: neighborhood trust badges under the lead paragraph —
     reuses .area-tag-link (defined in §5 below) so no new pill style exists
     for the same concept twice. */
  .b-neighbor-badges { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.7rem; }

  /* "See the transformations" — 2026-07-29: this is the hero's second-biggest
     action and the ONLY element sitting directly on the orange, but the base
     sheet centred it at content width, so it read as a small orphan pill after
     a tall white card. Full column width makes it look deliberate and gives it
     a hit target that matches its importance. */
  .b-page .hero .hero-actions { display: grid; grid-template-columns: 1fr; margin-top: 1.1rem; }

  /* Contact-form actions — 2026-07-29: the base sheet gives both buttons
     `flex: 1 1 45%`, i.e. equal width, which is half of why "Send Request" and
     "Add details" read as twins (the other half was the single button style,
     fixed in §2). Submitting is the goal, so it takes twice the width.
     KEYED BY POSITION, not color class (2026-08-01 fix) — this used to key
     off .btn--primary/.btn--ghost, so swapping which button had which COLOR
     (owner: "pill one blue, pill two orange") silently swapped the WIDTHS
     too. Send Request is always first in the markup and is always the goal
     regardless of what color it's wearing, so size now tracks position,
     color tracks color, and changing one can never again move the other. */
  .b-page .hero-form-actions > :first-child { flex: 2 1 58%; }
  .b-page .hero-form-actions > :last-child  { flex: 1 1 32%; }

  /* trust stats: staggered sunny cards + count-up numbers */
  /* The stat tiles need real width to read: measured max-content is 219px for
     the widest ("Thumbtack Since 2021"), 172/151/127 for the rest. Forcing 4
     across the hero's ~453px left column gave each only 103px, so labels
     broke onto 3 lines (owner 2026-07-27). Two-up is the default: it hands
     each tile ~220px, enough for even the widest label on ONE line.
     Four-up returns only when the CARD is genuinely wide enough (container
     query, because the width comes from the hero column, not the viewport).
     Explicit 2-or-4 — never auto-fit, which would produce a 3+1 orphan row. */
  .b-page .b-hero-card { container-type: inline-size; }
  .b-page .hero-trust {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.8rem; margin-top: 1.5rem; padding-top: 0; border-top: 0;
  }
  @container (min-width: 740px) {
    .b-page .hero-trust { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  }
  .b-page .hero-trust .ht-item {
    background: #fff; border: 2px solid var(--color-line); border-radius: 18px;
    padding: 0.75rem 0.3rem 0.65rem;
    box-shadow: 0 6px 16px rgba(33, 30, 28, 0.10);
    transition: transform var(--transition), box-shadow var(--transition);
  }
  .b-page .hero-trust .ht-num { color: var(--b-coral-deep); text-shadow: none; }
  .b-page .hero-trust .ht-label { color: var(--b-muted); }
  .b-page .hero-trust .ht-item:hover { transform: translateY(-3px); box-shadow: 0 12px 26px rgba(33, 30, 28, 0.16); }
  /* (the old max-width:599px 2-up rule is gone — 2-up is now the default) */

  /* right-column boxes: white, extra round, gentle hover lift */
  .b-page .hero-box {
    background: rgba(255, 255, 255, 0.97);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border: 2px solid var(--color-line);
    border-radius: 26px;
    box-shadow: 0 14px 40px rgba(33, 30, 28, 0.14);
    transition: transform var(--transition), box-shadow var(--transition);
  }
  .b-page .hero-box:hover { transform: translateY(-3px); box-shadow: 0 20px 48px rgba(33, 30, 28, 0.18); }
  .b-page .hero-review-thumb { background: var(--sm-orange); color: #fff; }
  .b-page .hero-review-stars { color: var(--b-orange-text); }
  /* review-carousel header: title left, "‹" & "›" nav controls right (grid);
     both controls are circular, 40×40, same button style as every other action
     on the page. Added 2026-07-30: both prev & next for symmetry & UX expectation. */
  .b-rev-head { display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 0.6rem; }
  .b-page .b-rev-prev, .b-page .b-rev-next { width: 40px; height: 40px; padding: 0; border-radius: 50%; font-size: 1.5rem; line-height: 1; }
  /* Flat bi-chrome: strip the bronze skin's glow/text-shadow effects */
  .b-page h1, .b-page h2, .b-page h3, .b-page .eyebrow { text-shadow: none; }
  /* Balanced heading wraps (2026-07-29): centred headings were breaking with
     a single orphaned word on the last line ("…figure it | out."). balance
     evens the lines; pretty does the same de-orphaning for the section
     intro paragraphs. Both degrade to normal wrapping in older browsers. */
  .b-page h1, .b-page h2, .b-page h3 { text-wrap: balance; }
  .b-page .section-head p, .b-page .hero .lead { text-wrap: pretty; }
  .b-page .hero h1, .b-page .hero .lead { text-shadow: none; }
  /* The skin paints the text below WHITE for its dark glass hero boxes
     (styles.css [data-theme] .hero-box--clear/--glass rules) — our boxes are
     white, so re-ink every piece for light surfaces. */
  .b-page .hero-box { color: var(--b-ink); }
  .b-page .hero-box h3 { color: var(--klein); }
  .b-page .hero-box .sub { color: var(--b-muted); }
  .b-page .hero-box .gt-text strong { color: var(--klein); }
  .b-page .hero-box .gt-text span { color: var(--b-muted); }
  .b-page .hero-box .hero-review p { color: var(--b-ink); }
  .b-page .hero-box .hero-review cite { color: var(--klein); }
  .b-page .hero-box .field label { color: var(--klein); }
  .b-page .hero-box .reply-promise { color: var(--b-muted); }
  /* thin neutral row dividers instead of the skin's thick gold ones */
  .b-page .hero-box .gt-row, .b-page .gt-row { border-top: 1px solid var(--color-line); }
  .b-page .hero-box .gt-row:first-of-type, .b-page .gt-row:first-of-type { border-top: 0; }

  /* ---- 5 · SHARED SECTIONS restyle ------------------------------------ */
  .b-page .trustbar { background: transparent; border-bottom: 0; }
  .b-page .trust-item {
    background: #fff; border: 2px solid var(--color-line); border-radius: 999px;
    padding: 0.5rem 1.1rem; color: var(--b-ocean-deep);
    box-shadow: 0 4px 12px rgba(33, 30, 28, 0.08);
  }
  .b-page .trust-item .trust-ico { color: var(--sm-orange); }

  .b-page .card { border-radius: 26px; border: 2px solid var(--color-line); }
  .b-page .card:hover { transform: translateY(-6px) rotate(-0.3deg); box-shadow: 0 20px 48px rgba(33, 30, 28, 0.18); border-color: var(--b-sun); }
  /* EVERY icon chip, wherever it sits. The base sheet only sizes ".card
     .icon", so the same chip used outside a card (service-page header,
     scheduled-services rows) would render as an unstyled transparent box —
     the full chip is defined here so one treatment covers all of them. */
  /* LAYOUT ONLY (2026-08-01, owner showed the glossy machined chip: "this
     is how I want my icons") — the background/color this rule used to set
     was the LAST flattener defeating the unified chip recipe (styles.css
     [data-theme] block) on public pages: solid --sm-orange + white glyph
     instead of the light→deep gradient + dark-ink glyph he pointed at.
     Paint now comes from the recipe alone, everywhere. */
  .b-page .icon {
    display: grid; place-items: center; width: 54px; height: 54px;
    border-radius: 16px;
  }
  .b-page .icon svg { width: 28px; height: 28px; }
  .b-page .icon .material-symbols-outlined { font-size: 28px; line-height: 1; }

  /* ONE SYSTEM TOP TO BOTTOM (owner 2026-07-27): no inverted color band
     mid-page — the Service Area is a normal light section with the exact
     same anatomy (eyebrow / h2+bar / sub) as every other section, and its
     chips speak the same white-pill language as the trust bar. */
  .b-page .section--alt, .b-page .cta-band { background: var(--color-bg-alt); color: var(--b-ink); }
  .b-page .cta-band h2 { color: var(--klein); }
  .b-page .cta-band p { color: var(--b-muted); }
  .b-page .area-tag-link {
    display: inline-block; background: #fff; border: 2px solid var(--color-line);
    color: var(--klein); border-radius: 999px; font-weight: 600;
    /* touch target raised again 2026-07-30: was 0.55rem (35px tall), still
       under 44px minimum. Now 0.8rem + tight line-height = exactly 44px
       tap-friendly pill, matching all other page controls (buttons, inputs). */
    padding: 0.8rem 1.2rem;
    box-shadow: 0 4px 12px rgba(33, 30, 28, 0.08);
    transition: transform var(--transition), border-color var(--transition), box-shadow var(--transition);
  }
  .b-page .area-tag-link:hover { border-color: var(--sm-orange); transform: translateY(-2px); box-shadow: 0 10px 22px rgba(33, 30, 28, 0.12); }
  /* Carried-over quiz answers, shown at the TOP of the Simple Contact
     Request (inc/quote_simple_form.php #hCarry). Deliberately quiet — it is
     reassurance that nothing was lost, not a second call to action, so it
     borrows the tile treatment already used by the benefit rows rather than
     introducing a new highlighted surface. */
  .b-page .b-carry {
    background: #fff; border: 2px solid var(--color-line);
    border-left: 4px solid var(--sm-orange);
    border-radius: var(--radius-sm); padding: 0.7rem 0.85rem; margin-bottom: 1rem;
  }
  .b-page .b-carry-title { font-family: var(--font-head); font-weight: 700; font-size: var(--fs-small);
    text-transform: uppercase; letter-spacing: 0.04em; color: var(--b-muted); margin: 0; }
  .b-page .b-carry-text { color: var(--klein); font-weight: 600; margin: 0.2rem 0 0; }
  .b-page .b-carry-edit { display: inline-block; margin-top: 0.35rem; font-size: var(--fs-small);
    font-weight: 600; color: var(--b-btn-2); }

  /* the one-line pointer above the area tags (see index.php #area) */
  .b-page .b-area-hint { text-align: center; color: var(--b-muted); font-size: var(--fs-small); font-weight: 600; margin: -0.4rem 0 0.8rem; }

  /* county group headings above each .area-tags block (2026-07-31, owner:
     "do one list LA COUNTY and OC COUNTY") — a second group needs its own
     label, or 127 pills read as one undifferentiated wall. */
  .b-page .area-county-head {
    text-align: center; font-family: var(--font-head); font-weight: 700;
    font-size: var(--fs-small); text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--klein); margin: 1.2rem 0 0.5rem;
  }
  .b-page .area-county-head:first-of-type { margin-top: 0.4rem; }

  /* partial star for the 4.6 rating summary (see index.php #reviews):
     a faint full star underneath, an orange copy on top clipped to
     --star-fill of its width. Sized by the same .stars svg rule below. */
  .b-page .b-star-part { position: relative; display: inline-block; line-height: 0; }
  .b-page .b-star-part .b-star-base { opacity: 0.25; }
  .b-page .b-star-part .b-star-over { position: absolute; inset: 0; clip-path: inset(0 calc(100% - var(--star-fill, 50%)) 0 0); }

  .b-page .review { border-radius: 24px; border: 2px solid var(--color-line); transition: transform var(--transition), box-shadow var(--transition); }
  .b-page .review:hover { transform: translateY(-4px); box-shadow: 0 14px 34px rgba(33, 30, 28, 0.14); }
  .b-page .review .avatar { background: var(--b-coral); color: #fff; }

  .b-page .contact-tile { border-radius: 24px; border: 2px solid var(--color-line); transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition); }
  /* a.contact-tile, NOT .contact-tile (2026-08-01 fix) — the base sheet
     correctly scopes this hover to real links only; this override didn't,
     so Service Area/Hours (real <div>s, not <a>s — see
     .contact-tile--static, they link nowhere) could still show a pointless
     lift on mouseover, a misleading affordance for content that isn't
     clickable. Owner: "totally static" — they're right that these two
     SHOULD look different from the clickable tiles, just not via a hover
     effect that promises a click does something. */
  a.contact-tile:hover { transform: translateY(-4px); border-color: var(--b-sun); box-shadow: 0 14px 34px rgba(33, 30, 28, 0.14); }
  /* resting-state depth for the non-clickable tiles, so they read as
     equally "designed" next to the clickable ones without faking
     interactivity they don't have */
  .b-page .contact-tile--static { box-shadow: var(--tile-shadow); }
  /* same orange-chip treatment as every other icon (base + skin paint these
     Klein-navy with an orange glyph — the exact incoherence being removed) */
  /* .ci-ico / .why-ico flat-orange overrides DELETED 2026-08-01 — they were
     silently defeating the unified chip recipe (styles.css, [data-theme]
     block). Every chip wears that ONE recipe now; nothing repaints here. */
  .b-page .contact-tile h3 { color: var(--klein); }

  .b-page .wizard-entry { background: #fff; border: 2px solid var(--color-line); border-radius: 26px; padding: 1.4rem 1.5rem; box-shadow: var(--tile-shadow); }

  /* ---- 6 · FORM: bigger, friendlier fields ---------------------------- */
  .b-page .field label { font-weight: 700; color: var(--b-ocean-deep); }
  .b-page .field input, .b-page .field select, .b-page .field textarea {
    font-size: 1.02rem; padding: 0.8rem 0.95rem;
    border: 2px solid var(--tint-line); border-radius: 14px;
    background: #FFFFFF; color: var(--b-ink);
    transition: border-color 0.18s ease, box-shadow 0.18s ease;
  }
  .b-page .field input:focus, .b-page .field select:focus, .b-page .field textarea:focus {
    outline: none; border-color: var(--b-coral); box-shadow: 0 0 0 4px rgba(251, 77, 26, 0.16);
  }
  /* plain text note — no one-off filled chip */
  .b-page .reply-promise { background: transparent; border: 0; padding: 0.2rem 0; color: var(--b-muted); }
  .b-form-hello { color: var(--b-muted); font-size: var(--fs-small); line-height: var(--lh-tight); margin: 0.2rem 0 var(--form-gap); }
  @media (prefers-reduced-motion: no-preference) {
    .b-page .b-cheer { animation: bCheer 0.7s ease; }
  }
  @keyframes bCheer { 0% { transform: scale(1); } 30% { transform: scale(1.02) rotate(0.4deg); } 60% { transform: scale(0.995); } 100% { transform: scale(1); } }

  /* ---- 7 · B-NEW COMPONENT: "What's broken?" quiz --------------------- */
  .b-quiz { max-width: 860px; margin: 0 auto; background: #fff; border: 2px solid var(--color-line); border-radius: 28px; padding: 1.5rem clamp(1rem, 3vw, 2rem) 1.7rem; box-shadow: var(--tile-shadow); }
  .b-quiz-dots { display: flex; justify-content: center; gap: 0.5rem; margin-bottom: 1.1rem; }
  .b-quiz-dot { width: 12px; height: 12px; border-radius: 50%; background: var(--color-line); transition: background var(--transition), transform var(--transition); }
  .b-quiz-dot.is-on { background: var(--b-coral); transform: scale(1.15); }
  .b-quiz-q { text-align: center; font-family: var(--font-head); font-weight: 700; font-size: var(--fs-h3); color: var(--b-ocean-deep); margin-bottom: 1rem; }
  .b-quiz-opts { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: 0.7rem; }
  /* Quiz options are CHOICE CHIPS, not inputs (restyled 2026-07-29): with the
     16px-radius rectangle + the same tan border the form fields use, they read
     as empty text inputs a visitor should type into. Full pill radius +
     centred text + the tile border puts them in the same "tap a chip"
     language as the area tags, which is what they are. */
  .b-quiz-opt {
    display: flex; align-items: center; justify-content: center; gap: 0.6rem; text-align: center;
    background: #FFFFFF; border: 2px solid var(--color-line); border-radius: 999px;
    padding: 0.8rem 1.1rem; font-size: 0.98rem; font-weight: 600; color: var(--klein);
    cursor: pointer;
    transition: transform var(--transition), border-color var(--transition), box-shadow var(--transition);
  }
  .b-quiz-opt:hover { transform: translateY(-3px); border-color: var(--b-coral); box-shadow: 0 10px 22px rgba(33, 30, 28, 0.12); }
  .b-quiz-nav { display: grid; grid-template-columns: auto 1fr; gap: 0.7rem; margin-top: 1.1rem; align-items: center; }
  .b-quiz-back { background: none; border: 0; color: var(--b-muted); font-size: var(--fs-small); font-weight: 600; justify-self: start; padding: 0.3rem 0.5rem; border-radius: 8px; }
  .b-quiz-back:hover { color: var(--b-coral-deep); }
  .b-quiz-result { text-align: center; }
  .b-quiz-summary { display: inline-block; font-weight: 700; color: var(--b-ocean-deep); margin: 0.6rem 0 1rem; }
  .b-quiz-actions { display: grid; grid-template-columns: minmax(0, 320px); justify-content: center; gap: 0.6rem; }

  /* ---- 8 · B-NEW COMPONENT: drag-to-compare job snapshots ------------- */
  .b-compare-grid { display: grid; gap: 1.4rem; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); max-width: 1020px; margin: 0 auto; }
  .b-ba { margin: 0; background: #fff; border: 2px solid var(--color-line); border-radius: 26px; padding: 0.8rem 0.8rem 0.4rem; box-shadow: var(--tile-shadow); }
  .b-ba-stage { position: relative; aspect-ratio: 16 / 10; border-radius: 18px; overflow: hidden; }
  .b-ba-stage:focus-within { box-shadow: var(--ring); }
  .b-ba-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
  .b-ba-top { clip-path: inset(0 0 0 var(--pos, 50%)); }
  .b-ba-line { position: absolute; top: 0; bottom: 0; left: var(--pos, 50%); width: 3px; background: #fff; box-shadow: 0 0 8px rgba(0, 0, 0, 0.45); transform: translateX(-50%); pointer-events: none; z-index: 2; }
  .b-ba-knob {
    position: absolute; top: 50%; left: var(--pos, 50%); transform: translate(-50%, -50%);
    width: 42px; height: 42px; border-radius: 50%; background: var(--b-coral); color: #fff;
    display: grid; place-items: center; font-weight: 800; font-size: 1.1rem;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35); pointer-events: none; z-index: 3;
  }
  .b-ba-range { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: ew-resize; margin: 0; z-index: 4; }
  .b-ba-tag { position: absolute; top: 10px; z-index: 2; background: rgba(33, 30, 28, 0.72); color: #fff; font-size: 0.78rem; font-weight: 700; padding: 0.25rem 0.75rem; border-radius: 999px; pointer-events: none; }
  .b-ba-tag--l { left: 10px; }
  .b-ba-tag--r { right: 10px; background: rgba(221, 61, 14, 0.88); }
  .b-ba figcaption { padding: 0.65rem 0.4rem 0.5rem; font-size: var(--fs-small); color: var(--b-muted); text-align: center; }
  .b-compare-cta { display: grid; grid-template-columns: minmax(0, 360px); justify-content: center; margin-top: 1.6rem; }

  /* ---- 9 · B-NEW COMPONENT: lightweight gallery lightbox -------------- */
  .b-page dialog.b-gal { border: 0; border-radius: 26px; padding: 0; width: min(980px, calc(100vw - 2rem)); max-height: calc(100vh - 3rem); background: var(--b-sand); box-shadow: 0 30px 90px rgba(0, 0, 0, 0.4); }
  .b-page dialog.b-gal::backdrop { background: rgba(20, 20, 20, 0.55); }
  .b-gal-head { position: sticky; top: 0; display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 1rem; padding: 0.9rem 1.2rem; background: var(--b-sand); border-bottom: 2px solid var(--color-line); z-index: 2; border-radius: 26px 26px 0 0; }
  .b-gal-head h3 { color: var(--b-ocean-deep); font-size: var(--fs-h3); }
  .b-gal-close { width: 40px; height: 40px; border-radius: 50%; border: 2px solid var(--color-line); background: #fff; color: var(--b-ink); font-size: 1.1rem; font-weight: 700; display: grid; place-items: center; transition: transform var(--transition), border-color var(--transition); }
  .b-gal-close:hover { transform: rotate(90deg); border-color: var(--b-coral); color: var(--b-coral-deep); }
  .b-gal-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(235px, 1fr)); gap: 0.9rem; padding: 1rem 1.2rem; }
  .b-gal-item { margin: 0; }
  .b-gal-item img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 16px; box-shadow: var(--shadow-sm); }
  .b-gal-item figcaption { font-size: var(--fs-small); color: var(--b-muted); padding: 0.35rem 0.2rem 0; }
  .b-gal-foot { padding: 0.4rem 1.2rem 1.2rem; display: grid; grid-template-columns: minmax(0, 340px); justify-content: center; }

  /* ---- 10 · scroll-reveal (JS-gated so content can never stay hidden) - */
  @media (prefers-reduced-motion: no-preference) {
    html.b-js .b-reveal { opacity: 0; transform: translateY(20px); transition: opacity 0.6s ease, transform 0.6s ease; }
    html.b-js .b-reveal.is-in { opacity: 1; transform: none; }
  }

  /* ---- 10b · SOPHISTICATION LAYER — refined effects & dynamic highlights.
     Every effect stays inside the color roles (orange accents only, neutral
     shadows) and every animation sits behind prefers-reduced-motion. ------- */
  /* text selection in the brand accent */
  .b-page ::selection { background: rgba(251, 77, 26, 0.25); }

  /* sticky header earns its shadow only once the page scrolls (JS toggle) */
  .b-page .site-header { transition: box-shadow 0.25s ease; }
  .b-page .site-header.b-scrolled { box-shadow: 0 6px 24px rgba(33, 30, 28, 0.12); }

  /* Every pill button: a light sheen sweeps across on hover (2026-08-01,
     owner: "fix it to match the orange ones" — ghost pills briefly had this
     removed to chase a "flash" report, but the real bug was the hover FILL
     being a flat single-color drop instead of the primary's lighter
     gradient, fixed above. With that fixed, ghost gets the identical sheen
     treatment again — one behavior, both roles, exactly the rule this
     file's header promises ("same element kind = same treatment"). */
  .b-page .btn--primary, .b-page .btn--ghost { position: relative; overflow: hidden; }
  .b-page .btn--primary::after, .b-page .btn--ghost::after {
    content: ""; position: absolute; top: 0; bottom: 0; left: -70%; width: 45%;
    background: linear-gradient(105deg, transparent, rgba(255, 255, 255, 0.38), transparent);
    transform: skewX(-18deg); pointer-events: none; transition: left 0.55s ease;
  }
  .b-page .btn--primary:hover::after, .b-page .btn--ghost:hover::after { left: 125%; }

  /* EVERY h2 in the page body draws the orange bar — selector deliberately
     scoped to "main h2", not ".section-head h2", so a heading that sits
     outside a section-head wrapper (the Why Us block) cannot escape it */
  .b-page h2::after {
    content: ""; display: block; width: 64px; height: 4px; border-radius: 2px;
    background: var(--sm-orange); margin: 0.55rem auto 0;
    transform: scaleX(1); transition: transform 0.55s ease 0.15s;
  }
  /* (the old left-aligned Why Us bar rule is gone — 2026-07-30 the Why Us
     title moved into the standard centred .section-head like every other
     section, so the default centred bar applies) */
  html.b-js .b-page .section-head.b-reveal:not(.is-in) h2::after { transform: scaleX(0); }

  /* icon chips answer their card's hover */
  .b-page .card .icon, .b-page .contact-tile .ci-ico { transition: transform var(--transition); }
  .b-page .card:hover .icon { transform: translateY(-4px) scale(1.06); }
  .b-page .contact-tile:hover .ci-ico { transform: scale(1.08); }

  /* gallery thumbnails ease in closer on hover */
  .b-gal-item { overflow: hidden; border-radius: 16px; }
  .b-gal-item img { transition: transform 0.5s ease; }
  .b-gal-item:hover img { transform: scale(1.04); }

  /* footer + inline links: underline slides in from the left */
  /* same guard: the sliding underline must never apply to a button */
  .b-page .footer-links a:not(.btn), .b-page .section-head p a:not(.btn) {
    background-image: linear-gradient(currentColor, currentColor);
    background-size: 0% 1.5px; background-repeat: no-repeat; background-position: 0 100%;
    transition: background-size 0.3s ease, color var(--transition);
  }
  .b-page .footer-links a:not(.btn):hover, .b-page .section-head p a:not(.btn):hover { background-size: 100% 1.5px; }

  /* "Booking now" live-status dot in the date card */
  .b-live-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%;
    background: var(--sm-orange); margin-right: 0.45rem; vertical-align: middle; position: relative; top: -1px; }

  @media (prefers-reduced-motion: no-preference) {
    /* the marker paints itself behind "superhero" shortly after load */
    html.b-js .b-page .hero h1 .b-hl { animation: bMarkerPaint 0.9s ease-out 0.6s both; }
    /* numbers pop once their count-up lands (JS adds .b-counted) */
    .b-page .b-counted { display: inline-block; animation: bPop 0.45s ease; }
    /* the compare knob pulses three times until first touched */
    html.b-js .b-page .b-ba:not(.b-touched) .b-ba-knob { animation: bKnobPulse 2.2s ease-out 1.2s 3; }
    /* live dot ping */
    html.b-js .b-live-dot { animation: bPing 2.4s ease-out infinite; }
    /* card grids cascade in with a slight stagger */
    html.b-js .b-page .cards .b-reveal:nth-child(2), html.b-js .b-page .reviews-grid .b-reveal:nth-child(2) { transition-delay: 0.08s; }
    html.b-js .b-page .cards .b-reveal:nth-child(3), html.b-js .b-page .reviews-grid .b-reveal:nth-child(3) { transition-delay: 0.16s; }
    html.b-js .b-page .cards .b-reveal:nth-child(4), html.b-js .b-page .reviews-grid .b-reveal:nth-child(4) { transition-delay: 0.24s; }
    html.b-js .b-page .cards .b-reveal:nth-child(5), html.b-js .b-page .reviews-grid .b-reveal:nth-child(5) { transition-delay: 0.32s; }
    html.b-js .b-page .cards .b-reveal:nth-child(6), html.b-js .b-page .reviews-grid .b-reveal:nth-child(6) { transition-delay: 0.40s; }
  }
  @keyframes bMarkerPaint { from { background-size: 0% 42%; } to { background-size: 100% 42%; } }
  @keyframes bPop { 0% { transform: scale(1); } 45% { transform: scale(1.12); } 100% { transform: scale(1); } }
  @keyframes bKnobPulse {
    0%   { box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35), 0 0 0 0 rgba(251, 77, 26, 0.45); }
    70%  { box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35), 0 0 0 14px rgba(251, 77, 26, 0); }
    100% { box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35), 0 0 0 0 rgba(251, 77, 26, 0); }
  }
  @keyframes bPing { 0% { box-shadow: 0 0 0 0 rgba(251, 77, 26, 0.40); } 60% { box-shadow: 0 0 0 9px rgba(251, 77, 26, 0); } 100% { box-shadow: 0 0 0 0 rgba(251, 77, 26, 0); } }

  /* ---- 11 · Live-chat flap → friendly floating bubble ------------------
     inc/tawk.php styles #kcoChat as a thin vertical edge flap; this heavier
     selector re-lays it out as a rounded chat bubble with a rotating message
     (the JS at the bottom of this file swaps the text). Same id, same popup. */
  body.b-page #kcoChat {
    writing-mode: horizontal-tb; text-orientation: initial;
    width: auto; height: auto; right: 16px; bottom: 120px;
    border-radius: 999px; padding: 0.75rem 1.2rem;
    display: inline-flex; align-items: center; gap: 0.5rem;
    font-size: 0.95rem; font-weight: 700;
    box-shadow: 0 10px 26px rgba(221, 61, 14, 0.35);
  }
  body.b-page #kcoChat .b-chat-msg { transition: opacity 0.2s ease; }
  body.b-page #kcoChat .b-chat-msg.is-swap { opacity: 0; }
  @media (max-width: 640px) { body.b-page #kcoChat { bottom: 92px; right: 10px; padding: 0.65rem 1rem; } }

  /* ---- 11b · floating "back to top" button (js/b_theme.js initBackToTop) --
     B-CHANGED 2026-07-30: moved to bottom-RIGHT (was left). Users expect
     "back to top" in the bottom-right corner — it's the web standard. Placing
     it in the bottom-left was non-standard and hurt discoverability. Same
     mobile clearance breakpoint (92px above the chat bubble). */
  .b-page .b-to-top {
    position: fixed; right: 16px; bottom: 120px; z-index: 90;
    width: 46px; height: 46px; border-radius: 50%;
    display: grid; place-items: center;
    background: linear-gradient(180deg, var(--b-btn-1), var(--b-btn-2));
    color: #fff; border: 2px solid #fff;
    box-shadow: 0 10px 26px rgba(221, 61, 14, 0.35);
    opacity: 0; transform: translateY(12px) scale(0.9); pointer-events: none;
    transition: opacity 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
  }
  .b-page .b-to-top.is-shown { opacity: 1; transform: none; pointer-events: auto; }
  .b-page .b-to-top:hover { box-shadow: 0 12px 28px rgba(221, 61, 14, 0.44); }
  .b-page .b-to-top svg { width: 20px; height: 20px; }
  @media (max-width: 640px) { .b-page .b-to-top { bottom: 92px; right: 10px; } }

  /* ======================================================================
     11 · SUB-PAGE COMPONENTS — FAQ · Gallery · Detailed Quote · the 8
     service pages · Scheduled Services · Thank-You · Check-Email.
     Those pages are built from .bill-head / .panel / .faq-* components
     instead of the homepage's hero + cards, so the SAME rules are extended
     to them here. Everything below is the same system, no new treatments.
     ====================================================================== */

  /* page headline blocks get THE bar, exactly like every section head */
  .b-page .bill-head h1::after,
  .b-page .faq-head h1::after,
  .b-page .ty-wrap h1::after {   /* thank-you + check-email confirmations */
    content: ""; display: block; width: 64px; height: 4px; border-radius: 2px;
    background: var(--sm-orange); margin: 0.55rem auto 0;
  }
  /* a panel's head is a compact flex row whose OWN border is its headline
     rule — recoloured to the orange, and the bar is suppressed there so it
     can never render as a stray block inside the flex row */
  .b-page .panel-head { border-bottom: 3px solid var(--sm-orange); }
  .b-page .panel-head h2::after { display: none; }
  .b-page .panel { border: 2px solid var(--color-line); border-radius: var(--radius); }

  /* FAQ: one tile treatment, and an open question rules off from its answer */
  .b-page .faq-item { border: 2px solid var(--color-line); border-radius: var(--radius); box-shadow: var(--shadow-sm); }
  .b-page .faq-item > summary { color: var(--klein); }
  .b-page .faq-item[open] > summary { border-bottom: 3px solid var(--sm-orange); }
  .b-page .faq-item > summary::before { border-right-color: var(--sm-orange); border-bottom-color: var(--sm-orange); }
  /* :not(.btn) is essential — the "Save as App" pill is an <a> INSIDE a FAQ
     answer, so a bare `a` colour rule outranked .btn--primary's white text and
     painted orange-on-orange (invisible until hover re-asserted white).
     Link-colour rules must never reach a button. */
  .b-page .faq-answer a:not(.btn) { color: var(--b-orange-text); font-weight: 600; }
  /* the page background is white now, so this block reads as a tile, not a tint */
  .b-page .faq-cta { background: #fff; border: 2px solid var(--color-line); }

  /* the one button style reaches the sub-pages' own variant too */
  .b-page .btn--ghost-dark {
    background: linear-gradient(180deg, var(--b-btn-1), var(--b-btn-2));
    color: #fff; border: 2px solid #fff;
    box-shadow: 0 6px 16px rgba(221, 61, 14, 0.30);
  }
  .b-page .btn--ghost-dark:hover { background: linear-gradient(180deg, var(--b-btn-1h), var(--b-btn-2h)); border-color: #fff; color: #fff; }
  .b-page .btn--ghost-dark::after {
    content: ""; position: absolute; top: 0; bottom: 0; left: -70%; width: 45%;
    background: linear-gradient(105deg, transparent, rgba(255, 255, 255, 0.38), transparent);
    transform: skewX(-18deg); pointer-events: none; transition: left 0.55s ease;
  }
  .b-page .btn--ghost-dark { position: relative; overflow: hidden; }
  .b-page .btn--ghost-dark:hover::after { left: 125%; }

  /* back-links + muted notes keep the page's two inks */
  .b-page .nav-back { color: var(--klein); }
  .b-page .nav-back:hover { color: var(--b-orange-text); }
  .b-page .hint, .b-page .muted { color: var(--b-muted); }
  /* gallery slideshow controls follow the action colour */
  .b-page .gal-dot .gal-fill { background: var(--sm-orange); }

  /* ======================================================================
     12 · SCHEDULED SERVICES — PLAN BUILDER (owner 2026-07-27)
     The per-card "Request this" button is gone: the WHOLE tile is now the
     control and toggles a service into the plan. Tiles keep the one card
     treatment — selection is shown by the action colour (orange border +
     tick), not by a different card style, so the system stays intact.
     ====================================================================== */
  /* PUBLIC pages carry .billing-page for layout, which also pulls in
     `.billing-page .card { padding: 0.65rem }` — the COMPACT padding meant for
     dense admin/billing tables. On a public marketing card that reads as
     cramped (measured 10.4px against the card system's 1.7rem). Restore the
     real card padding for public cards; scoped with .b-page so admin surfaces
     keep their compact spacing. */
  .b-page.billing-page .card { padding: 1.7rem; }

  .b-page .svc-pick {
    /* button reset, then inherit the shared .card look */
    font: inherit; color: inherit; text-align: left; width: 100%;
    display: flex; flex-direction: column; position: relative;
    cursor: pointer; background: var(--color-surface);
    /* padding comes from the .b-page.billing-page .card rule above (1.7rem),
       which is more specific — deliberately not repeated here */
    /* .card transitions box-shadow + border-color; those transitions kept the
       selected state from ever painting (measured 2026-07-27: background,
       which is NOT in the card's transition list, applied instantly while the
       transitioned properties stayed on their old values). Narrow the
       transition to transform so the selected state lands immediately. */
    transition: transform var(--transition);
  }
  .b-page .svc-pick:hover { transform: translateY(-6px); border-color: var(--sm-orange); }
  .b-page .svc-pick:focus-visible { outline: none; box-shadow: var(--ring); }

  /* the tick sits top-right, empty until picked — a visible affordance that
     the tile is selectable, which a plain card would not advertise */
  .b-page .svc-pick-mark {
    position: absolute; top: 0.9rem; right: 0.9rem; width: 26px; height: 26px;
    border: 2px solid var(--color-line); border-radius: 50%;
    display: grid; place-items: center; flex: none;
    transition: transform var(--transition);   /* see note above — colour changes must be instant */
  }
  .b-page .svc-pick-mark::after {
    content: ""; width: 11px; height: 6px; margin-top: -3px;
    border-left: 2.5px solid #fff; border-bottom: 2.5px solid #fff;
    transform: rotate(-45deg) scale(0.4); opacity: 0;
    transition: transform var(--transition), opacity var(--transition);
  }
  /* Selected state keys off the .is-picked CLASS (js adds it alongside
     aria-pressed). The attribute selector is kept as a companion so the state
     is still styled if the class is ever dropped. The ring is drawn with
     box-shadow rather than border-color so it cannot collide with the
     card's own border declaration. */
  .b-page .svc-pick.is-picked,
  .b-page .svc-pick[aria-pressed="true"] {
    border-color: var(--sm-orange);
    background: #FFF6F2;
    box-shadow: 0 0 0 3px var(--sm-orange), 0 10px 26px rgba(221, 61, 14, 0.20);
  }
  .b-page .svc-pick.is-picked .svc-pick-mark,
  .b-page .svc-pick[aria-pressed="true"] .svc-pick-mark { background: var(--sm-orange); border-color: var(--sm-orange); transform: scale(1.06); }
  .b-page .svc-pick.is-picked .svc-pick-mark::after,
  .b-page .svc-pick[aria-pressed="true"] .svc-pick-mark::after { transform: rotate(-45deg) scale(1); opacity: 1; }
  /* leave room for the tick so a long title never runs under it */
  .b-page .svc-pick h3 { padding-right: 2.2rem; }

  /* group headings: the page reads as a maintenance rhythm, not a menu */
  .b-page .svc-group { margin-top: clamp(1.6rem, 3vw, 2.6rem); }
  .b-page .svc-group-head { margin-bottom: 1.1rem; }
  .b-page .svc-group-head p { max-width: 60ch; margin-inline: auto; }

  /* sticky plan summary — only rendered once something is selected */
  .b-page .svc-planbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 95;
    background: rgba(255, 255, 255, 0.97);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    border-top: 3px solid var(--sm-orange);
    box-shadow: 0 -8px 28px rgba(33, 30, 28, 0.14);
    padding: 0.8rem 0;
  }
  .b-page .svc-planbar-inner { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: nowrap; }
  .b-page .svc-planbar-text { margin: 0; min-width: 0; color: var(--b-ink); }
  .b-page .svc-planbar-text strong { color: var(--klein); }
  .b-page .svc-planbar-actions { display: flex; align-items: center; gap: 0.9rem; flex: none; }
  /* Clear is a text control, NOT a second button — two identical orange pills
     side by side would leave the row with no hierarchy at all. */
  .b-page .svc-plan-clear {
    background: none; border: 0; padding: 0.3rem 0.2rem; cursor: pointer;
    font: inherit; font-weight: 600; color: var(--b-muted); text-decoration: underline;
    text-underline-offset: 3px;
  }
  .b-page .svc-plan-clear:hover { color: var(--b-orange-text); }
  /* keep the last row of cards clear of the fixed bar */
  .b-page.has-planbar { padding-bottom: 92px; }
  @media (max-width: 560px) {
    .b-page .svc-planbar-inner { flex-direction: column; align-items: stretch; gap: 0.6rem; text-align: center; }
    .b-page .svc-planbar-actions { justify-content: center; }
    .b-page.has-planbar { padding-bottom: 140px; }
  }

  /* ---- 13 · HEADER BREAKPOINT CORRECTION (regression fix 2026-07-27) ----
     The owner rule is ONE control size site-wide (no exceptions), so the
     enlarged control scale in this theme also applies to the header, making
     its content ~100px wider than the base sheet assumed. The wide-screen
     quick links (.nav-quick, 326px) therefore no longer fit at their base
     900px breakpoint: between 900 and 1023px they pushed the public
     hamburger past the viewport edge, where html{overflow-x:clip} silently
     CUT IT OFF — measured at 933px, the nav overflowed by 42px and
     #navToggle's right edge sat at 960px. The hamburger must be visible at
     ALL sizes (styles.css line 423), so the links yield, not the control.
     1040px is the first width where brand + links + CTA cluster all fit. */
  @media (max-width: 1039px) {
    .b-page .nav-quick { display: none; }
  }

  /* Narrow phones: at the enlarged control scale, brand (154px) + the full
     date string (145px) + hamburger (41px) exceed a 375px viewport by 4px,
     clipping the hamburger's right edge. The hamburger is a control and must
     always be reachable; the dateline is informational, so IT yields below
     420px (measured fit threshold ~394px, rounded up for other pages' brand
     widths). On the homepage the date also appears in the hero card, so
     nothing is lost there. flex:none pins the hamburger so no future header
     item can squeeze it. */
  @media (max-width: 419px) {
    .b-page .site-header .nav-date { display: none; }
  }
  .b-page #navToggle { flex: none; }
