/* ============================================================
       CSS CUSTOM PROPERTIES
    ============================================================ */
    :root {
      /* ── Colour (Phase 1 overhaul) ──────────────────────────────────────
         Brand OS: TWO colours — Wearzo Blue + Pure White. Tints of the blue
         are the ONLY permitted intermediate surfaces. The --blue-NN tokens
         are the canonical scale; the legacy names below them are aliases so
         2,000 lines of existing rules keep resolving. New rules use the
         --blue-NN names. White is the default canvas; saturated blue is
         punctuation — at most ONE full-bleed blue section per page, plus
         header and footer (asserted by tools/overhaul_check.py). */
      --blue:         #1A3A6B;   /* Wearzo Blue — the brand colour */
      --blue-05:      #F0F4F8;   /* 5% tint  — subtle section / chip fills */
      --blue-10:      #E8EBEF;   /* 10% tint — borders, stronger fills */
      --blue-90:      #122A52;   /* deep shade — footer depth, gradients */
      --blue-dark:    var(--blue-90);
      --blue-mid:     #1E4580;
      --blue-light:   #2A5298;
      --cream:        #FFFFFF;   /* Pure White — page & card surfaces */
      --cream-dark:   var(--blue-05);
      --cream-mid:    var(--blue-10);
      /* One elevation, one radius, one border colour (Phase 1 components).
         The old three-shadow ladder collapsed onto one card elevation; the
         -sm/-lg names survive as aliases. */
      --shadow:       0 6px 28px rgba(26,58,107,0.14);
      --shadow-sm:    var(--shadow);
      --shadow-lg:    var(--shadow);
      --radius:       12px;
      --radius-lg:    var(--radius);
      --border-c:     rgba(26,58,107,0.16);
      /* Motion policy: nothing beyond a 150ms hover transition. */
      --transition:   all 0.15s ease;
      /* 'Poppins Fallback' is a metric-matched local Arial — see the note
         at the foot of assets/fonts/poppins.css. It has to sit BETWEEN
         Poppins and the generic, so it is what renders during the swap
         window and nothing reflows when the real font lands. */
      --font-h:       'Poppins', 'Poppins Fallback', sans-serif;
      --font-b:       'Helvetica Neue', Helvetica, Arial, sans-serif;
      --w:            min(1200px, 92vw);


      /* ── Type scale (L-02) ──────────────────────────────────────────────
         34 font sizes collapsed onto 10 steps. The sizes were not a scale,
         they were 34 independent decisions: 0.92 / 0.93 / 0.94 / 0.95 / 0.96
         all appeared, differences invisible on their own and incoherent
         together. Every value moved by at most ~1px at a 16px root, so no
         single element changes noticeably — the page gains rhythm instead. */
      /* Phase 1 overhaul: 10 steps → 7 (brief §7 caps the scale at 7).
         The two sub-0.80rem steps merged up into --fs-xs — the reviewer's
         "elements too small" note argues for larger floors, not more of
         them — and --fs-base merged into --fs-md at 1rem. Old names are
         aliases; distinct values number exactly seven. Display steps are
         fluid via clamp(); text steps are fixed (clamping 13px text buys
         nothing). */
      --fs-xs:    0.80rem;                            /* floor — chips, eyebrows, hints */
      --fs-sm:    0.88rem;                            /* secondary text, buttons */
      --fs-md:    1.00rem;                            /* body prose */
      --fs-lg:    1.25rem;                            /* leads, sub-heads */
      --fs-xl:    clamp(1.35rem, 1.4rem + 0.6vw, 1.55rem);
      --fs-2xl:   clamp(1.70rem, 1.5rem + 1.0vw, 1.95rem);
      --fs-3xl:   clamp(2.40rem, 2.0rem + 1.8vw, 3.20rem);  /* display numerals */
      --fs-3xs:   var(--fs-xs);
      --fs-2xs:   var(--fs-xs);
      --fs-base:  var(--fs-md);

      /* ── Line-height (L-02) ─────────────────────────────────────────────
         18 values onto 4. The plan asked for 3; `--lh-none` is the fourth and
         it earns its place — a single-line display numeral or a wordmark wants
         exactly 1, and forcing 1.15 on them adds space that is simply wrong. */
      --lh-none:    1;
      --lh-tight:   1.15;    /* was 1.07 1.10 1.12 1.18 */
      --lh-snug:    1.45;    /* was 1.35 1.36 1.45 1.52 1.55 */
      --lh-relaxed: 1.70;    /* was 1.60 1.62 1.70 1.75 1.76 1.78 1.80 1.82 */

      /* ── Spacing scale (L-03) ───────────────────────────────────────────
         38 distinct px values onto 10, on a 4px base. 2px is kept as a real
         step: hairline gaps and dots are deliberate at that size and rounding
         them to 4px doubles them. */
      --sp-2:   2px;
      --sp-4:   4px;
      --sp-8:   8px;
      --sp-12: 12px;
      --sp-16: 16px;
      --sp-24: 24px;
      --sp-32: 32px;
      --sp-48: 48px;
      --sp-64: 64px;
      --sp-96: 96px;

      /* ── Section rhythm (Phase 1 overhaul) ──────────────────────────────
         ONE vertical rhythm, applied by one section wrapper: ~96px desktop /
         ~56px mobile (brief §7). The three-density system is gone — pages get
         shorter by having fewer sections, not tighter ones. The -lg/-sm names
         survive as aliases so nothing silently loses its padding, and the
         same-background collapse rule below still merges adjacent twins. */
      --space-section:    clamp(56px, 4.5vw + 20px, 96px);
      --space-section-lg: var(--space-section);
      --space-section-sm: var(--space-section);

      /* ── Measure (L-04) ─────────────────────────────────────────────────
         Three competing widths appeared inside a single section: .lead at
         580px, .prose at 78ch, and an inline max-width:820px. Two ch-based
         widths replace them, so the measure tracks the font rather than a
         pixel count that stops being right when the type scale moves. */
      --measure-prose: 68ch;
      --measure-lead:  56ch;

      /* ── Text-colour floors (WCAG 2.2 AA, 4.5:1) ───────────────────────────
         Secondary text is expressed as an alpha over the section background,
         which makes it easy to pick a value that looks right and fails the
         contrast floor — seven tokens had done exactly that. These are the
         LOWEST alphas that still clear 4.5:1 against their real backgrounds,
         measured, not estimated:

           --ink-muted   blue @78%  on #FFFFFF  = 5.90:1   (on #F0F4F8 = 5.55:1)
           --ink-soft    blue @82%  on #FFFFFF  = 6.85:1
           --on-blue-muted   white @72% on #1A3A6B = 7.06:1 (on #122A52 = 8.89:1)

         Do not lower these. Anything genuinely decorative (the .why-c
         watermark numeral, the '›' breadcrumb separator) is aria-hidden and is
         deliberately not expressed with these tokens. */
      --ink-muted:      rgba(26,58,107,0.78);
      --ink-soft:       rgba(26,58,107,0.82);
      --on-blue-muted:  rgba(255,255,255,0.72);
    }

    /* ============================================================
       RESET
    ============================================================ */
    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
    html { scroll-behavior: smooth; font-size: 16px; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
    /* L-07: `html, body { overflow-x: hidden }` was removed in Phase 3. It made
       every future overflow bug silent — a stray 18px of horizontal scroll from
       an off-screen honeypot was once found only because someone measured — and
       it disables `position: sticky` in every descendant. Overflow is now
       asserted instead of hidden: the verification sweep checks
       320/375/414/768/900/1024/1280/1440 and fails on any horizontal scroll. */
    body { font-family: var(--font-b); background: var(--cream); color: var(--blue); }
    img { max-width: 100%; height: auto; display: block; }
    a { text-decoration: none; color: inherit; }
    ul { list-style: none; }
    button { cursor: pointer; font-family: inherit; }

    /* ============================================================
       UTILITIES
    ============================================================ */
    .c  { width: var(--w); margin-inline: auto; }
    .section { padding-block: var(--space-section); }
    /* Density variants. A page is not a uniform stack: a hero-adjacent block
       wants air, a related-links or chip row does not. */
    .section--lg { padding-block: var(--space-section-lg); }
    .section--sm { padding-block: var(--space-section-sm); }
    /* Phase 11 (L-09): a section whose content is nothing but measure-capped
       text used to pin that text to the left edge of the 1200px container and
       leave the right half of the screen empty. The template marks such
       sections (see page.html.j2) and they get a centred editorial column
       instead. Text inside stays left-aligned; only the column is centred. */
    .section--narrow .c { max-width: min(880px, 92vw); }

    /* Same-background neighbours collapse to ONE padding instead of stacking
       two. Two consecutive cream sections used to put 160px between their
       content with no visible boundary to justify it — the eye reads them as
       one block, so they should be spaced as one. Where the background DOES
       change, the full pair stays: that gap is doing work.

       :is() keeps this to four rules instead of sixteen. */
    .section--cream   + .section--cream,
    .section--cream-d + .section--cream-d,
    .section--cream-m + .section--cream-m,
    .section--blue    + .section--blue { padding-top: 0; }
    .section--blue  { background: var(--blue);      color: var(--cream); }
    .section--cream { background: var(--cream); }
    .section--cream-d { background: var(--cream-dark); }
    .section--cream-m { background: var(--cream-mid); }
    .ta-center { text-align: center; }

    .tag {
      font-family: var(--font-h); font-size: var(--fs-3xs); font-weight: 700;
      letter-spacing: 0.18em; text-transform: uppercase;
      display: inline-block; padding: var(--sp-8) var(--sp-16); border-radius: 100px;
      background: var(--cream-dark); color: var(--blue); margin-bottom: var(--sp-12);
    }
    .tag-cta {
      background: var(--blue); color: var(--cream);
      box-shadow: 0 8px 24px rgba(26,58,107,0.2);
      border: 1px solid rgba(255,255,255,0.18);
    }
    .section--blue .tag { background: rgba(255,255,255,0.12); color: rgba(255,255,255,0.85); }

    .h2 {
      font-family: var(--font-h); font-size: clamp(1.75rem,3.4vw,2.75rem);
      font-weight: 800; line-height: var(--lh-tight); margin-bottom: var(--sp-12);
    }
    /* opacity 0.72 measured 4.47:1 on the 10% blue tint (`section--cream-m`) —
       under the 4.5:1 floor, and the one accessibility failure left on four
       pages. 0.78 clears every surface `.lead` actually lands on:

         blue text  on #FFFFFF 5.92 · on #F0F4F8 5.53 · on #E8EBEF 5.27
         white text on #1A3A6B 7.56 · on #122A52 9.17

       `opacity` rather than a colour token is deliberate here: `.lead` is used
       on light AND blue sections and has to darken or lighten with whatever it
       inherits. That is also why the contrast gate never caught this — it read
       rgba() tokens and could not see an opacity. It now checks both. */
    .lead {
      font-size: clamp(0.98rem,1.5vw,1.08rem); line-height: var(--lh-relaxed);
      opacity: 0.78; max-width: var(--measure-lead);
    }
    .ta-center .lead { margin-inline: auto; }
    /* L-05: intros are left-aligned by default. `.lead` is measure-capped,
       so a left intro keeps a readable line length instead of stretching. */
    .sec-intro { margin-bottom: var(--sp-32); }
    .sec-intro .lead { margin-inline: 0; }


    /* ── Layout utilities (ARCH-02 / L-03) ───────────────────────────────────
       These replace 602 of the 739 inline `style=` attributes the migrated
       pages carried. Each one was a presentational decision copy-pasted across
       up to 147 places, so a single change meant 147 edits and drift was
       guaranteed — the three `.split` gaps were already 32px, 28px and 12px
       for no reason anyone could state.

       What deliberately STAYS inline: the colour on a swatch chip. That is the
       product's actual colour — data, not styling — and hoisting it into a
       class would mean a class per colour. */
    .split {
      display: flex; flex-wrap: wrap; gap: var(--sp-32); align-items: flex-start;
    }
    .split-col   { flex: 1 1 300px; }
    .split-col--380 { max-width: 380px; flex-basis: 260px; }
    .split-col--440 { max-width: 440px; }
    .split-col--560 { max-width: 560px; flex-basis: 320px; }
    .split-fixed { flex: 0 0 auto; }

    .chip-row {
      display: flex; flex-wrap: wrap; gap: var(--sp-12); margin-top: var(--sp-16);
    }
    .btn-row-center { justify-content: center; margin-top: var(--sp-8); }

    /* L-03 / 3.3: `max-width:820px` was a prose-measure decision copy-pasted
       inline. It is one decision, so it is one class — and it now tracks the
       type scale rather than a fixed pixel count. */
    .measure { max-width: var(--measure-prose); }

    .mt-16 { margin-top: var(--sp-16); }
    .mt-24 { margin-top: var(--sp-24); }
    .mt-48 { margin-top: var(--sp-48); }
    .lh-snug { line-height: var(--lh-snug); }
    .txt-em { font-style: italic; }
    .link-u { color: inherit; text-decoration: underline; }
    .cap-note {
      margin: var(--sp-12) 0 0; color: var(--blue);
      font-weight: 600; font-size: var(--fs-sm);
    }

    .note-em { margin-top: var(--sp-16); font-style: italic; color: var(--blue); }
    .link-strong { text-decoration: underline; font-weight: 700; }
    .txt-sm { font-weight: 500; font-size: var(--fs-xs); }

    .img-framed {
      width: 100%; height: auto;
      border: 1px solid var(--border-c);
      border-radius: var(--radius); background: var(--cream);
    }
    .img-square {
      width: 200px; height: 200px; object-fit: cover;
      border: 1px solid var(--border-c); border-radius: var(--radius);
    }

    /* ── Image slots (Phase 1 overhaul, brief §7) ─────────────────────────
       Photography leads; copy supports. One ratio per slot type, cover-fit,
       one border, one radius. Sizes are set to what the ASSETS can honestly
       carry (AUDIT.md §8): garment photos are 667×1000/1000×800, fabric
       macros are 400×400 native — a slot larger than its source upscales,
       which is worse than smaller-but-crisp.
         slot-hero    product hero shot — ≥480px tall on desktop
         slot-fabric  fabric macro — 1:1 at native 400px, down to 280px
         slot-context factory / people shot — 4:5
         (logo tiles are .cl-card, below with the client grid)              */
    .slot-hero {
      width: 100%; aspect-ratio: 2 / 3; min-height: 480px; max-height: 640px;
      object-fit: cover; object-position: top center;
      border: 1px solid var(--border-c); border-radius: var(--radius);
      background: var(--cream);
    }
    .slot-hero--wide { aspect-ratio: 5 / 4; min-height: 480px; }
    .slot-fabric {
      width: min(400px, 100%); aspect-ratio: 1 / 1; object-fit: cover;
      border: 1px solid var(--border-c); border-radius: var(--radius);
    }
    .slot-context {
      width: 100%; aspect-ratio: 4 / 5; object-fit: cover;
      border: 1px solid var(--border-c); border-radius: var(--radius);
    }
    @media (max-width: 900px) {
      .slot-hero, .slot-hero--wide { min-height: 0; max-height: 70vh; }
    }

    /* ── /styleguide/ only ────────────────────────────────────────────────
       Presentation for the design-system page. Kept here rather than inlined
       in the spec so the styleguide is built from the same stylesheet it
       documents — if a token changes, the page showing that token changes
       with it. ~40 lines on a noindex page nobody but us loads. */
    .sg-swatches { display: grid; gap: var(--sp-16); grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); margin-top: var(--sp-24); }
    .sg-swatch { font-size: var(--fs-sm); line-height: var(--lh-snug); }
    .sg-chip { display: block; height: 72px; border-radius: var(--radius); margin-bottom: var(--sp-8); }
    .sg-type { margin-top: var(--sp-24); }
    .sg-row { display: flex; align-items: baseline; gap: var(--sp-16); flex-wrap: wrap; padding: var(--sp-8) 0; border-bottom: 1px solid var(--border-c); }
    .sg-label { font-family: var(--font-h); font-size: var(--fs-xs); font-weight: 700; color: var(--ink-muted); min-width: 90px; }
    /* Demo surface for components that only exist on blue. */
    .sg-on-blue { background: var(--blue); border-radius: var(--radius); padding: var(--sp-24); margin-top: var(--sp-16); }
    .sg-layout { display: grid; gap: var(--sp-32); margin-top: var(--sp-24); }
    .sg-demo { display: grid; gap: var(--sp-8); }
    .sg-box { background: var(--blue-05); border: 1px dashed var(--border-c); border-radius: var(--radius); padding: var(--sp-24) var(--sp-16); text-align: center; font-size: var(--fs-sm); }
    .sg-split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-24); }
    .sg-grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-16); }
    @media (max-width: 640px) {
      .sg-split, .sg-grid3 { grid-template-columns: 1fr; }
    }

    .swatch-item {
      display: inline-flex; align-items: center; gap: var(--sp-8);
      font-size: var(--fs-sm);
    }
    /* A11Y-06, resolved in Phase 9. The text-alternative half of the finding
       was already satisfied — every chip has its colour NAME as visible text
       immediately beside it ("White", "Sky Blue"), so the chip is decorative
       and correctly invisible to a screen reader.

       What was left is the visual half: 22px is small to judge a colour by,
       which matters most to the low-vision readers who need the swatch to do
       real work. 28px, and the border darkened so a pale shade still reads as
       a swatch against the cream card rather than dissolving into it. */
    .swatch-chip {
      width: 28px; height: 28px; border-radius: 6px;
      border: 1px solid rgba(26,58,107,0.32);
      flex-shrink: 0;
    }

    /* ============================================================
       SCROLL REVEAL — RETIRED (Phase 1 overhaul)
    ============================================================ */
    /* The motion policy is now "nothing beyond a 150ms hover transition"
       (brief §7). Content is simply present; it does not enter. The data-r /
       data-rl attributes remain in templates and wearzo.js still toggles
       .on — both are inert, so no template or JS edit was needed and nothing
       can flash-hide if JS fails. */
    [data-r], [data-rl] { opacity: 1; transform: none; }

    /* ============================================================
       BUTTONS
    ============================================================ */
    .btn {
      display: inline-flex; align-items: center; gap: var(--sp-8);
      font-family: var(--font-h); font-size: var(--fs-sm); font-weight: 700;
      padding: var(--sp-12) var(--sp-32); border-radius: 8px; border: 2px solid transparent;
      transition: var(--transition); white-space: nowrap; cursor: pointer;
    }
    .btn-solid {
      background: var(--cream); color: var(--blue); border-color: var(--cream);
    }
    .btn-solid:hover { background: var(--cream-dark); transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0,0,0,0.18); }
    .btn-outline-cream {
      background: transparent; color: var(--cream); border-color: rgba(255,255,255,0.38);
    }
    .btn-outline-cream:hover { border-color: var(--cream); background: rgba(255,255,255,0.08); }
    .btn-blue {
      background: var(--blue); color: var(--cream); border-color: var(--blue);
    }
    .btn-blue:hover { background: var(--blue-dark); transform: translateY(-2px); box-shadow: var(--shadow); }
    /* The light-background counterpart to .btn-outline-cream. `.btn-outline`
       was being applied in two places without ever being defined, so those
       buttons inherited `.btn`'s transparent background AND transparent
       border — bare text sitting next to a fully-styled solid button. */
    .btn-outline-blue {
      background: transparent; color: var(--blue); border-color: rgba(26,58,107,0.32);
    }
    .btn-outline-blue:hover {
      border-color: var(--blue); background: var(--cream-dark); transform: translateY(-2px);
    }
    .btn svg { flex-shrink: 0; width: 16px; height: 16px; }
    /* File size on a download button. Stating it up front is the difference
       between a considered click and an abandoned one on mobile data. */
    .btn-meta { font-weight: 600; opacity: 0.75; font-size: 0.92em; }

    /* ============================================================
       KEYFRAMES — none.
       Phase 1 motion policy: nothing on this site animates by itself.
       slideUp/fadeIn/slideR/float/pulse/spin/pcCarousel all deleted with
       their last consumers. If a keyframe returns, it needs a reason the
       150ms-hover policy cannot serve.
    ============================================================ */

    /* ============================================================
       HEADER
    ============================================================ */
    /* B-04: the header used to be transparent until y>60 and only worked
       because every page's first 60px happened to be blue — a light hero would
       have produced white-on-white navigation. The background is now permanent;
       scrolling only adds the shadow.

       The padding no longer changes on scroll either. It was cosmetic, and a
       header whose height moves mid-scroll is a moving anchor for the mega-menu
       panels, which hang off --hdr-h. Constant height, no jitter. */
    .hdr {
      --hdr-h: 68px;
      position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
      height: var(--hdr-h);
      display: flex; align-items: center;
      background: rgba(26,58,107,0.97);
      backdrop-filter: blur(16px) saturate(180%);
      -webkit-backdrop-filter: blur(16px) saturate(180%);
      transition: box-shadow 0.32s cubic-bezier(0.4,0,0.2,1);
    }
    .hdr > .c { width: var(--w); }
    .hdr.scrolled {
      box-shadow: 0 2px 24px rgba(26,58,107,0.35);
    }
    .hdr-inner {
      display: flex; align-items: center; justify-content: space-between; gap: var(--sp-16);
    }
    .hdr-logo {
      display: flex; align-items: center; gap: var(--sp-12);
    }
    .hdr-logo img {
      height: 36px; width: auto;
      filter: none;
      transition: var(--transition);
    }
    .hdr-logo-name {
      font-family: var(--font-h); font-weight: 800; font-size: var(--fs-md);
      color: var(--cream); line-height: var(--lh-none);
      white-space: nowrap;
    }
    /* ── Mega menu (D-07) ──────────────────────────────────────────────────
       Four triggers replace seven links. Each trigger is a <button
       aria-expanded>; the panel it controls carries the routes. Panels are
       hidden with the `hidden` attribute rather than a class, so the menu is
       genuinely closed for assistive tech and not merely invisible — and so it
       degrades to a plain visible list if the JS never runs. */
    nav.main-nav { display: flex; align-items: center; gap: var(--sp-2); }
    .nav-item { position: relative; }
    .nav-trigger {
      display: inline-flex; align-items: center; gap: var(--sp-8);
      font-family: var(--font-h); font-size: var(--fs-xs); font-weight: 500;
      color: rgba(255,255,255,0.82); padding: var(--sp-8) var(--sp-12); border-radius: 6px;
      background: none; border: none; letter-spacing: 0.01em;
      transition: color 0.2s, background 0.2s;
    }
    .nav-trigger:hover,
    .nav-trigger[aria-expanded="true"] { color: var(--cream); background: rgba(255,255,255,0.1); }
    /* aria-current="true" on the trigger = "you are somewhere inside this
       menu". Distinct from aria-current="page" on the exact link inside it. */
    .nav-trigger[aria-current="true"] { color: var(--cream); }
    .nav-trigger[aria-current="true"]::after {
      content: ""; position: absolute; left: 13px; right: 13px; bottom: -2px;
      height: 2px; border-radius: 2px; background: var(--cream);
    }
    .nav-caret { width: 9px; height: 6px; flex-shrink: 0; transition: transform 0.22s; }
    .nav-trigger[aria-expanded="true"] .nav-caret { transform: rotate(180deg); }

    .nav-panel {
      position: absolute; top: calc(100% + 10px); left: 0;
      min-width: 280px; z-index: 1001;
      background: var(--cream); color: var(--blue);
      border-radius: var(--radius); box-shadow: var(--shadow-lg);
      border: 1px solid var(--cream-mid);
      overflow: hidden;
    }
    /* The product menu is the site's whole catalogue, so it spans the viewport
       instead of hanging off one trigger. `fixed` (not absolute) because the
       header is fixed — this keeps it out of the nav item's stacking context
       and off the horizontal-overflow path at every width. */
    /* Phase 11: was `left: 4vw; right: 4vw` — a 92vw sheet that read as a new
       page rather than a menu, and its uneven column heights (8 links vs 1)
       left a dead quarter-screen of white inside it. Capped to the content
       width and packed with CSS multi-columns below. */
    .nav-panel-wide {
      position: fixed; top: calc(var(--hdr-h) + 6px); left: 0; right: 0;
      margin-inline: auto; width: min(1200px, 94vw);
      min-width: 0; max-height: calc(100vh - var(--hdr-h) - 24px);
      overflow-y: auto;
    }
    /* The last two menus sit close enough to the right edge that a panel
       anchored `left: 0` spills off-screen — measured at 1024px, where the
       Resources panel ran to 1188px in a 1024px viewport. Anchoring them to
       their own right edge keeps every panel inside the viewport at every
       desktop width, with no JS repositioning. */
    .nav-item:nth-last-child(-n+2) .nav-panel:not(.nav-panel-wide) {
      left: auto; right: 0;
    }
    .nav-panel[hidden] { display: none; }
    .nav-panel-in { padding: var(--sp-24) var(--sp-24); }
    .nav-panel-wide .nav-panel-in { padding: var(--sp-24) var(--sp-32); }

    .nav-cols {
      display: grid; gap: var(--sp-16) var(--sp-32);
      grid-template-columns: repeat(auto-fit, minmax(178px, 1fr));
    }
    .nav-panel:not(.nav-panel-wide) .nav-cols { grid-template-columns: repeat(2, minmax(150px, 1fr)); }
    /* Phase 11: the wide panel packs its groups with CSS multi-columns instead
       of one grid row per group. Grid gave every group the tallest group's row
       height, which is where the dead space came from; columns let a short
       group (Industrial, 2 links) stack under another instead of reserving a
       full-height cell. Each group stays whole via break-inside. */
    .nav-panel-wide .nav-cols { display: block; columns: 5 176px; column-gap: var(--sp-32); }
    .nav-panel-wide .nav-col { break-inside: avoid; margin-bottom: var(--sp-16); }
    .nav-col { display: flex; flex-direction: column; gap: var(--sp-2); }
    .nav-col-h {
      font-family: var(--font-h); font-size: var(--fs-2xs); font-weight: 700;
      letter-spacing: 0.1em; text-transform: uppercase;
      color: var(--blue); padding: var(--sp-4) var(--sp-8); margin-bottom: var(--sp-2); border-radius: 5px;
      transition: background 0.18s;
    }
    .nav-col-h:hover { background: var(--cream-dark); }
    .nav-link {
      font-size: var(--fs-sm); color: var(--ink-muted);
      padding: var(--sp-8) var(--sp-8); border-radius: 5px; line-height: var(--lh-snug);
      transition: background 0.18s, color 0.18s;
    }
    .nav-link:hover { background: var(--cream-dark); color: var(--blue); }
    .nav-link[aria-current="page"],
    .nav-col-h[aria-current="page"],
    .nav-rich[aria-current="page"] { background: var(--cream-dark); color: var(--blue); font-weight: 700; }

    .nav-list { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 320px; }
    .nav-rich {
      display: flex; flex-direction: column; gap: var(--sp-2);
      padding: var(--sp-8) var(--sp-12); border-radius: 7px;
      transition: background 0.18s;
    }
    .nav-rich:hover { background: var(--cream-dark); }
    .nav-rich-t { font-family: var(--font-h); font-size: var(--fs-sm); font-weight: 600; color: var(--blue); }
    .nav-rich-n { font-size: var(--fs-2xs); color: var(--ink-muted); line-height: var(--lh-snug); }

    .nav-foot {
      display: flex; align-items: center; justify-content: space-between;
      gap: var(--sp-16); flex-wrap: wrap;
      margin-top: var(--sp-16); padding-top: var(--sp-12);
      border-top: 1px solid var(--cream-mid);
    }
    .nav-blurb { font-size: var(--fs-xs); color: var(--ink-muted); margin: 0; }
    .nav-foot-cta {
      font-family: var(--font-h); font-size: var(--fs-xs); font-weight: 700;
      color: var(--blue); white-space: nowrap;
    }
    .nav-foot-cta:hover { text-decoration: underline; }

    /* Catches the click that dismisses an open panel. Transparent: a mega menu
       is a dropdown, not a modal, and dimming the page would say otherwise. */
    .nav-scrim { position: fixed; inset: 0; z-index: 999; background: transparent; }
    .nav-scrim[hidden] { display: none; }

    .hdr-cta {
      font-family: var(--font-h); font-size: var(--fs-xs); font-weight: 700;
      background: var(--cream); color: var(--blue); padding: var(--sp-8) var(--sp-24);
      border-radius: 6px; transition: var(--transition);
      /* Never let flex wrap the label onto two lines or shrink the icon
         button: at 1024px the row was tight enough to do both. */
      white-space: nowrap; flex-shrink: 0;
    }
    .hdr-cta:hover { background: var(--cream-dark); }

    /* CRO-02: `.hdr-phone` — the 38px circular call button that sat immediately
       left of the header CTA on all 68 pages — was removed in Phase 2, not
       restyled. A call is an unqualified, untracked, business-hours-only lead
       competing with the form that captures sector, quantity and timeline. The
       number still appears on /contact/, in the footer, in the mobile drawer as
       a secondary link, and in the enquiry-form success state. */

    /* 44x44: this is the only navigation control on mobile, so it gets a full
       comfortable tap target (WCAG 2.2 2.5.8 asks 24x24 as a floor; 44 is the
       platform convention). The bars stay visually 22px wide — the padding
       grows the hit area, not the icon. */
    .burger {
      display: none; flex-direction: column; align-items: center; justify-content: center;
      gap: var(--sp-4); width: 44px; height: 44px;
      background: none; border: none; padding: 0;
      position: relative;
      z-index: 1003;
    }
    .burger.is-open { opacity: 0; pointer-events: none; }
    .burger span {
      display: block; width: 22px; height: 2px;
      background: var(--cream); border-radius: 2px; transition: var(--transition);
    }

    /* ── Mobile drawer (B-06) ──────────────────────────────────────────────
       Rebuilt as an accordion mirroring the mega menu. The old drawer centred
       seven links vertically and repeated all three CTAs beneath them; the
       accordion now carries 45 routes, which means it scrolls, which means it
       cannot be centred. Top-aligned, its own scroll container, one primary
       action pinned at the end of the flow. */
    .mob-menu {
      display: none; position: fixed; inset: 0; z-index: 1002;
      background: var(--blue-dark);
      flex-direction: column; align-items: stretch; justify-content: flex-start;
    }
    .mob-menu.open { display: flex; }
    .mob-bar {
      display: flex; align-items: center; justify-content: space-between;
      height: var(--hdr-h, 68px); flex-shrink: 0;
      padding: 0 max(var(--sp-16), calc((100vw - var(--w)) / 2));
      border-bottom: 1px solid rgba(255,255,255,0.14);
    }
    .mob-bar-t {
      font-family: var(--font-h); font-size: var(--fs-2xs); font-weight: 700;
      letter-spacing: 0.18em; text-transform: uppercase;
      color: var(--on-blue-muted);
    }
    .mob-close {
      font-size: var(--fs-2xl); color: var(--cream);
      background: none; border: none; line-height: var(--lh-none);
      width: 44px; height: 44px; padding: 0;
      display: flex; align-items: center; justify-content: center;
      z-index: 1004;
    }
    /* -webkit-overflow-scrolling for momentum on older iOS; overscroll-behavior
       stops a flick at the end of the list from scrolling the page underneath. */
    .mob-scroll {
      flex: 1; overflow-y: auto; overscroll-behavior: contain;
      -webkit-overflow-scrolling: touch;
      padding: var(--sp-8) max(var(--sp-16), calc((100vw - var(--w)) / 2)) var(--sp-32);
    }
    .mob-group { border-bottom: 1px solid rgba(255,255,255,0.1); }
    .mob-acc {
      display: flex; align-items: center; justify-content: space-between;
      width: 100%; gap: var(--sp-12); min-height: 56px; padding: var(--sp-12) var(--sp-4);
      background: none; border: none; text-align: left;
      font-family: var(--font-h); font-size: var(--fs-md); font-weight: 700;
      color: var(--cream);
    }
    .mob-acc-ico { width: 12px; height: 8px; flex-shrink: 0; transition: transform 0.22s; }
    .mob-acc[aria-expanded="true"] .mob-acc-ico { transform: rotate(180deg); }
    .mob-panel { padding: 0 var(--sp-4) var(--sp-12); }
    .mob-panel[hidden] { display: none; }
    /* Column headings in the drawer are LINKS to the hub, not just labels, so
       they get the same 44px target as everything else here — a 34px link
       clears WCAG 2.5.8's 24px floor but not the platform convention the
       burger already follows. */
    .mob-col-h {
      display: flex; align-items: flex-end; min-height: 44px;
      font-family: var(--font-h); font-size: var(--fs-3xs); font-weight: 700;
      letter-spacing: 0.14em; text-transform: uppercase;
      color: var(--on-blue-muted);
      padding: var(--sp-12) var(--sp-8) var(--sp-8); border-radius: 7px;
    }
    .mob-link {
      display: block; font-size: var(--fs-base); color: rgba(255,255,255,0.88);
      padding: var(--sp-12) var(--sp-8); border-radius: 7px; min-height: 44px;
    }
    .mob-link:hover, .mob-link:active { background: rgba(255,255,255,0.08); }
    .mob-link[aria-current="page"], .mob-col-h[aria-current="page"] {
      background: rgba(255,255,255,0.12); color: var(--cream); font-weight: 700;
    }
    .mob-link-cta { font-family: var(--font-h); font-weight: 700; color: var(--cream); }
    /* One primary action, then phone and WhatsApp as compact secondary links —
       the drawer used to give all three equal weight as full-width buttons. */
    .mob-actions {
      display: flex; flex-direction: column; gap: var(--sp-12); align-items: center;
      margin-top: var(--sp-24); padding-top: var(--sp-24);
      border-top: 1px solid rgba(255,255,255,0.16);
    }
    .mob-actions .btn { justify-content: center; width: 100%; font-size: var(--fs-base); }
    /* REMOVED: `.mob-secondary` — the phone and WhatsApp links under the
       drawer's primary CTA (C-01, C-04). The drawer was the last surface
       stacking all three asks in one eyeful. Both are still on mobile: the FAB
       is now mobile-only and the phone number is in the footer. */

    /* ============================================================
       HERO
    ============================================================ */
    /* L-08: was `min-height: 100vh`. A full viewport of hero is a promise the
       content did not keep — at 1280x720 the first screen held a pill, an H1,
       one paragraph and six stat cards, and nothing to click. The clamp keeps
       the hero generous on a laptop without letting a tall monitor turn it into
       a wall, and the CTA row (CRO-01) now sits inside the first screen. */
    .hero {
      min-height: clamp(560px, 82vh, 760px); display: flex; align-items: center;
      background: var(--blue); position: relative; overflow: hidden;
      padding-top: var(--sp-64);
    }
    .hero::before {
      content: '';
      position: absolute; inset: 0;
      background:
        radial-gradient(ellipse 65% 70% at 85% 50%, rgba(42,82,152,0.55) 0%, transparent 65%),
        radial-gradient(ellipse 45% 50% at 5% 85%, rgba(18,42,82,0.75) 0%, transparent 55%);
    }
    .hero-grid {
      position: absolute; inset: 0; opacity: 0.035;
      background-image:
        linear-gradient(rgba(255,255,255,1) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255,255,255,1) 1px, transparent 1px);
      background-size: 56px 56px;
    }
    .hero-content {
      position: relative; z-index: 2;
      display: grid; grid-template-columns: 1fr 1fr;
      gap: clamp(var(--sp-32),6vw,var(--sp-64)); align-items: center;
    }
    .hero-text { /* entrance animation removed — Phase 1 motion policy */ }
    .hero-pill {
      display: inline-flex; align-items: center; gap: var(--sp-8);
      background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.18);
      border-radius: 100px; padding: var(--sp-8) var(--sp-16); margin-bottom: var(--sp-24);
      font-family: var(--font-h); font-size: var(--fs-2xs); font-weight: 600;
      color: rgba(255,255,255,0.88); letter-spacing: 0.1em; text-transform: uppercase;
    }
    .hero-pill-dot {
      width: 7px; height: 7px; border-radius: 50%; background: #FFFFFF;
      /* was `pulse 2.2s infinite` — the last self-starting motion on the site */
    }
    .hero-h1 {
      font-family: var(--font-h); font-size: clamp(2.1rem, 4.8vw, 3.9rem);
      font-weight: 900; line-height: var(--lh-tight); color: var(--cream); margin-bottom: var(--sp-24);
    }
    .hero-h1 .hl {
      position: relative; display: inline-block;
    }
    .hero-h1 .hl::after {
      content: '';
      position: absolute; bottom: 1px; left: 0; right: 0; height: 3px;
      background: rgba(255,255,255,0.28); border-radius: 2px;
    }
    .hero-sub {
      font-size: clamp(0.98rem,1.55vw,1.12rem); line-height: var(--lh-relaxed);
      color: rgba(255,255,255,0.82); margin-bottom: var(--sp-32); max-width: 500px;
    }
.hero-assurance {
      display: inline-flex; align-items: center; gap: var(--sp-12); flex-wrap: wrap;
      padding: var(--sp-12) var(--sp-16); border-radius: 12px;
      background: rgba(255,255,255,0.09);
      border: 1px solid rgba(255,255,255,0.16);
      backdrop-filter: blur(10px);
    }
    .hero-assurance span {
      font-family: var(--font-h); font-size: var(--fs-xs); font-weight: 600;
      color: rgba(255,255,255,0.86); white-space: nowrap;
    }
    .hero-assurance span::before {
      content: '•'; margin-right: var(--sp-8); color: rgba(255,255,255,0.9);
    }

    /* The UVP. Its own line, its own weight — it is the one sentence the
       brand system asks the homepage to lead with, so it is set above the
       supporting paragraph rather than inside it. */
    .hero-uvp {
      font-family: var(--font-h); font-weight: 700;
      font-size: clamp(1.02rem,1.9vw,1.3rem); line-height: var(--lh-tight);
      color: #FFFFFF; margin-bottom: var(--sp-16);
      letter-spacing: 0.005em;
    }

    /* Hero photograph. Aspect ratio is reserved from the intrinsic width/height
       on the <img>, so the hero never shifts as it decodes (CLS). */
    .hero-media {
      position: relative; z-index: 2;
    }
    .hero-media img {
      width: 100%; height: auto; display: block;
      max-height: 62vh; object-fit: cover;
      border-radius: var(--radius-lg);
      border: 1px solid rgba(255,255,255,0.16);
      box-shadow: 0 18px 60px rgba(0,0,0,0.28);
    }

    /* Hero visual card grid — now the proof strip below the hero. */
    .hero-cards {
      display: grid; grid-template-columns: repeat(3,minmax(0,1fr)); gap: var(--sp-12);
    }
    /* Six across on the proof strip: it is a compact band, not a hero column. */
    .proof-strip { grid-template-columns: repeat(6,minmax(0,1fr)); animation: none; }
    /* Phase 3: the homepage band is four figures, not six. */
    .proof-strip--4 { grid-template-columns: repeat(4,minmax(0,1fr)); }

    /* ── Full-screen hero (2026-08-21) ────────────────────────────────────
       The hero is now the first screen in its entirety: heading, tagline,
       photograph AND the four capacity figures in ONE blue container. The
       figures used to be a separate section directly beneath it, which is the
       same band with a seam through it.

       100svh, not 100vh. On mobile Safari and Chrome 100vh measures the
       viewport with the address bar RETRACTED, so a 100vh hero is ~15% taller
       than the screen on first paint and the stat row opens below the fold —
       the one thing this layout exists to prevent. The vh line stays first as
       the fallback for browsers without svh. */
    .hero--full { min-height: 100vh; min-height: 100svh; }
    /* .hero is a flex container centring a single .c child; without this the
       container shrink-wraps its content and the stat row loses the gutter. */
    .hero--full > .c { width: 100%; }

    /* The stat row is a sibling of .hero-content, not a cell inside it, so it
       spans the full container width under both columns. The clamp lets the
       gap give way first on a short laptop screen — the row staying ON the
       first screen matters more than the space above it. */
    .hero-stats { margin-top: clamp(var(--sp-24), 4vh, var(--sp-48)); }

    /* Short desktop screens. A 1366x768 laptop carrying a large browser chrome
       and a taskbar leaves ~560px of viewport, and at that height the hero grew
       past the screen and pushed the stat row — the whole reason the hero is
       full-height — below the fold. The photograph is the only element with
       real height to give back, so it gives it back first; the heading and the
       gaps tighten a step behind it.

       min-width guards the phone breakpoint, where the hero deliberately
       stacks and is meant to be taller than a screen. */
    @media (min-width: 769px) and (max-height: 700px) {
      .hero--full .hero-media img { max-height: 44vh; }
      .hero--full .hero-h1 { margin-bottom: var(--sp-16); }
      .hero--full .hero-sub { margin-bottom: 0; }
      .hero--full .hero-stats { margin-top: var(--sp-16); }
      .hero--full .proof-strip .hc { padding: var(--sp-12); }
      .hero--full .hc-num { font-size: clamp(1.5rem,2.4vw,2.1rem); margin-bottom: var(--sp-4); }
    }

    /* ── Phase 3 homepage components ──────────────────────────────────────
       The promise band, folded into the proof section rather than standing
       as its own full-bleed blue slab between the client grid and the FAQ. */
    .promise {
      margin-top: var(--sp-48); padding-top: var(--sp-32);
      border-top: 1px solid var(--border-c); text-align: center;
    }
    .promise-line {
      font-family: var(--font-h); font-size: var(--fs-2xl);
      font-weight: 900; color: var(--blue); line-height: var(--lh-tight);
    }
    .promise-line span { display: block; font-size: 0.86em; color: var(--ink-soft); }
    .promise-sub {
      max-width: var(--measure-prose); margin: var(--sp-12) auto 0;
      color: var(--ink-muted); line-height: var(--lh-relaxed); font-size: var(--fs-sm);
    }
    /* A centred measure. `.measure` alone left the column pinned left. */
    .measure-center { max-width: var(--measure-prose); margin-inline: auto; }
    .hero-ctas--center { justify-content: center; }

    /* Product hero with its garment photograph: approved layout (b), 50/50.
       The image column is fixed so the photo is the same size on every
       product page — a ratio-based column would size the garment to how much
       copy its lede happens to have. */
    .lp-hero--media .lp-hero-grid {
      display: grid; grid-template-columns: 1fr 420px;
      gap: var(--sp-48); align-items: center;
    }
    .lp-hero-media img { width: 100%; }
    @media (max-width: 900px) {
      .lp-hero--media .lp-hero-grid { grid-template-columns: 1fr; gap: var(--sp-32); }
      .lp-hero-media { max-width: 360px; }
    }

    /* Capability: approved layout (b), 50/50 side-by-side. Six items in two
       columns beside the fabric macro — 280px shorter than the 3-across card
       grid it replaces, and it carries a real photograph. */
    .cap-split {
      display: grid; grid-template-columns: 400px 1fr;
      gap: var(--sp-48); align-items: start;
    }
    .cap-list {
      display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: var(--sp-24); margin-top: var(--sp-24); list-style: none; padding: 0;
    }
    .cap-list li { font-size: var(--fs-sm); line-height: var(--lh-relaxed); color: var(--ink-muted); }
    .cap-list strong {
      display: block; font-family: var(--font-h); font-weight: 700;
      font-size: var(--fs-md); color: var(--blue); margin-bottom: var(--sp-4);
    }
    @media (max-width: 900px) {
      .cap-split { grid-template-columns: 1fr; gap: var(--sp-32); }
      .cap-media { max-width: 320px; }
    }
    @media (max-width: 620px) {
      .cap-list { grid-template-columns: 1fr; }
    }
    .proof-strip .hc { min-height: 0; padding: var(--sp-16) var(--sp-12); }
    /* Phase 1: one rhythm — the tight variant now resolves to the shared
       section padding like everything else. Kept as a class so specs and
       templates need no change. */
    .section--tight { padding-block: var(--space-section); }
    .hc {
      background: rgba(255,255,255,0.07);
      border: 1px solid rgba(255,255,255,0.11);
      border-radius: 16px; padding: var(--sp-24) var(--sp-16);
      backdrop-filter: blur(8px); transition: var(--transition);
      min-height: 132px;
    }
    .hc:hover { background: rgba(255,255,255,0.11); transform: translateY(-4px); }
    .hc.wide { grid-column: 1 / -1; padding: var(--sp-24) var(--sp-24); }
    .hc-num {
      font-family: var(--font-h); font-size: clamp(1.9rem,3.2vw,2.9rem);
      font-weight: 900; color: var(--cream); line-height: var(--lh-none); margin-bottom: var(--sp-8);
    }
    .hc-lbl {
      /* 0.58 measured 4.29:1 on the card fill — below the 4.5:1 floor for text
         at this size. 0.70 clears it with margin and costs nothing visually. */
      font-size: var(--fs-xs); color: rgba(255,255,255,0.70); line-height: var(--lh-snug);
    }

    /* Phase 3: the homepage proof strip moved off the blue slab onto a blue
       tint, so the cards need the light-surface treatment — white-on-white
       would have been invisible. --ink-muted is the measured 4.5:1 floor on
       this tint (5.55:1), so the label is not merely "dark enough to see". */
    .section--cream-d .hc,
    .section--cream .hc,
    .section--cream-m .hc {
      background: var(--cream); border: 1px solid var(--border-c);
      backdrop-filter: none;
    }
    .section--cream-d .hc:hover,
    .section--cream .hc:hover,
    .section--cream-m .hc:hover { background: var(--cream); border-color: var(--blue); transform: none; }
    .section--cream-d .hc-num,
    .section--cream .hc-num,
    .section--cream-m .hc-num { color: var(--blue); }
    .section--cream-d .hc-lbl,
    .section--cream .hc-lbl,
    .section--cream-m .hc-lbl { color: var(--ink-muted); }

    /* ============================================================
       STATS STRIP
    ============================================================ */
/* The stat band carries WHITE text, so it has to own a dark surface rather
       than inherit whatever the section is painted. It did not, and when the
       palette moved from cream to Pure White the `--cream` text colour became
       #FFFFFF on a #F0F4F8 section: /about/ shipped a capacity band at a
       contrast ratio of 1.1:1 — four figures that were, in practice, invisible.
       Giving the band its own Wearzo Blue fill fixes it wherever it is used and
       cannot be undone by a section variant. */
    .stats-row {
      display: flex;
      background: var(--blue);
      border-radius: var(--radius);
      overflow: hidden;
    }
    .stat {
      flex: 1; padding: var(--sp-24) var(--sp-16); text-align: center;
      border-right: 1px solid rgba(255,255,255,0.07);
      transition: var(--transition);
    }
    .stat:last-child { border-right: none; }
    .stat:hover { background: rgba(255,255,255,0.04); }
    .stat-n {
      font-family: var(--font-h); font-size: clamp(1.5rem,2.3vw,2.1rem);
      font-weight: 900; color: var(--cream); line-height: var(--lh-none); margin-bottom: var(--sp-4);
    }
    .stat-l { font-size: var(--fs-xs); color: rgba(255,255,255,0.75); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 600; }

    /* ============================================================
       ABOUT
    ============================================================ */
    .about-grid {
      display: grid; grid-template-columns: 1fr 1.1fr;
      gap: clamp(var(--sp-32),6vw,var(--sp-64)); align-items: center;
    }
    .about-img-block {
      position: relative;
    }
    .about-frame {
      aspect-ratio: 4/5; border-radius: var(--radius-lg); overflow: hidden;
      background: linear-gradient(145deg, var(--blue-mid) 0%, var(--blue-light) 100%);
      display: flex; align-items: center; justify-content: center;
      position: relative;
    }
    .about-frame img {
      width: 100%; height: 100%; object-fit: cover;
      border-radius: var(--radius-lg);
    }
/* The badge deliberately overhangs its frame, which is the look — but at 320px
   the frame already fills the container, so `right: -18px` pushed it 13px past
   the viewport and produced real horizontal scroll. `html, body { overflow-x:
   hidden }` had been hiding that; removing the mask (L-07) surfaced it on the
   first sweep. The overhang is kept where there is room for it and drops to
   flush inside the frame when there is not. */
    .about-badge {
      position: absolute; bottom: -18px; right: -18px;
      background: var(--cream); color: var(--blue);
      border-radius: var(--radius); padding: var(--sp-16) var(--sp-24);
      box-shadow: var(--shadow-lg); font-family: var(--font-h); text-align: center;
      z-index: 2;
    }
    .about-badge strong { font-size: var(--fs-2xl); font-weight: 900; display: block; line-height: var(--lh-none); }
    /* `opacity` here dimmed the whole label to 3.6:1 on the white badge. Colour
       carries the de-emphasis instead, at the measured 4.5:1 floor. */
    @media (max-width: 560px) {
      .about-badge { right: var(--sp-8); bottom: var(--sp-8); padding: var(--sp-12) var(--sp-16); }
    }
    .about-badge span { font-size: var(--fs-3xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-muted); }
    .about-points { margin-top: var(--sp-32); display: flex; flex-direction: column; gap: var(--sp-12); }
    .apo {
      display: flex; align-items: flex-start; gap: var(--sp-12);
      padding: var(--sp-12) var(--sp-16); background: var(--cream-dark); border-radius: 10px;
      transition: var(--transition);
    }
    .apo:hover { background: var(--cream-mid); }
    /* CRO-06 / A11Y-02 — the inline SVG icon set that replaced 52 distinct
       emoji. One base rule: every icon inherits its size from the box it sits
       in and its colour from the surrounding text, so a container that used to
       set `font-size` to scale an emoji still scales the SVG and needed no
       change. `stroke: currentColor` is on the SVG itself. */
    .ico {
      width: 1em; height: 1em; display: block; flex-shrink: 0;
      /* Optical: line icons read slightly small next to heavy display type. */
      transform: scale(1.05);
    }
    .apo-icon {
      width: 34px; height: 34px; border-radius: 8px; flex-shrink: 0;
      background: var(--blue); color: var(--cream);
      display: flex; align-items: center; justify-content: center;
      font-size: var(--fs-base);
    }
    /* Card icon: sits above the card heading, brand blue, same optical size
       as the emoji it replaced. */
    .card-ico {
      display: block; font-size: var(--fs-lg); color: var(--blue);
      margin-bottom: var(--sp-8);
    }
    .apo-body { font-size: var(--fs-sm); line-height: var(--lh-snug); }
    .apo-body strong { font-family: var(--font-h); font-weight: 700; display: block; margin-bottom: var(--sp-2); font-size: var(--fs-sm); }

    /* Team */
    .team-grid {
      margin-top: var(--sp-32);
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: var(--sp-16);
    }
    .tm-card {
      background: var(--cream);
      border: 1.5px solid rgba(26,58,107,0.1);
      border-radius: var(--radius);
      overflow: hidden;
      box-shadow: var(--shadow-sm);
      transition: var(--transition);
    }
    .tm-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
    .tm-photo {
      width: 100%;
      aspect-ratio: 4 / 3;
      object-fit: cover;
      background: linear-gradient(145deg, var(--blue-mid), var(--blue-light));
    }
    .tm-body { padding: var(--sp-16) var(--sp-16) var(--sp-16); }
    .tm-name {
      font-family: var(--font-h);
      font-size: var(--fs-md);
      font-weight: 800;
      color: var(--blue);
      margin-bottom: var(--sp-4);
    }
    .tm-role {
      font-size: var(--fs-2xs);
      font-weight: 700;
      letter-spacing: 0.08em;
      text-transform: uppercase;
      color: var(--ink-muted);
      margin-bottom: var(--sp-8);
      font-family: var(--font-h);
    }
    .tm-desc {
      font-size: var(--fs-sm);
      line-height: var(--lh-relaxed);
      color: rgba(26,58,107,0.74);
      margin: 0;
    }

    /* ============================================================
       PRODUCTS
    ============================================================ */
    .products-grid {
      display: grid; grid-template-columns: repeat(3,1fr); gap: var(--sp-16); margin-top: var(--sp-48);
    }
    .pc {
      background: var(--cream); border: 1px solid var(--border-c);
      border-radius: var(--radius); padding: var(--sp-16) var(--sp-16) var(--sp-24);
      position: relative; overflow: hidden; transition: var(--transition); text-align: center;
    }
    .pc::before {
      content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
      background: var(--blue); border-radius: 3px 3px 0 0;
      transform: scaleX(0); transform-origin: left; transition: transform 0.3s ease;
    }
    .pc:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); border-color: rgba(26,58,107,0.18); }
    .pc:hover::before { transform: scaleX(1); }
    .pc-icon { font-size: var(--fs-2xl); margin-bottom: var(--sp-16); display: block; color: var(--blue); }
    /* REMOVED: five `.pc:nth-child(n) .pc-icon{animation-delay}` rules. They
       staggered a float loop on the product-card emoji; the emoji are now line
       icons and the loop is gone (same reasoning as the FAB in C-06). */
    /* The product-line image. One per card now, so this is a plain container
       with an <img> in it rather than a <button> hosting a stack of absolutely
       positioned slides.

       Gone with the carousel: the cursor:pointer and appearance resets that
       existed only because it was a <button>, the .pc-slide opacity/transform
       pair, the .is-active state and the "1 / 5" counter that was the
       affordance telling a visitor the image was pressable. */
    /* Phase 3: 170px -> 260px. "Product imagery should be given real size and
       prominence, not thumbnail treatment" was the reviewer's §2.5 point, and
       a 170px letterbox on a page selling garments is exactly a thumbnail.
       The height this adds is paid for by the two sections deleted above it,
       not by shrinking anything. */
    .pc-media-static {
      display: block; width: 100%;
      height: 260px; margin: 0 0 var(--sp-16);
      border-radius: var(--radius); overflow: hidden;
      background: var(--blue-05);
      border: 1px solid var(--border-c);
    }
    .pc-media-static img {
      width: 100%; height: 100%; object-fit: cover; display: block;
      filter: saturate(1.02) contrast(1.02);
    }
    /* Who the line is for, above the description — a buyer self-selects on
       audience faster than on garment type. */
    .pc-audience {
      font-family: var(--font-h); font-size: var(--fs-2xs); font-weight: 700;
      letter-spacing: 0.04em; text-transform: uppercase;
      color: var(--ink-muted); margin-bottom: var(--sp-8);
    }
    .pc-link-2 { display: block; margin-top: var(--sp-8); font-weight: 600; }

    .pc-name { font-family: var(--font-h); font-size: var(--fs-md); font-weight: 700; color: var(--blue); margin-bottom: var(--sp-8); }
    .pc-desc { font-size: var(--fs-sm); color: var(--ink-muted); line-height: var(--lh-relaxed); margin-bottom: var(--sp-12); }
    .pc-tags { display: flex; flex-wrap: wrap; gap: var(--sp-4); justify-content: center; }
    .pct {
      font-size: var(--fs-2xs); font-weight: 700; font-family: var(--font-h);
      background: rgba(26,58,107,0.07); color: var(--blue);
      padding: var(--sp-2) var(--sp-8); border-radius: 100px;
    }

    /* ============================================================
       SERVICES (blue section)
    ============================================================ */
    .srv-grid {
      display: grid; grid-template-columns: repeat(2,1fr); gap: var(--sp-24); margin-top: var(--sp-48);
    }
    .srv {
      background: rgba(255,255,255,0.07);
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: var(--radius); padding: var(--sp-32); transition: var(--transition);
    }
    .srv:hover { background: rgba(255,255,255,0.11); transform: translateY(-4px); }
    .srv-n {
      font-family: var(--font-h); font-size: var(--fs-3xs); font-weight: 700;
      letter-spacing: 0.16em; text-transform: uppercase;
      color: var(--on-blue-muted); margin-bottom: var(--sp-12);
    }
    .srv-title { font-family: var(--font-h); font-size: var(--fs-md); font-weight: 700; color: var(--cream); margin-bottom: var(--sp-8); }
    .srv-desc { font-size: var(--fs-sm); color: rgba(255,255,255,0.68); line-height: var(--lh-relaxed); margin-bottom: var(--sp-12); }
    .srv-feats { display: flex; flex-direction: column; gap: var(--sp-4); }
    .srv-feat { font-size: var(--fs-xs); color: rgba(255,255,255,0.62); display: flex; align-items: flex-start; gap: var(--sp-8); }
    .srv-feat::before { content: '→'; color: rgba(255,255,255,0.32); font-size: var(--fs-2xs); flex-shrink: 0; margin-top: var(--sp-2); }

    /* VAS grid */
    .vas-wrap { margin-top: var(--sp-48); text-align: center; }
    .vas-row {
      display: grid; grid-template-columns: repeat(5,1fr); gap: var(--sp-12); margin-top: var(--sp-32);
    }
    .vas-c {
      text-align: center; padding: var(--sp-24) var(--sp-12);
      background: rgba(255,255,255,0.05);
      border: 1px solid rgba(255,255,255,0.09);
      border-radius: 10px; transition: var(--transition);
    }
    .vas-c:hover { background: rgba(255,255,255,0.1); transform: translateY(-4px); }
    .vas-c-icon { font-size: var(--fs-xl); margin-bottom: var(--sp-8); display: block; color: var(--cream); }
    .vas-c-name { font-family: var(--font-h); font-size: var(--fs-2xs); font-weight: 700; color: var(--cream); margin-bottom: var(--sp-2); }
    .vas-c-hint { font-size: var(--fs-3xs); color: var(--on-blue-muted); }

    /* ============================================================
       WHY US
    ============================================================ */
    .why-grid {
      display: grid; grid-template-columns: repeat(4,1fr); gap: var(--sp-16); margin-top: var(--sp-48);
    }
    .why-c {
      padding: var(--sp-24) var(--sp-24); border-radius: var(--radius);
      background: var(--cream-dark); border: 1.5px solid transparent;
      position: relative; overflow: hidden; transition: var(--transition);
    }
    .why-c::after {
      content: attr(data-n);
      position: absolute; right: 14px; top: 10px;
      font-family: var(--font-h); font-size: var(--fs-3xl); font-weight: 900;
      color: rgba(26,58,107,0.22); line-height: var(--lh-none); pointer-events: none;
    }
    .why-c:hover { border-color: var(--blue); transform: translateY(-5px); box-shadow: var(--shadow); }
    .why-c-icon { font-size: var(--fs-xl); margin-bottom: var(--sp-12); color: var(--blue); }
    /* L-10: the numeral is a watermark at 3.2rem/1 occupying y=10-61px while the
       title starts at y=60px, so a two-line title on a narrow card ran into its
       baseline. Reserving the numeral's inline space stops the collision without
       shrinking either. */
    .why-c-title {
      font-family: var(--font-h); font-size: var(--fs-base); font-weight: 700;
      margin-bottom: var(--sp-8); padding-right: var(--sp-48);
    }
    .why-c-desc { font-size: var(--fs-sm); color: var(--ink-muted); line-height: var(--lh-relaxed); }

    /* ============================================================
       PROCESS
    ============================================================ */
    .process-row {
      display: grid; grid-template-columns: repeat(4,1fr);
      gap: var(--sp-32) 0; margin-top: var(--sp-64); position: relative;
    }
    .pr-step {
      text-align: center; padding: 0 var(--sp-12); position: relative; z-index: 1;
    }
    /* L-09 — connector geometry.
       The rail used to start at `calc(50% + 30px)` (the circle's edge, with no
       clearance) and run `calc(100% - 18px)` wide, which carried it 12px PAST
       the next circle's centre and underneath it, while the arrowhead sat at
       the step's right edge — the midpoint of the rail, not its end.

       Both are now expressed from one set of numbers. Columns are equal and the
       horizontal gap is 0, so the next circle's centre is exactly 100% away;
       --pr-r is the circle radius and --pr-gap the clearance either side, so the
       rail spans centre+r+gap to (centre+100%)-r-gap and the arrowhead lands on
       its far end by construction. Change the circle size and both follow. */
    .process-row { --pr-r: 30px; --pr-gap: 8px; --pr-arrow: 11px; }
    .pr-step::before,
    .pr-step::after {
      content: '';
      position: absolute;
      top: 29px;
      pointer-events: none;
    }
    .pr-step::after {
      left: calc(50% + var(--pr-r) + var(--pr-gap));
      width: calc(100% - 2 * (var(--pr-r) + var(--pr-gap)));
      border-top: 2px dashed rgba(26,58,107,0.34);
      transform: translateY(-50%);
    }
    .pr-step::before {
      left: calc(150% - var(--pr-r) - var(--pr-gap) - var(--pr-arrow));
      width: var(--pr-arrow);
      height: var(--pr-arrow);
      border-top: 2px solid rgba(26,58,107,0.52);
      border-right: 2px solid rgba(26,58,107,0.52);
      transform: translateY(-50%) rotate(45deg);
    }
    /* Last in a row has no next circle to point at. One selector per column
       count, declared with the breakpoint that sets that count — eleven
       scattered nth-child overrides became three. */
    .pr-step:nth-child(4n)::before,
    .pr-step:nth-child(4n)::after,
    .pr-step:last-child::before,
    .pr-step:last-child::after {
      display: none;
    }
    .pr-num {
      width: 60px; height: 60px; border-radius: 50%;
      background: var(--blue); color: var(--cream);
      font-family: var(--font-h); font-size: var(--fs-lg); font-weight: 800;
      display: flex; align-items: center; justify-content: center;
      margin: 0 auto var(--sp-12); box-shadow: 0 4px 16px rgba(26,58,107,0.28);
      transition: var(--transition); position: relative; z-index: 2;
    }
    .pr-step:hover .pr-num { transform: scale(1.1); }
    .pr-name { font-family: var(--font-h); font-size: var(--fs-sm); font-weight: 700; color: var(--blue); margin-bottom: var(--sp-4); }
    .pr-hint { font-size: var(--fs-xs); color: var(--ink-muted); line-height: var(--lh-relaxed); }


    /* ── Product index / site map (D-05, D-08) ─────────────────────────────── */
    .prod-index {
      display: grid; gap: var(--sp-24) var(--sp-32); margin-top: var(--sp-32);
      grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    }
    .prod-index-col { display: flex; flex-direction: column; gap: var(--sp-4); }
    .prod-index-h {
      font-family: var(--font-h); font-size: var(--fs-2xs); font-weight: 700;
      letter-spacing: 0.1em; text-transform: uppercase; color: var(--blue);
      padding-bottom: var(--sp-8); margin-bottom: var(--sp-4);
      border-bottom: 1px solid var(--cream-mid);
    }
    a.prod-index-h:hover { color: var(--blue-light); }
    .prod-index-list { display: flex; flex-direction: column; gap: var(--sp-2); }
    .prod-index-list a {
      display: block; font-size: var(--fs-sm); color: var(--ink-muted);
      padding: var(--sp-8) var(--sp-4); border-radius: 6px; line-height: var(--lh-snug);
    }
    .prod-index-list a:hover { background: var(--cream-dark); color: var(--blue); }

    /* ── Sector switcher (D-06) ────────────────────────────────────────────── */
    .sector-switch {
      display: grid; gap: var(--sp-12); margin-top: var(--sp-24);
      grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    }
    .sector-switch-item {
      display: flex; flex-direction: column; gap: var(--sp-2);
      padding: var(--sp-12) var(--sp-16); border-radius: 10px;
      background: var(--cream); border: 1px solid var(--cream-mid);
      transition: border-color 0.2s, transform 0.2s, box-shadow 0.2s;
    }
    .sector-switch-item:hover {
      border-color: var(--blue); transform: translateY(-2px); box-shadow: var(--shadow-sm);
    }
    .sector-switch-n { font-family: var(--font-h); font-size: var(--fs-sm); font-weight: 700; color: var(--blue); }
    .sector-switch-c { font-size: var(--fs-3xs); color: var(--ink-muted); }

    /* ============================================================
       BUYER RESOURCES GRID
       Step 8 of the homepage journey. Deliberately text-only: these are
       reading destinations, and a thumbnail beside each would add six images
       to the page to decorate six links.
    ============================================================ */
    .res-grid {
      display: grid; gap: var(--sp-16); list-style: none; padding: 0;
      grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    }
    .res-c {
      background: #FFFFFF; border: 1.5px solid rgba(26,58,107,0.10);
      border-radius: var(--radius); padding: var(--sp-24);
      transition: var(--transition);
    }
    .res-c:hover { border-color: rgba(26,58,107,0.28); box-shadow: var(--shadow-sm); }
    .res-c-link {
      font-family: var(--font-h); font-size: var(--fs-md); font-weight: 700;
      color: var(--blue); text-decoration: none; display: block;
      margin-bottom: var(--sp-8);
    }
    /* The whole card is the target, not just the words — a 44px touch target
       without nesting a second interactive element inside the card. */
    .res-c-link::after { content: ''; position: absolute; inset: 0; }
    .res-c { position: relative; }
    .res-c-link:hover, .res-c-link:focus-visible { text-decoration: underline; }
    .res-c-a {
      font-size: var(--fs-sm); color: var(--ink-muted);
      line-height: var(--lh-relaxed); margin: 0;
    }

    /* ============================================================
       CLIENTS GRID
       Was a marquee: a 22-item duplicated track on a 26s linear infinite
       animation, plus a Pause button and a `will-change: transform` layer
       promotion held for the life of the page. Replaced with a static grid
       (WCAG 2.2.2) — the animation, the toggle, the duplicated DOM and the
       compositor layer all go with it.
    ============================================================ */
    /* Phase 2 overhaul: the tiles are substantially larger — 220px min track
       and a 156px tile against the old 168/124 — because "tiny drifting
       logos read as clip-art" was the reviewer's point and the fix for the
       motion half (a static grid) did nothing for the size half. Uniform
       height, uniform padding, one background treatment, and NO greyscale:
       dimming a client's logo to 92% opacity is the visual language of a
       placeholder, on the strongest trust asset the page has.

       The cap on the art is 120×188 — the source files top out around 200px
       (AUDIT.md §8), so the tile is sized to display them at roughly 1:1
       rather than upscaling them into softness. */
    /* 180px min puts six tiles on a 1200px container, so eleven logos fill two
       rows rather than three-with-an-orphan. The tile is still 156px tall —
       the Phase 1 enlargement is not given back to save height. */
    .client-grid {
      display: grid; gap: var(--sp-16); margin-top: var(--sp-32);
      grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
      list-style: none; padding: 0;
    }
    .cl-card {
      min-width: 0; height: 156px;
      background: var(--cream); border: 1px solid var(--border-c);
      border-radius: var(--radius); display: flex; align-items: center;
      justify-content: center; padding: var(--sp-24); flex-shrink: 0;
      transition: var(--transition);
    }
    .cl-card:hover { border-color: var(--blue); box-shadow: var(--shadow); }
    .cl-card img {
      max-height: 120px; max-width: 188px; object-fit: contain;
    }

    /* ── Client logo carousel ─────────────────────────────────────────────
       Restored 2026-08-21 alongside the rest of the 2026-07-31 sections.

       Two identical sets of logos scroll left and the animation translates by
       exactly -50%, so set two arrives where set one began and the loop has no
       visible seam.

       It runs CONTINUOUSLY — Devansh's call, 2026-08-21. There is deliberately
       no pause-on-hover and no pause control. The one thing that still stops
       it is the sitewide prefers-reduced-motion block at the foot of this
       file, which is the visitor's own OS-level setting rather than a pause
       bolted onto the carousel. */
    @keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
    .marquee-wrap { overflow: hidden; margin-top: var(--sp-48); }
    .marquee-track {
      display: flex; gap: var(--sp-24); width: max-content;
      animation: marquee 26s linear infinite;
      will-change: transform;
    }
    /* .cl-card is sized by the grid on /clients/; in the flex track it needs
       its own width or every tile is as wide as the logo inside it. */
    .marquee-track .cl-card { min-width: 208px; margin-top: 0; }

    /* ============================================================
       CONTACT
    ============================================================ */
    .contact-grid {
      display: grid; grid-template-columns: 1fr 1.25fr;
      gap: var(--sp-48); align-items: start; margin-top: var(--sp-48);
    }
    .contact-cards { display: flex; flex-direction: column; gap: var(--sp-12); }
    .cc {
      background: var(--cream-dark); border-radius: var(--radius);
      padding: var(--sp-16) var(--sp-24); display: flex; align-items: flex-start; gap: var(--sp-12);
      transition: var(--transition);
    }
    .cc:hover { box-shadow: var(--shadow-sm); transform: translateY(-2px); }
    .cc-icon {
      width: 42px; height: 42px; border-radius: 9px; flex-shrink: 0;
      background: var(--blue); color: var(--cream);
      display: flex; align-items: center; justify-content: center; font-size: var(--fs-md);
    }
    /* `opacity: 0.45` measured 2.40:1 on the card fill — the worst contrast on
       the site. These are field labels ("PHONE / WHATSAPP"), not decoration. */
    .cc-lbl { font-size: var(--fs-2xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-muted); margin-bottom: var(--sp-2); font-family: var(--font-h); }
    .cc-val { font-size: var(--fs-base); font-weight: 600; font-family: var(--font-h); }
    .cc-val a { color: inherit; }
    .cc-val a:hover { text-decoration: underline; }

    /* C-05 — the assurance block that replaced the four contact cards beside
       the enquiry form on every page except /contact/.

       Deliberately quieter than `.cc`: no card fill, no hover lift, no icon.
       Those cards were styled as things to click, which is exactly what they
       should not have been — the one thing to act on in this column is the
       form. This is a plain definition list of four facts, with a single rule
       between rows to separate them, so it reads as reassurance the eye can
       skim past rather than a second menu of choices competing with the
       submit button. */
    .assure { display: flex; flex-direction: column; }
    .assure-item { padding: var(--sp-16) 0; border-bottom: 1px solid rgba(26,58,107,0.12); }
    .assure-item:first-child { padding-top: 0; }
    .assure-item:last-child { border-bottom: none; }
    .assure-lbl {
      font-family: var(--font-h); font-size: var(--fs-2xs); font-weight: 700;
      text-transform: uppercase; letter-spacing: 0.1em;
      color: var(--ink-muted); margin-bottom: var(--sp-4);
    }
    .assure-val { font-size: var(--fs-sm); font-weight: 500; line-height: var(--lh-snug); }
    .assure-prompt {
      font-family: var(--font-h); font-size: var(--fs-sm); font-weight: 700;
      color: var(--blue); margin-top: var(--sp-24); margin-bottom: var(--sp-8);
    }

    /* Form */
    .form-wrap {
      background: var(--cream-dark); border-radius: var(--radius-lg);
      /* Was a flat 36px 32px at every width: on a 375px screen that left only
         311px of usable field width. */
      padding: clamp(var(--sp-24), 5vw, var(--sp-32)) clamp(var(--sp-16), 4.5vw, var(--sp-32));
      box-shadow: var(--shadow);
    }
    /* REMOVED: `@media(min-width:1025px){ .form-wrap { margin-top: -250px } }`
       A magic number tuned for the homepage, where the contact heading is
       left-aligned and the form sits in the right column, so pulling the form
       up merely aligned it beside the heading.
       On /contact/ the heading block is `.ta-center`, so the centred <h2> and
       lede span the full container — and the form was dragged 250px UP ON TOP
       OF THEM. That was the reported overlap.
       It also pulled only `.form-wrap`, never `.contact-cards`, so the two
       columns started 250px apart on all ten pages that embed the form.
       Both columns now start on the same baseline. */
    .contact-grid > * { min-width: 0; }
    /* B-07: the form card ended flush against the next section, so on a phone
       the submit button and the consent line sat in the same band of screen as
       the FAB and whatever followed. The FAB now moves out of the way on its
       own (see `.wa-fab.is-near-form`); this gives the card itself somewhere
       to end. Scoped to the narrow breakpoint because at desktop widths the
       two-column grid already provides the gap. */
    @media (max-width: 768px) {
      .form-wrap { margin-bottom: var(--sp-32); }
    }
    .form-head { font-family: var(--font-h); font-size: var(--fs-lg); font-weight: 800; color: var(--blue); margin-bottom: var(--sp-4); }
    .form-sub { font-size: var(--fs-sm); color: var(--ink-muted); margin-bottom: var(--sp-24); }
    .fg { margin-bottom: var(--sp-16); }
    .fr { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-12); }
    label {
      font-size: var(--fs-2xs); font-weight: 700; font-family: var(--font-h);
      color: var(--blue); display: block; margin-bottom: var(--sp-4); letter-spacing: 0.04em;
    }
    /* font-size MUST stay >= 16px. iOS Safari zooms the viewport in whenever a
       focused control has a smaller font, and never zooms back out — so every
       tap on the enquiry form used to jerk the page. 1rem is the fix; the
       controls are only marginally taller as a result. */
    input, select, textarea {
      width: 100%; padding: var(--sp-12) var(--sp-12); border-radius: 7px;
      border: 1.5px solid rgba(26,58,107,0.14);
      background: var(--cream); color: var(--blue);
      font-family: var(--font-b); font-size: var(--fs-md);
      transition: var(--transition); outline: none; appearance: none;
    }
    input:focus, select:focus, textarea:focus {
      border-color: var(--blue); box-shadow: 0 0 0 3px rgba(26,58,107,0.09);
    }
    textarea { resize: vertical; min-height: 92px; }
    .form-btn {
      width: 100%; padding: var(--sp-12); background: var(--blue); color: var(--cream);
      font-family: var(--font-h); font-size: var(--fs-sm); font-weight: 700;
      border: none; border-radius: 8px; transition: var(--transition); letter-spacing: 0.04em;
    }
    .form-btn:hover { background: var(--blue-dark); transform: translateY(-2px); box-shadow: var(--shadow); }
    .form-btn[disabled] { opacity: 0.65; cursor: not-allowed; transform: none; box-shadow: none; }
    /* Clipped in place rather than parked at left:-9999px. A large negative
       offset still counts toward the document's scrollable width, which is how
       an invisible field ended up causing 18px of horizontal scroll on tablet.
       clip-path hides it without moving it. Still tabindex="-1" and
       aria-hidden in the markup, so it stays out of tab order and the a11y
       tree while remaining fillable by a bot. */
    .hp-field {
      position: absolute !important;
      width: 1px !important;
      height: 1px !important;
      margin: -1px !important;
      padding: 0 !important;
      overflow: hidden !important;
      clip: rect(0 0 0 0) !important;
      clip-path: inset(50%) !important;
      white-space: nowrap !important;
    }
    /* Per-field validation message, injected under its input by wearzo.js and
       tied to it with aria-describedby.

       BRAND OS: the palette is Wearzo Blue and Pure White only, so the error
       red (#A3231F) that used to carry this state is gone. The guidance is
       explicit that status must be expressed through icons, text, borders and
       weight rather than an off-brand colour — and WCAG 1.4.1 already required
       that colour not be the only signal, so nothing is lost by removing the
       one signal that was never sufficient on its own.

       What now marks an invalid field:
         · a "!" glyph before the message (::before, decorative — the message
           itself already names the problem, so it is aria-hidden by virtue of
           being generated content)
         · the message text, in bold
         · a 2px border and a 3px focus ring, both Wearzo Blue — twice the
           weight of a valid field's 1.5px hairline
         · aria-invalid + aria-describedby, which is what a screen reader
           actually acts on
       Blue at full strength on white is 8.6:1, comfortably past AA. */
    .field-err {
      display: none; margin-top: var(--sp-8);
      font-family: var(--font-h);
      font-size: var(--fs-xs); line-height: var(--lh-snug); font-weight: 700;
      color: var(--blue);
    }
    .field-err::before {
      content: '!';
      display: inline-flex; align-items: center; justify-content: center;
      width: 15px; height: 15px; margin-right: var(--sp-8);
      border: 1.5px solid currentColor; border-radius: 50%;
      font-size: 10px; font-weight: 900; line-height: 1;
      vertical-align: -2px;
    }
    input[aria-invalid="true"],
    select[aria-invalid="true"],
    textarea[aria-invalid="true"] { border-color: var(--blue); border-width: 2px; }
    input[aria-invalid="true"]:focus,
    select[aria-invalid="true"]:focus,
    textarea[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px rgba(26,58,107,0.30); }
    /* The confirmation receives focus when the form is replaced; it is
       programmatically focusable, so suppress the ring it would otherwise draw
       around a whole panel the user did not tab to. */
    .form-ok:focus { outline: none; }
    .form-ok:focus-visible { outline: 3px solid var(--blue); outline-offset: 2px; }

    /* Data-handling notice under the submit button. 4.6:1+ on white at this
       size, and the link is underlined so it does not rely on colour alone. */
    .form-consent {
      margin-top: var(--sp-12); font-size: var(--fs-xs); line-height: var(--lh-relaxed);
      color: rgba(26,58,107,0.78);
    }
    .form-consent a { color: var(--blue); font-weight: 600; text-decoration: underline; }

    .form-err {
      display: none;
      margin-top: var(--sp-12);
      padding: var(--sp-12) var(--sp-12);
      border-radius: 8px;
      /* Submission-failure banner. Same reasoning as .field-err above: the
         red is replaced by Wearzo Blue at full strength on a 5% tint, plus a
         left rule at 4px so the block reads as an alert at a glance and not
         merely as another card. role="alert" in the markup is what announces
         it; the styling is not carrying the meaning on its own. */
      border: 1px solid rgba(26,58,107,0.28);
      border-left: 4px solid var(--blue);
      background: var(--cream-dark);
      color: var(--blue);
      font-size: var(--fs-sm);
      font-weight: 600;
      font-family: var(--font-h);
    }
    .form-ok {
      display: none; padding: var(--sp-24);
      background: rgba(26,58,107,0.06); border-radius: 8px;
      font-family: var(--font-h); font-size: var(--fs-base); color: var(--blue);
    }
    /* CRO-07: the success state became a numbered sequence rather than one
       centred sentence, so it is left-aligned like every other block of
       instructions on the site. Centred text is fine for a line; it is poor
       for a list someone is meant to read and act on. */
    .fok-head { font-weight: 800; font-size: var(--fs-md); margin-bottom: var(--sp-12); }
    .fok-head::before { content: "\2705"; margin-right: var(--sp-8); }
    .fok-steps {
      list-style: decimal; padding-left: var(--sp-24); margin-bottom: var(--sp-16);
      font-family: var(--font-b); font-size: var(--fs-sm); line-height: var(--lh-relaxed);
    }
    .fok-steps li { margin-bottom: var(--sp-8); }
    .fok-prep {
      font-family: var(--font-b); font-size: var(--fs-xs); line-height: var(--lh-relaxed);
      color: rgba(26,58,107,0.78); padding: var(--sp-12);
      background: rgba(26,58,107,0.05); border-radius: 6px; margin-bottom: var(--sp-16);
    }
    .fok-actions { display: flex; flex-direction: column; gap: var(--sp-12); }
    .fok-sooner {
      font-family: var(--font-b); font-size: var(--fs-xs);
      line-height: var(--lh-relaxed); color: rgba(26,58,107,0.78);
    }

    /* ── Two-step enquiry (CRO-03) ───────────────────────────────────────── */
    /* `hidden` is set by wearzo.js. The rule is needed because `.fstep` would
       otherwise inherit a display value and defeat the attribute. */
    .fstep[hidden] { display: none; }

    .fstep-head {
      display: flex; align-items: center; gap: var(--sp-12);
      margin-bottom: var(--sp-16);
    }
    .fstep-ind {
      font-family: var(--font-h); font-size: var(--fs-2xs); font-weight: 700;
      text-transform: uppercase; letter-spacing: 0.1em;
      color: var(--ink-muted); white-space: nowrap;
    }
    .fstep-track {
      flex: 1; height: 4px; border-radius: 2px;
      background: rgba(26,58,107,0.14); overflow: hidden;
    }
    .fstep-bar {
      display: block; height: 100%; width: 50%;
      background: var(--blue); border-radius: 2px; transition: var(--transition);
    }
    .fstep-back {
      background: none; border: none; padding: 0 0 var(--sp-16) 0;
      font-family: var(--font-h); font-size: var(--fs-xs); font-weight: 700;
      color: var(--blue); text-decoration: underline; text-underline-offset: 3px;
      /* 44px target without adding visible height to the form. */
      min-height: 44px; display: inline-flex; align-items: center;
    }
    .fstep-back:hover { color: var(--blue-dark); }

    /* ── Trust strip above submit (CRO-04) ───────────────────────────────── */
    /* Deliberately plain: four facts, small, no icons and no card. It is there
       to be absorbed in the second before someone presses Send, not to compete
       with the button it sits above. */
    .trust-strip {
      list-style: none; margin: var(--sp-16) 0; padding: var(--sp-12) var(--sp-16);
      background: rgba(26,58,107,0.05); border-radius: 8px;
      display: flex; flex-direction: column; gap: var(--sp-8);
      font-family: var(--font-b); font-size: var(--fs-xs);
      line-height: var(--lh-snug); color: rgba(26,58,107,0.82);
    }
    .trust-strip li { display: flex; align-items: flex-start; gap: var(--sp-8); }
    .trust-strip li::before {
      content: "\2713"; color: var(--blue); font-weight: 700; flex-shrink: 0;
    }
    .trust-strip strong { color: var(--blue); font-weight: 700; }

    /* ============================================================
       TAGLINE BREAK
    ============================================================ */
    .tl-break {
      padding: var(--sp-64) 0; text-align: center;
      background:
        radial-gradient(circle at 16% 22%, rgba(255,255,255,0.16) 0, transparent 36%),
        radial-gradient(circle at 84% 78%, rgba(255,255,255,0.12) 0, transparent 34%),
        linear-gradient(135deg, #133360 0%, #1A3A6B 52%, #224A87 100%);
      position: relative;
      overflow: hidden;
    }
    .tl-break::before,
    .tl-break::after {
      content: '';
      position: absolute;
      border-radius: 999px;
      border: 1px solid rgba(255,255,255,0.18);
      pointer-events: none;
    }
    .tl-break::before {
      width: 420px;
      height: 420px;
      top: -280px;
      left: -120px;
    }
    .tl-break::after {
      width: 320px;
      height: 320px;
      bottom: -210px;
      right: -90px;
    }
    .tl-chip {
      display: inline-flex;
      align-items: center;
      gap: var(--sp-8);
      padding: var(--sp-8) var(--sp-16);
      border-radius: 999px;
      border: 1px solid rgba(255,255,255,0.28);
      background: rgba(255,255,255,0.08);
      font-family: var(--font-h);
      font-size: var(--fs-3xs);
      font-weight: 700;
      letter-spacing: 0.16em;
      text-transform: uppercase;
      color: rgba(255,255,255,0.9);
      margin-bottom: var(--sp-16);
    }
    .tl-big {
      font-family: var(--font-h); font-size: clamp(1.65rem,3vw,2.85rem);
      font-weight: 900; color: var(--cream); line-height: var(--lh-tight); max-width: 760px;
      margin: 0 auto var(--sp-12);
    }
    .tl-big span { display: block; opacity: 0.8; font-size: 0.86em; margin-top: var(--sp-8); }
    .tl-sub {
      font-size: clamp(0.92rem,1.55vw,1.04rem);
      color: rgba(255,255,255,0.72);
      max-width: 620px;
      line-height: var(--lh-relaxed);
      margin: 0 auto 0;
    }

    /* ============================================================
       MODALS
    ============================================================ */
.modal.open { display: flex; }
.modal-body h4:first-child { margin-top: 0; }
/* ============================================================
       FOOTER
    ============================================================ */
    footer {
      background: var(--blue-dark); padding: var(--sp-64) 0 0;
    }
    /* Generated pages ship five footer columns (brand + Range + Guides +
       Company + Contact); the frozen hand-built pages ship four. auto-fit sizes
       whichever arrives — a fixed track list would leave an empty column on the
       frozen pages. It must NOT be combined with a leading `fr` track: the
       repeat then resolves to a single column and the whole footer stacks. */
    .ft-grid {
      display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
      gap: var(--sp-32); margin-bottom: var(--sp-32);
    }
    .ft-logo-row { display: flex; align-items: center; gap: var(--sp-12); margin-bottom: var(--sp-12); }
    .ft-logo-row img { height: 30px; filter: none; }
    .ft-logo-row span { font-family: var(--font-h); font-size: var(--fs-base); font-weight: 800; color: var(--cream); }
    /* Footer text sits on --blue-dark. Alphas below ~0.70 fall under the WCAG
       1.4.3 4.5:1 floor at these sizes — 0.46 measured 4.18:1 and 0.30 measured
       2.59:1. Values below are the lowest that still clear 4.5:1. */
    .ft-tag { font-size: var(--fs-xs); color: rgba(255,255,255,0.72); font-style: italic; margin-bottom: var(--sp-12); }
    .ft-desc { font-size: var(--fs-sm); color: rgba(255,255,255,0.72); line-height: var(--lh-relaxed); max-width: 250px; }
    .ft-social { display: flex; gap: var(--sp-8); margin-top: var(--sp-16); }
    .soc-btn {
      width: 44px; height: 44px; border-radius: 9px;
      background: rgba(255,255,255,0.10); border: 1px solid rgba(255,255,255,0.16);
      display: flex; align-items: center; justify-content: center;
      color: rgba(255,255,255,0.82); font-size: var(--fs-xs);
      transition: var(--transition);
    }
    .soc-btn:hover { background: rgba(255,255,255,0.13); color: var(--cream); }
    .soc-btn svg { width: 14px; height: 14px; }
    .ft-col-h {
      font-family: var(--font-h); font-size: var(--fs-xs); font-weight: 700;
      text-transform: uppercase; letter-spacing: 0.14em;
      color: rgba(255,255,255,0.78); margin-bottom: var(--sp-12);
    }
    .ft-links { display: flex; flex-direction: column; gap: var(--sp-8); }
    /* Footer links were 15px tall — below the WCAG 2.2 2.5.8 24x24 minimum and
       awkward to hit on a phone. Vertical padding brings each to 24px+ without
       changing the visual rhythm much. `padding-left` on hover is kept but is
       now part of the base padding so the row does not jump. */
    .ft-links a {
      font-size: var(--fs-sm); color: rgba(255,255,255,0.78);
      display: block; padding: var(--sp-4) 0 var(--sp-4) 0; min-height: 24px;
      transition: color 0.32s cubic-bezier(0.4,0,0.2,1), padding-left 0.32s cubic-bezier(0.4,0,0.2,1);
    }
    .ft-links a:hover { color: var(--cream); padding-left: var(--sp-4); }
    .ft-addr { font-size: var(--fs-xs); color: rgba(255,255,255,0.72); line-height: var(--lh-relaxed); margin-top: var(--sp-12); }
    .ft-bottom {
      border-top: 1px solid rgba(255,255,255,0.07);
      padding: var(--sp-16) 0;
      display: flex; align-items: center; justify-content: space-between;
      gap: var(--sp-12); flex-wrap: wrap;
    }
    .ft-copy { font-size: var(--fs-xs); color: rgba(255,255,255,0.72); }
    .ft-legal { display: flex; gap: var(--sp-16); }
    /* These were rgba(255,255,255,0.30) = 2.59:1 — Privacy Policy, Terms and
       Sitemap, on all 68 pages, well under the 4.5:1 floor. The pass that
       raised the rest of the footer to >=0.70 missed this rule. */
    .ft-legal a { font-size: var(--fs-3xs); color: var(--on-blue-muted); transition: var(--transition); }
    .ft-legal a:hover { color: var(--cream); }

    /* ============================================================
       FLOATING ELEMENTS
    ============================================================ */
    /* C-06 — the WhatsApp FAB, on the terms the audit set.

       Three changes, each with its own reason:

       1. MOBILE ONLY. It is hidden from 769px up. WhatsApp Web exists, but a
          buyer evaluating a manufacturer on a laptop enquires by form or by
          email; the FAB there was one of three permanent overlays (fixed
          header, FAB, go-top) eating the corners of every page for an action
          almost nobody takes on that device.
       2. NO PERPETUAL ANIMATION. `animation: float 3.2s infinite` ran for as
          long as the page was open. A control that never stops moving never
          stops asking, and it competed with whatever the visitor was actually
          reading — including, on ten pages, the enquiry form itself.
       3. IT GETS OUT OF THE WAY. `.is-near-form` is set by wearzo.js while the
          enquiry form is on screen (B-07): on a phone the FAB sat exactly
          where the submit button lands. Fading rather than `display: none`
          keeps it from reflowing, and `visibility` keeps it out of the tab
          order while hidden. */
    .wa-fab {
      position: fixed; bottom: 26px; right: 26px; z-index: 998;
      display: flex; align-items: center; gap: var(--sp-8);
      /* BRAND OS: was WhatsApp green (#25D366) — the one non-blue, non-white
         fill left on the site, and a third party's brand colour rather than
         Wearzo's. The glyph identifies the channel perfectly well without it;
         a green pill on a blue site read as a foreign object anyway. */
      background: var(--blue); color: #FFFFFF;
      padding: var(--sp-12) var(--sp-24); border-radius: 50px;
      border: 1.5px solid rgba(255,255,255,0.28);
      box-shadow: 0 6px 22px rgba(26,58,107,0.42);
      font-family: var(--font-h); font-size: var(--fs-xs); font-weight: 700;
      transition: var(--transition);
    }
    .wa-fab:hover { transform: translateY(-4px) scale(1.03); box-shadow: 0 10px 28px rgba(26,58,107,0.52); }
    .wa-fab svg { width: 18px; height: 18px; flex-shrink: 0; }
    .wa-fab.is-near-form {
      opacity: 0; visibility: hidden; transform: translateY(8px);
    }
    @media (min-width: 769px) {
      .wa-fab { display: none; }
    }

    .go-top {
      position: fixed; bottom: 26px; left: 26px; z-index: 998;
      width: 42px; height: 42px; border-radius: 9px;
      background: var(--blue); color: var(--cream);
      border: none; display: flex; align-items: center; justify-content: center;
      font-size: var(--fs-base); box-shadow: var(--shadow-sm);
      opacity: 0; transform: translateY(10px); transition: var(--transition);
    }
    .go-top.vis { opacity: 1; transform: none; }
    .go-top:hover { background: var(--blue-dark); transform: translateY(-2px); }

    @media (prefers-reduced-motion: reduce) {
      [data-r], [data-rl] {
        opacity: 1;
        transform: none;
        transition: none;
      }
      .wa-fab, .pc-icon {
        animation: none;
      }
      .hero-text,
      .hero-media,
      .hero-cards {
        animation: none !important;
        transition: none !important;
      }
      /* Smooth scrolling is itself motion: jumping the viewport several
         thousand pixels is exactly what a vestibular-disorder user turns this
         setting on to avoid. Applies to in-page anchors and the go-top button,
         which passes behavior:'smooth' — the media query overrides it. */
      html { scroll-behavior: auto; }
      /* Nothing should animate for longer than an instant. */
      *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
      }
    }

    /* The marquee pause-toggle rules that stood here are gone with the
       marquee itself — the client logos are a static grid now, so there is no
       animation to pause and no control to render. */

    /* Guide provenance line, under the hero lede on /resources/ pages. */
    .byline {
      display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-8);
      margin-top: var(--sp-16); font-size: var(--fs-sm); color: rgba(255,255,255,0.78);
    }
    .byline strong { color: var(--cream); font-weight: 600; }
    .byline-sep { opacity: 0.5; }

    /* ============================================================
       SIBLING PRODUCT LINKS
       Chips rather than cards: this is a wayfinding row, not a feature grid,
       and chips keep it compact enough to sit above the FAQ without pushing
       the enquiry CTA off a phone screen. Targets are 44px tall.
    ============================================================ */
    .sibling-list {
      display: flex; flex-wrap: wrap; gap: var(--sp-12); margin-top: var(--sp-24); padding: 0;
    }
    .sibling-list a {
      display: inline-flex; align-items: center; min-height: 44px;
      padding: var(--sp-12) var(--sp-16); border-radius: 100px;
      background: var(--cream); border: 1.5px solid rgba(26,58,107,0.16);
      font-family: var(--font-h); font-size: var(--fs-sm); font-weight: 600;
      color: var(--blue);
      transition: background 0.32s cubic-bezier(0.4,0,0.2,1),
                  border-color 0.32s cubic-bezier(0.4,0,0.2,1),
                  transform 0.32s cubic-bezier(0.4,0,0.2,1);
    }
    .sibling-list a:hover {
      background: var(--cream-dark); border-color: var(--blue); transform: translateY(-2px);
    }
    .sibling-list .sibling-all {
      background: var(--blue); color: var(--cream); border-color: var(--blue);
    }
    .sibling-list .sibling-all:hover { background: var(--blue-dark); }

    /* ============================================================
       ACCESSIBILITY: visible keyboard focus + skip link
    ============================================================ */
    :where(a, button, summary, select, input, textarea, [tabindex]):focus-visible {
      outline: 3px solid var(--blue);
      outline-offset: 2px;
      border-radius: 3px;
    }

    /* WCAG 2.2 AA 2.5.8 (Target Size, Minimum) — 24x24 CSS px.
       These inline links sat at 20-21px tall: the "View X →" link inside each
       product card, and the quick-link / contact lists on the homepage. Padding
       lifts the hit area without moving the text, so no layout changes. */
    .pc-link,
    .cc-val a,
    .ft-legal a {
      display: inline-flex; align-items: center; min-height: 24px;
      padding-block: var(--sp-2);
    }
    /* .ft-legal is a flex row with a 20px gap, so raising the links to 24px
       does not push anything: the row simply gets its natural height back. */
    .ft-legal { align-items: center; }
    .section--blue :focus-visible,
    .lp-hero :focus-visible,
    .hdr :focus-visible,
    .mob-menu :focus-visible,
    .wa-fab:focus-visible {
      outline-color: var(--cream);
    }
    input:focus, select:focus, textarea:focus {
      box-shadow: 0 0 0 3px rgba(26,58,107,0.35);
    }
    .skip-link {
      position: absolute; left: 0; top: -100px; z-index: 2000;
      background: var(--cream); color: var(--blue);
      font-family: var(--font-h); font-weight: 700; font-size: var(--fs-sm);
      padding: var(--sp-12) var(--sp-16); border-radius: 0 0 8px 0;
    }
    .skip-link:focus { top: 0; }
    .sr-only {
      position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
      overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
    }

    /* ============================================================
       RESPONSIVE
    ============================================================ */
    /* B-05: this block used to shrink nav padding to 9px/0.79rem AND hide the
       wordmark to fit logo + 7 nav items + phone + CTA + burger on one row. Four
       triggers and no phone button removed the pressure at source (Phase 2), so
       only the wordmark still goes — and only below 1000px, where the row is
       genuinely tight rather than merely narrow. */
    @media(min-width:769px) and (max-width:999px){
      .hdr-logo-name { display: none; }
      .nav-trigger { padding: var(--sp-8) var(--sp-12); font-size: var(--fs-xs); }
      .hdr-inner { gap: var(--sp-12); }
    }
    @media(max-width:1024px){
      .hero-cards { grid-template-columns: repeat(2,minmax(0,1fr)); }
      /* The proof strip stays a strip, not a 2-column block: three across is
         still compact and keeps the band shallow. */
      .proof-strip { grid-template-columns: repeat(3,minmax(0,1fr)); }
      /* Four figures go 2x2, never 3+1 with an orphan on its own row. */
      .proof-strip--4 { grid-template-columns: repeat(2,minmax(0,1fr)); }
      .why-grid { grid-template-columns: repeat(2,1fr); }
      .products-grid { grid-template-columns: repeat(2,1fr); }
      .ft-grid { grid-template-columns: 1fr 1fr; }
      .vas-row { grid-template-columns: repeat(3,1fr); }
    }
    @media(max-width:768px){
      .hero {
        min-height: auto;
        align-items: flex-start;
        padding-top: var(--sp-96);
        padding-bottom: var(--sp-64);
      }
      /* .hero--full outranks .hero, so the full-screen floor has to be
         released by name. On a phone the hero stacks to text + photograph +
         a 2x2 stat grid and is far past a screen tall on its own; pinning a
         100svh floor under it would only add dead space at the bottom. */
      .hero--full { min-height: auto; }
      .hero-content { grid-template-columns: 1fr; }
      .hero-sub { margin-bottom: var(--sp-16); }
      /* The hero photograph stacks under the text on a phone and is capped so
         it cannot push the CTAs off the first screen. It stays visible: for a
         manufacturer the floor is the strongest single trust signal, and
         mobile is where most of this site's traffic is. */
      .hero-media { margin-top: var(--sp-24); }
      .hero-media img { max-height: 46vh; }
      .hero-cards {
        display: grid;
        grid-template-columns: repeat(2,minmax(0,1fr));
        gap: var(--sp-12);
      }
      .hc { min-height: 120px; padding: var(--sp-16) var(--sp-12); border-radius: 12px; }
      .hc-num { font-size: clamp(1.45rem,6.6vw,1.95rem); }
      .hc-lbl { font-size: var(--fs-2xs); line-height: var(--lh-snug); }
      .about-grid { grid-template-columns: 1fr; }
      /* The factory photo used to be display:none below 768px. For a
         manufacturer it is the single strongest trust signal on the page, and
         mobile is where most of this site's traffic is — hiding it there
         removed the proof from the audience that most needs it. It is shown,
         capped in height so it cannot dominate the fold, and ordered after the
         copy so the heading still leads. */
      /* width:100% is REQUIRED, not decorative. `margin-inline: auto` on a grid
         item overrides the default `stretch`, so the item sizes to its content
         — and the only content is .about-frame, which has an aspect-ratio but
         no intrinsic width. Without an explicit width the whole block collapsed
         to 0x0 and the photo vanished on every phone. */
      .about-img-block {
        display: block; order: 2;
        width: 100%; max-width: 320px; margin: var(--sp-24) auto 0;
      }
      .about-frame { aspect-ratio: 4/5; }
      .team-grid { grid-template-columns: 1fr; }
      .srv-grid { grid-template-columns: 1fr; }
      .products-grid { grid-template-columns: 1fr; }
      /* Tablet: two tiles per row, still big enough to read the mark. */
      .client-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
      .cl-card { min-width: 0; height: 132px; padding: var(--sp-16); }
      .cl-card img { max-height: 96px; max-width: 152px; }
      /* REMOVED: the `.pc-media` and `.pc-slide` mobile overrides. They existed
         to undo the desktop hover-reveal on touch, where hover does not exist.
         The base rule now shows the image at every width, so re-stating it here
         would only be a second place for the height to drift. */
      .contact-grid { grid-template-columns: 1fr; }
      .why-grid { grid-template-columns: 1fr 1fr; }
      .process-row { grid-template-columns: repeat(2,1fr); gap: var(--sp-24) 0; margin-top: var(--sp-64); }
      .process-row .pr-step:nth-child(n) { grid-column: auto; grid-row: auto; }
      /* Two columns: the base geometry already holds, so only the row-end
         selector changes. Everything the desktop rule set stays set. */
      .pr-step:nth-child(4n)::before,
      .pr-step:nth-child(4n)::after { display: block; }
      .pr-step:nth-child(2n)::before,
      .pr-step:nth-child(2n)::after,
      .pr-step:last-child::before,
      .pr-step:last-child::after { display: none; }
      .stats-row { flex-wrap: wrap; }
      .stat { flex: 0 0 50%; border-bottom: 1px solid rgba(255,255,255,0.07); }
      /* Mobile header: the mega menu collapses into the burger, but the primary
         conversion control STAYS. It was once hidden too, leaving the mobile
         header with nothing but a logo and a burger — removing the quote CTA
         from the device class that carries most of this site's traffic. Room is
         made by dropping the wordmark text (the logo mark and the link's
         aria-label still identify it) rather than by dropping the CTA. Phone is
         no longer here at all (CRO-02); it lives in the drawer's secondary row. */
      nav.main-nav { display: none; }
      .hdr-logo-name { display: none; }
      .hdr-cta { padding: var(--sp-12) var(--sp-12); font-size: var(--fs-xs); }
      .burger { display: flex; }
      .vas-row { grid-template-columns: repeat(2,1fr); }
      .ft-grid { grid-template-columns: 1fr 1fr; }
      .fr { grid-template-columns: 1fr; }
    }
    @media(max-width:480px){
      .hero { padding-top: var(--sp-96); padding-bottom: var(--sp-48); }
      .hero-pill { margin-bottom: var(--sp-16); }
      .hero-h1 { margin-bottom: var(--sp-12); }
      .hero-cards { gap: var(--sp-8); }
      .proof-strip, .proof-strip--4 { grid-template-columns: repeat(2,minmax(0,1fr)); }
      .hc { min-height: 112px; padding: var(--sp-12) var(--sp-12); }
      .hc-lbl { font-size: var(--fs-3xs); }
      .why-grid { grid-template-columns: 1fr; }
      .stat { flex: 0 0 100%; }
      .ft-grid { grid-template-columns: 1fr; }
      .process-row { grid-template-columns: 1fr; }
      .process-row { gap: var(--sp-32); }
      .process-row .pr-step:nth-child(n) { grid-column: auto; grid-row: auto; }
      .pr-step { padding-bottom: var(--sp-12); }
      /* One column: the connector turns vertical and runs into the next step's
         circle instead of across to it. Only :last-child ends the chain. */
      .pr-step::before,
      .pr-step::after,
      .pr-step:nth-child(4n)::before,
      .pr-step:nth-child(4n)::after,
      .pr-step:nth-child(2n)::before,
      .pr-step:nth-child(2n)::after {
        display: block;
      }
      .pr-step::after {
        left: 50%;
        top: calc(100% - 4px);
        width: 0;
        height: 26px;
        border-top: none;
        border-left: 2px dashed rgba(26,58,107,0.34);
        transform: translateX(-50%);
      }
      .pr-step::before {
        left: auto;
        top: auto;
        right: 50%;
        bottom: -7px;
        width: 10px;
        height: 10px;
        border-top: none;
        border-right: 2px solid rgba(26,58,107,0.52);
        border-bottom: 2px solid rgba(26,58,107,0.52);
        transform: translateX(50%) rotate(45deg);
      }
      .pr-step:last-child::before,
      .pr-step:last-child::after { display: none; }
      .hero-assurance { width: 100%; justify-content: center; }
      /* 390px: two per row at 150px wide. The old 92px tile with a 56px cap
         is exactly the "unclear at phone size" the reviewer called out. */
      .client-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-12); }
      .cl-card { min-width: 0; height: 116px; padding: var(--sp-12); }
      .cl-card img { max-height: 84px; max-width: 132px; }
}

    /* ============================================================
       LANDING / SEGMENT PAGE COMPONENTS  (shared across money pages)
    ============================================================ */
    .crumbs { background: var(--blue); padding-top: var(--sp-96); }
    .crumbs .c { display: flex; flex-wrap: wrap; gap: var(--sp-8); align-items: center;
      font-family: var(--font-h); font-size: var(--fs-xs); color: rgba(255,255,255,0.78); }
    /* WCAG 2.5.8 Target Size (Minimum), 24x24 CSS px. A breadcrumb link is a
       STANDALONE navigation control, not a link inside a sentence, so the
       inline exception does not cover it — and these measured 38x20, failing on
       height at every breakpoint. Vertical padding takes the hit area past 24px
       without moving anything: the row is already `align-items: center` with a
       flex gap, so the extra height is absorbed by the band. */
    .crumbs a {
      color: rgba(255,255,255,0.82);
      display: inline-flex; align-items: center;
      min-height: 24px; padding-block: var(--sp-4);
    }
    .crumbs a:hover { color: #fff; text-decoration: underline; }
    .crumbs .sep { opacity: 0.4; }
    .crumbs [aria-current] { color: #fff; font-weight: 600; }

    /* Phase 11 (L-09): the hero used to pin a ~60ch text block to the left of
       a 1200px container, leaving the right half of every generated page's
       first screen empty — the single biggest "looks unfinished" signal on the
       site. The block is now centred: same copy, same measures, balanced page.
       Everything inside is measure-capped, so centring costs no readability. */
    .lp-hero { background: var(--blue); color: var(--cream); text-align: center;
      padding: var(--sp-32) 0 clamp(var(--sp-48),7vw,var(--sp-64)); }
    .lp-hero .eyebrow { font-family: var(--font-h); font-size: var(--fs-2xs); font-weight: 700;
      letter-spacing: 0.16em; text-transform: uppercase; color: rgba(255,255,255,0.72);
      display: inline-block; margin-bottom: var(--sp-12); }
    .lp-hero h1 { font-family: var(--font-h); font-weight: 900; line-height: var(--lh-tight);
      font-size: clamp(1.85rem,4.1vw,3rem); margin-bottom: var(--sp-16); max-width: 24ch;
      margin-inline: auto; }
    .lp-hero .hero-lede { font-size: clamp(1rem,1.5vw,1.12rem); line-height: var(--lh-relaxed);
      color: rgba(255,255,255,0.82); max-width: 62ch; margin-bottom: var(--sp-24);
      margin-inline: auto; }
    .lp-hero .trust-row,
    .lp-hero .hero-ctas { justify-content: center; }
    .lp-hero .byline { justify-content: center; }
    .trust-row { display: flex; flex-wrap: wrap; gap: var(--sp-12); margin-bottom: var(--sp-24); }
    .trust-pill { font-family: var(--font-h); font-size: var(--fs-2xs); font-weight: 600;
      background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.18);
      padding: var(--sp-8) var(--sp-12); border-radius: 100px; color: rgba(255,255,255,0.9); }
    .hero-ctas { display: flex; flex-wrap: wrap; gap: var(--sp-12); }
    .hero .hero-ctas { margin-top: var(--sp-32); }
    .hero .hero-assurance { margin-top: var(--sp-16); }

    .prose { max-width: var(--measure-prose); }
    .prose > * + * { margin-top: var(--sp-16); }
    .prose p { font-size: var(--fs-md); line-height: var(--lh-relaxed); color: rgba(26,58,107,0.82); }
    .section--blue .prose p { color: rgba(255,255,255,0.82); }
    .prose h3 { font-family: var(--font-h); font-weight: 800; font-size: var(--fs-lg); margin-top: var(--sp-24); }
    .prose ul { display: grid; gap: var(--sp-8); }
    .prose ul li { position: relative; padding-left: var(--sp-24); line-height: var(--lh-relaxed);
      font-size: var(--fs-base); color: rgba(26,58,107,0.82); }
    .prose ul li::before { content: '✓'; position: absolute; left: 0; top: 0;
      color: var(--blue); font-weight: 800; }

    .lead-grid { display: grid; grid-template-columns: repeat(auto-fit,minmax(230px,1fr)); gap: var(--sp-16); margin-top: var(--sp-32); }
    .info-card { background: var(--cream); border: 1px solid var(--cream-mid);
      border-radius: var(--radius); padding: var(--sp-24); box-shadow: var(--shadow-sm); }
    .info-card h3 { font-family: var(--font-h); font-weight: 800; font-size: var(--fs-md); margin-bottom: var(--sp-8); }
    .info-card p { font-size: var(--fs-sm); line-height: var(--lh-relaxed); color: rgba(26,58,107,0.74); }
    a.info-card { display: block; transition: var(--transition); }
    a.info-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--blue-light); }
    a.info-card .seg-go { font-family: var(--font-h); font-weight: 700; font-size: var(--fs-xs); color: var(--blue-light); margin-top: var(--sp-12); display: inline-block; }
    .pc-link { display: inline-block; margin-top: var(--sp-16); font-family: var(--font-h); font-weight: 700; font-size: var(--fs-sm); color: var(--blue); }
    .pc-link:hover { color: var(--blue-light); text-decoration: underline; }
    .section--blue .pc-link { color: var(--cream); }
    .ft-creds { font-size: var(--fs-xs); line-height: var(--lh-snug); color: rgba(255,255,255,0.75); margin-bottom: var(--sp-12); letter-spacing: 0.01em; }

    /* Closing aside under a section — quieter and smaller than the section's
       own lead, so it reads as a footnote rather than a second intro. */
    .section-note { margin-top: var(--sp-24); font-size: var(--fs-sm); }
    .section-note a { color: var(--blue); text-decoration: underline; font-weight: 600; }
    .section--blue .section-note a { color: var(--cream); }

    .uchip-grid { display: flex; flex-wrap: wrap; gap: var(--sp-12); margin-top: var(--sp-24); }
    .uchip { font-family: var(--font-h); font-size: var(--fs-sm); font-weight: 600;
      background: var(--cream); border: 1px solid var(--cream-mid); color: var(--blue);
      padding: var(--sp-12) var(--sp-16); border-radius: 8px; box-shadow: var(--shadow-sm); }

    .img-grid { display: grid; grid-template-columns: repeat(auto-fit,minmax(200px,1fr)); gap: var(--sp-12); margin-top: var(--sp-32); }
    .img-grid img { border-radius: var(--radius); box-shadow: var(--shadow-sm);
      width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4/5; background: var(--cream-dark); }

    .spec-table-wrap { overflow-x: auto; margin-top: var(--sp-32); border-radius: var(--radius); box-shadow: var(--shadow-sm); }
    table.spec-table { width: 100%; border-collapse: collapse; background: var(--cream); font-size: var(--fs-sm); min-width: 640px; }
    /* Phase 11.6 — the literal "boxes are being cut" bug. Spec tables authored
       inside `.prose` sit in a 68ch (~612px) column, and min-width: 640px made
       every one of them clip ~30px of its right edge behind the wrap's
       overflow at ALL desktop widths (31 product pages). Inside prose the
       table wraps its cell text instead of scrolling; the min-width stays for
       tables rendered outside a measure-capped column. */
    .prose table.spec-table { min-width: 0; }

    table.spec-table th, table.spec-table td { text-align: left; padding: var(--sp-12) var(--sp-16); border-bottom: 1px solid var(--cream-mid); vertical-align: top; }
    table.spec-table thead th { background: var(--blue); color: var(--cream); font-family: var(--font-h); font-weight: 700; font-size: var(--fs-xs); letter-spacing: 0.02em; }
    table.spec-table tbody tr:last-child td { border-bottom: none; }
    /* Row headers replaced the bolded first <td>, so the weight rule follows. */
    table.spec-table tbody th[scope="row"] {
      font-weight: 600; color: var(--blue); white-space: nowrap;
      background: var(--cream-dark); width: 1%;
    }
    table.spec-table caption {
      caption-side: top; text-align: left;
      padding: var(--sp-12) var(--sp-16); background: var(--blue); color: var(--cream);
      font-family: var(--font-h); font-weight: 700; font-size: var(--fs-xs);
      letter-spacing: 0.04em; text-transform: uppercase;
    }

    /* B-08: below 640px the table becomes a stack of labelled cards.

       It was `min-width: 640px` inside an `overflow-x: auto` wrapper — which
       contains the overflow but shows a 375px visitor 54% of a fabric table
       with no visible affordance that the rest exists. These tables are the
       specification a buyer is trying to read; hiding half of them behind a
       horizontal scroll nobody signals is the worst outcome for the page's most
       load-bearing content.

       Each cell carries a `data-label` naming its column (injected in build.py
       from the table's own <thead>, so it cannot drift), which is what makes a
       stacked cell readable without its header row. */
    @media (max-width: 640px) {
      .spec-table-wrap { overflow-x: visible; box-shadow: none; }
      table.spec-table { min-width: 0; background: transparent; }
      table.spec-table caption { text-align: left; }
      /* The header row is redundant once every cell states its own column, and
         `display: none` on a <thead> keeps it out of the a11y tree too — the
         data-label text replaces it visually, and the reading order of a
         stacked card is label, value, label, value. */
      table.spec-table thead { display: none; }
      table.spec-table, table.spec-table tbody, table.spec-table tr, table.spec-table td,
      table.spec-table th { display: block; width: auto; }
      table.spec-table tbody tr {
        background: var(--cream); border: 1.5px solid rgba(26,58,107,0.10);
        border-radius: var(--radius); box-shadow: var(--shadow-sm);
        padding: var(--sp-4) var(--sp-16) var(--sp-12);
        margin-bottom: var(--sp-16);
      }
      table.spec-table tbody td, table.spec-table tbody th {
        border-bottom: none; padding: var(--sp-8) 0 0;
      }
      table.spec-table tbody td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-family: var(--font-h); font-size: var(--fs-3xs); font-weight: 700;
        letter-spacing: 0.04em; text-transform: uppercase;
        color: var(--ink-soft);
        margin-bottom: 2px;
      }
      /* The first cell is the row's subject — render it as the card's title. */
      table.spec-table tbody tr > :first-child {
        font-family: var(--font-h); font-weight: 700; color: var(--blue);
        font-size: var(--fs-md);
        padding-top: var(--sp-12);
      }
      table.spec-table tbody tr > :first-child::before { color: var(--ink-muted); }
      /* The row header is `white-space: nowrap; width: 1%` in table layout —
         correct there, because it keeps the subject column from wrapping while
         the table scrolls. Stacked, both are actively harmful: `nowrap` makes
         "Polyester / poly-blend lightweight woven (gown fabric)" a single
         451px line that no 320px screen can contain, and `width: 1%` collapses
         the box to 3px so the text escapes it entirely. This is what pushed
         four sector hubs into horizontal overflow. */
      table.spec-table tbody th[scope="row"] {
        background: none;
        white-space: normal;
        width: auto;
        overflow-wrap: anywhere;
      }
    }

    .faq-list { max-width: 820px; margin: var(--sp-32) auto 0; }
    .faq-item { background: var(--cream); border: 1px solid var(--cream-mid); border-radius: var(--radius); margin-bottom: var(--sp-12); overflow: hidden; }
    .faq-item summary { cursor: pointer; list-style: none; padding: var(--sp-16) var(--sp-24); font-family: var(--font-h); font-weight: 700; font-size: var(--fs-md); color: var(--blue); display: flex; justify-content: space-between; gap: var(--sp-16); align-items: center; }
    .faq-item summary::-webkit-details-marker { display: none; }
    .faq-item summary::after { content: '+'; font-size: var(--fs-xl); font-weight: 400; line-height: var(--lh-none); color: var(--blue-light); flex-shrink: 0; transition: transform 0.25s ease; }
    .faq-item[open] summary::after { transform: rotate(45deg); }
    .faq-item .faq-a { padding: 0 var(--sp-24) var(--sp-24); font-size: var(--fs-base); line-height: var(--lh-relaxed); color: rgba(26,58,107,0.8); }

    .cta-band { text-align: center; }
    .cta-band h2 { color: var(--cream); }
    .cta-band .lead { color: rgba(255,255,255,0.82); margin-inline: auto; }
    .cta-band .hero-ctas { justify-content: center; margin-top: var(--sp-24); }

    @media (max-width: 700px) {
      .lp-hero h1 { max-width: 100%; }
    }

    /* Below 480px a CTA row stacks and each button fills the width.
       `.btn` is `white-space: nowrap`, so a long label could not wrap and simply
       ran off the side — "Download Company Profile (PDF, 6.1 MB)" measured 347px
       inside a 294px container at 320px viewport. It never showed as a scrollbar
       because `html, body { overflow-x: hidden }` was silently clipping it,
       which is exactly why that rule is scheduled for removal.
       Stacking also gives every CTA a full-width tap target on a phone. */
    @media (max-width: 480px) {
      .hero-ctas { flex-direction: column; align-items: stretch; }
      .hero-ctas .btn { justify-content: center; white-space: normal; text-align: center; }
    }

    /* ============================================================
       PRINT STYLES
    ============================================================ */
    @media print {
      .hdr, .wa-fab, .go-top, .mob-menu, .modal { display: none !important; }
      .hero { min-height: auto; padding-top: var(--sp-24); }
      * { print-color-adjust: exact; }
    }
