/** Shopify CDN: Minification failed

Line 852:28 Expected identifier but found whitespace
Line 852:47 Unexpected "767"
Line 853:78 Unterminated string token

**/
/* ============================================================================
   rcds-tokens.css — RolaCase US Design System, token layer
   ----------------------------------------------------------------------------
   Target   : LIVE theme 156872999214 (Wpbingo 1.0.2) · staged on 188393783598
   Source   : homepage-preview/v13/styles.css (approved design, 1124 lines)
   Owner    : Jeko
   Built    : 2026-07-24
   Load     : FIRST, before any rcds-*.css component sheet.
              <link rel="stylesheet" href="{{ 'rcds-tokens.css' | asset_url }}">
              Must be a real asset link, NOT {% stylesheet %} — that tag has been
              auto-subset per page since 2026-04-20 and would strip tokens that
              only a later-loaded component references. It also does not render
              Liquid, so it cannot carry settings-driven values.

   ----------------------------------------------------------------------------
   THE FIVE CONTRACTS THIS FILE ENFORCES
   ----------------------------------------------------------------------------
   1. EVERY name is `--rcds-*`. Zero overlap with the live theme's 40 body{} tokens
      (--theme-color, --gray-dark, --font-size-base …) and zero overlap with the
      ~47-61 Liquid-injected props (--col*, --title-*, --price-*), which are a
      FROZEN API. This file is purely additive. It renames nothing.

   2. ZOOM. layout/theme.liquid:372 ships `body{zoom:0.80}` and it stays.
      (Rule opens at :372, declaration on :373. Cite 372 — that is the line you
      delete if the zoom is ever retired. Every file in this system says 372.)
      Consequences, all measured:
        · A CSS length L inside body renders at 0.8·L device px.
        · `zoom:1` on a descendant is a NO-OP (zoom multiplies down the tree:
          0.8 × 1 = 0.8). The only counter is `zoom:1.25` (0.8 × 1.25 = 1).
        · One real viewport of height = 125vh of authored CSS.
        · Media queries evaluate on the REAL viewport, which is unaffected by
          zoom on a descendant. The layout box is viewport ÷ 0.8.
      Therefore, and this is the whole trick:
        · LENGTHS scale UP   ×1.25  (var(--rcds-z))     — see §1
        · BREAKPOINTS scale DOWN ×0.80                — see §10
      Both derive from the single 0.80. Flip --rcds-z to 1 and delete the
      breakpoint table if zoom:0.80 is ever removed. Nothing else changes.

   3. CASCADE. The live cascade carries 1,292 !important across assets/*.css
      (1,726 counting the inline <style> in theme.liquid and section files) plus
      ~908KB of inline <style>. Tokens do NOT fight that: a custom property only
      competes with another declaration of the SAME name, and the theme never
      writes --rcds-*. Components must be self-sufficient inside `.rcds-scope`
      (see §14) rather than trying to out-specify the theme globally.

   4. UNDECLARED v13 TOKENS. v13 has three var() refs to names it never declares:
        --edge-strong  (styles.css:1078)  --red-hover (:1095)  --ticker-dur (:539)
      All three currently ship their *fallback*. Resolved explicitly in §2/§9.

   5. NAMESPACE PROOF (measured against this exact theme pull):
        .btn*       → 322 matches in assets/bootstrap.min.css
                    + 133 matches in assets/css-site.css   = 455
        .card*      →  81 matches in bootstrap
        .container* →  87 bootstrap + 7 css-site           =  94
        .badge*     →  48 bootstrap
        .row* .col* →  31 + 148 bootstrap
      CORRECTION to the intake brief: bootstrap IS in the cascade. It is not
      referenced by any .liquid file, but css-site.css line 1 is
      `@import '…/bootstrap.min.css…'`, so it loads on every page. The .btn
      collision is therefore ~3.4× worse than the css-site-only count, and
      .card/.container/.badge/.row/.col collide with bootstrap alone.
      Nothing in the rc- system may use an unprefixed utility name.
   ============================================================================ */


/* ============================================================================
   §1  ZOOM ENGINE  — the single knob everything else hangs off
   ============================================================================
   --rcds-z is the counter-zoom factor: 1 / 0.80 = 1.25.
   Every LENGTH token below is authored as `calc(<v13 design px> * var(--rcds-z))`
   so it renders at the size v13 drew. The design value stays visible in the
   expression, so this file diffs cleanly against v13's styles.css.

   NOT scaled (deliberately, see DECISIONS):
     · hairline border widths (§6)   · line-height / letter-spacing (unitless
     · durations and easings (§9)      or em — they ride the scaled font-size)
     · breakpoints (they go the OTHER way, §10)
   ============================================================================ */
/* ⚠ --rcds-z IS DECLARED ON :root ONLY (and re-declared by .rcds-unzoom below).
   It must NOT appear in the `:root, .rcds-scope, .rcds-unzoom` token blocks.
   WHY — measured in Chrome, not theorised: a custom property containing var()
   is substituted at computed-value time ON THE ELEMENT WHERE IT IS DECLARED,
   and the already-substituted token stream is what inherits. With --rcds-z
   declared on .rcds-scope, `--rcds-text-md` computes to the literal string
   `calc(16px * 1.25)` at :root and inherits in that frozen form, so overriding
   --rcds-z further down the tree does nothing. Verified defect and fix:
       before → .rcds-unzoom > p  --rcds-z:1  but font-size resolved 20px (double-scaled)
       after  → .rcds-unzoom > p  --rcds-z:1  and font-size resolves 16px
   Declaring --rcds-z once at the top and re-declaring the TOKENS (not the factor)
   on any element that needs a different factor is the only arrangement that
   works. Keep it that way. */
:root {
  /* The live body zoom. Read-only reference — do not consume directly. */
  --rcds-body-zoom: 0.8;

  /* Counter-zoom factor. 1 / 0.8. THE knob.
     If layout/theme.liquid:372 ever drops `body{zoom:0.80}`, set this to 1
     and re-emit §10's breakpoint table at its design values. */
  --rcds-z: 1.25;
}

:root,
.rcds-scope,
.rcds-unzoom {

  /* One real viewport of height, authored inside the zoomed body. = 125vh */
  --rcds-vh: calc(1vh * var(--rcds-z));
  --rcds-viewport-h: calc(100vh * var(--rcds-z));

  /* Chrome the homepage hero reserves so hero + trust strip + fit-finder land
     EXACTLY at the fold at scrollY=0 (promo open) — no cut, no white gap below.
     Empirically tuned: 260 left a 26px white strip under the fit-finder, so the
     hero gets 26px back (234). Keep in sync with the rc- header, the trust-strip
     padding, and the fit-finder height. */
  --rcds-chrome-h: 234px;

  /* Solo-hero fill height: a hero that fills the view ALONE (collection heroes with
     no trust strip / fit-finder below it) reserves ONLY the sticky chrome (promo +
     header = 91px, breadcrumb now sits inside the hero). Used when a hero opts in to
     fill_viewport, so it lands exactly at the fold with no white gap below. */
  --rcds-hero-fill-h: max(
      calc(320px * var(--rcds-z)),
      calc((100vh - 91px) * var(--rcds-z))
  );

  /* Homepage hero height. Ports v13 `.hero--static`
     min-height:max(320px, calc(100vh - 234px)).
     Both terms scale together, so the ×1.25 factors out cleanly.
     LESSON 201 applies: the homepage hero is `.hero.hero--static`; the trade
     page heroes carry an INLINE min-height that beats any stylesheet rule, so
     this token affects the homepage only. Do not "fix" the trade heroes here. */
  --rcds-hero-static-h: max(
      calc(320px * var(--rcds-z)),
      calc((100vh - var(--rcds-chrome-h)) * var(--rcds-z))
  );
}

/* --- Counter-zoom utility -------------------------------------------------
   Opt-in escape hatch for a self-contained block that you want rendered at
   true 1:1 with no scaled tokens — e.g. an embedded widget, an iframe shell,
   a third-party script's container, or a block you are porting verbatim.

   ⚠ IT RESETS --rcds-z TO 1 ON THE SAME ELEMENT. That coupling is mandatory:
   without it every token inside would scale twice (1.25 × 1.25 × 0.8 = 1.25).

   ⚠ CORRECTED 2026-07-24 (defects H4/H5). This note used to read "⛔ Do NOT wrap
   anything containing position:fixed or position:sticky … the rc- header, the
   mobile drawer, the nav backdrop, the mega menu and the sticky quote FAB must
   all sit OUTSIDE any counter-zoomed subtree". That is not what the engine does,
   and believing it is what left the drawer at 0.80 and painted its 44px close
   button at 35.19px. Measured in Chromium at 1220x900 under body{zoom:0.80}:

       position:fixed; inset:0; zoom:1.25      → paints 1220 x 900 (full viewport)
       position:sticky; top:0;  zoom:1.25      → sticks at y=0, height holds
       44px box inside zoom:1.25               → paints 44px
       44px box at plain body zoom             → paints 35.19px

   Fixed and sticky resolve against the viewport correctly with zoom applied.
   Counter-zooming IS the fix for those elements, not a hazard to avoid. The nav,
   promo bar, drawer, backdrop and skip link are all counter-zoomed in
   rcds-nav.css §1 for exactly this reason.

   What remains true, and is the real constraint: a token declared on :root is
   substituted at :root and inherits already frozen at x1.25 (see the block
   above). So overriding --rcds-z on a counter-zoomed root does NOT retro-scale
   inherited tokens — the root must also re-declare the token blocks, which is
   why `.rcds-unzoom` appears in every `:root, .rcds-scope, .rcds-unzoom` list
   below. A counter-zoomed root that is NOT in those lists (the rcds-nav.css
   roots) must declare the handful of tokens it needs locally. */
.rcds-unzoom {
  zoom: 1.25;      /* 0.8 × 1.25 = 1.0 — a literal, because zoom does not
                      accept var() reliably across engines. */
  --rcds-z: 1;       /* mandatory partner of the line above */
}

/* Kill switch. Put on <html> if zoom:0.80 is ever removed from theme.liquid.
   Restores every length to its v13 design value. Breakpoints in §10 must be
   re-emitted at their design column at the same time. */
:root[data-rc-zoom="none"] {
  --rcds-z: 1;
}


/* ============================================================================
   §2  COLOUR
   ----------------------------------------------------------------------------
   All 17 v13 tokens ported 1:1, plus explicit resolution of every off-palette
   literal v13 used without declaring. 24 distinct hex values were found in
   v13's stylesheet; the ones not in the palette are folded or promoted below.
   ============================================================================ */
:root,
.rcds-scope,
.rcds-unzoom {

  /* --- Surfaces (v13: --ink --charcoal --charcoal-2 --steel-900 --bg --bg-2 --paper) */
  --rcds-ink:            #141619;   /* rgb(20,22,25) — every scrim below derives from this */
  --rcds-ink-2:          #191B1F;   /* was --steel-900 */
  --rcds-charcoal:       #22262B;
  --rcds-charcoal-2:     #2C3137;
  --rcds-paper:          #FFFFFF;
  --rcds-surface:        #F3F4F6;   /* was --bg   */
  --rcds-surface-2:      #E9EBEE;   /* was --bg-2 */

  /* Product-photo plate. v13 inlined `linear-gradient(160deg,#fff,#eef0f2)`
     on .pcard .ph. #EEF0F2 promoted to a token rather than folded to
     --rcds-surface-2 (#E9EBEE): the gradient needs a stop lighter than the
     page surface or product cutouts sit in a visible well. */
  --rcds-plate-a:        #FFFFFF;
  --rcds-plate-b:        #EEF0F2;
  --rcds-plate:          linear-gradient(160deg, var(--rcds-plate-a) 0%, var(--rcds-plate-b) 100%);

  /* --- Lines (v13: --line --line-strong --line-dark) */
  --rcds-line:           #D8DCE0;
  --rcds-line-strong:    #C2C7CD;
  --rcds-line-ondark:    rgba(255,255,255,.13);
  --rcds-line-ondark-strong: #9AA0A8;   /* v13 hardcoded this on .hero .btn--ghost-light:hover */

  /* RESOLVED — v13 styles.css:1078 `border-color:var(--edge-strong,#cfd3d8)`.
     --edge-strong was never declared, so #CFD3D8 shipped: a FOURTH grey sitting
     between --line (#D8DCE0) and --line-strong (#C2C7CD), 3 units from the
     latter and invisible at any zoom. Folded, not promoted. */
  --rcds-edge-strong:    var(--rcds-line-strong);

  /* --- Text (v13: --text --text-2 --muted --muted-d) */
  --rcds-text:           #15171A;
  --rcds-text-2:         #3D434B;
  --rcds-text-muted:     #6A7079;
  --rcds-text-ondark:        #FFFFFF;
  --rcds-text-ondark-2:      rgba(255,255,255,.86);  /* v13 used .9/.85/.82/.8/.78/.76 — one step */
  --rcds-text-ondark-muted:  rgba(255,255,255,.62);  /* was --muted-d */
  --rcds-text-ondark-faint:  rgba(255,255,255,.40);  /* placeholders, inactive dots */
  --rcds-text-disabled-ondark: rgba(255,255,255,.30);

  /* --- Brand (v13: --red --red-d --red-soft) */
  --rcds-red:            #D81F1F;
  --rcds-red-dark:       #B01717;
  --rcds-red-soft:       rgba(216,31,31,.10);

  /* RESOLVED — v13 styles.css:1095 `background:var(--red-hover,#b91a1a)`.
     --red-hover was never declared, so #B91A1A shipped on .sticky-quote:hover —
     a FOURTH red, off-palette, and the ONLY hover in the system that did not
     land on --red-d. Aliased to --rcds-red-dark; #B91A1A is deleted from the
     system. Every red hover in rc- now resolves to one value. */
  --rcds-red-hover:      var(--rcds-red-dark);

  /* Pale red wash. v13 used `oklch(from var(--red) 96% .04 h)` and `97% .03 h`
     on .cmp2 .c2-hot / .cmp-card--hot. Relative colour syntax has no graceful
     degradation — an engine that cannot parse it drops the declaration and the
     highlighted column loses its highlight entirely. Static hex computed from
     #D81F1F (oklch L .5653 / C .2160 / H 27.77) and shipped as the value; the
     oklch form is layered on top as progressive enhancement in the component
     sheet, never as the sole declaration. */
  --rcds-red-tint:        #FFEEEA;   /* = oklch(from #D81F1F 97% 0.03 h) */
  --rcds-red-tint-strong: #FFE8E3;   /* = oklch(from #D81F1F 96% 0.04 h) */

  /* Accent-rule indirection (v13 --accent-rule). Driven by §13. */
  --rcds-accent-rule:    var(--rcds-red);

  /* --- Semantic (promoted from v13 literals — these are NOT decoration) */
  --rcds-star:           #F5A623;   /* Google review star gold. Must never be red. */
  --rcds-success:        #7CFFB0;   /* newsletter confirmation on dark */
  --rcds-focus:          var(--rcds-red);

  /* --- Scrims. v13 shipped FIVE near-black bases: rgb(20,22,25) = --ink,
     plus #1D1D1F, #0F1013, #0B0F17 and #0C0C0D. All four strays fold to --ink;
     they differ by ≤9 units per channel and are only ever seen at ≤.92 alpha
     over photography. #0F172A (the .trade card background, Tailwind slate-900)
     also folds — it sits behind a full-bleed cover image and is never visible. */
  --rcds-scrim-weak:     rgba(20,22,25,.30);
  --rcds-scrim:          rgba(20,22,25,.50);
  --rcds-scrim-strong:   rgba(20,22,25,.92);
  --rcds-scrim-backdrop: rgba(20,22,25,.34);   /* nav backdrop */
  --rcds-scrim-panel:    rgba(20,22,25,.88);   /* stamp / caption plates */

  /* Reusable scrim ramps (v13 repeated these gradients inline 8 times). */
  --rcds-scrim-bottom:  linear-gradient(180deg, rgba(20,22,25,0) 52%, rgba(20,22,25,.68) 100%);
  --rcds-scrim-tile:    linear-gradient(180deg, rgba(20,22,25,.05) 30%, rgba(20,22,25,.50) 62%, rgba(20,22,25,.92) 100%);
  --rcds-scrim-left:    linear-gradient(90deg, rgba(20,22,25,.72) 0%, rgba(20,22,25,.42) 38%, rgba(20,22,25,0) 74%);
  --rcds-scrim-flat:    linear-gradient(rgba(20,22,25,.40), rgba(20,22,25,.40));

  /* Engineered motifs (v13 .perf / .perf-dark) */
  --rcds-perf-light: radial-gradient(rgba(255,255,255,.10) 1.4px, transparent 1.5px);
  --rcds-perf-dark:  radial-gradient(rgba(0,0,0,.07) 1.4px, transparent 1.5px);
  --rcds-perf-size:  calc(16px * var(--rcds-z)) calc(16px * var(--rcds-z));

  /* --- LEGACY BRIDGE — READ ONLY. Do not restyle rc- components to this.
     This is the live Wpbingo --theme-color, a FIFTH red already on the page.
     Declared only so that a bridging component (an rc- block that must sit
     flush against an unmigrated theme button) can reference it by name instead
     of hardcoding the hex a sixth time. */
  --rcds-legacy-theme-red: #be2e1a;
}


/* ============================================================================
   §3  TYPE
   ----------------------------------------------------------------------------
   v13 uses 40 distinct font-size literals across 152 declarations. Clustered
   below into 6 static UI steps + 6 fluid display steps. Every step value is a
   real v13 literal — none invented. Band membership and use counts are noted so
   the merge is auditable.
   ============================================================================ */
:root,
.rcds-scope,
.rcds-unzoom {

  /* --- Families ------------------------------------------------------------
     v13 loaded these with `@import url(fonts.googleapis…)` inside its
     stylesheet. Do NOT port the @import: it serialises a third-party round trip
     behind the CSS parse. Ship instead in layout/theme.liquid <head>:
       <link rel="preconnect" href="https://fonts.googleapis.com">
       <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
       <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Saira+Condensed:wght@600;700;800&family=Archivo:wght@400;500;600;700;800&display=swap">

     Display fallback is the theme's already-loaded Barlow Semi Condensed, so
     the swap lands on a condensed face and the metric shift is small.
     UI fallback is deliberately NOT Barlow: Archivo is not condensed and a
     condensed fallback reflows badly. */
  --rcds-font-display: 'Saira Condensed', 'Barlow Semi Condensed', 'Arial Narrow', Arial, sans-serif;
  --rcds-font-ui:      'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;

  --rcds-fw-regular: 400;
  --rcds-fw-medium:  500;
  --rcds-fw-semi:    600;
  --rcds-fw-bold:    700;
  --rcds-fw-black:   800;

  /* --- Static UI scale, 6 steps -------------------------------------------
     Cluster centroids of v13's static literals. `band` = the literals folded
     into that step; `n` = occurrences.

     ⚠ THE ZOOM MAKES THIS NON-OPTIONAL. Un-scaled, v13's 15px body copy renders
     at 12.0 device px inside body{zoom:.8} and its 10.5px overline renders at
     8.4px. The ×1.25 restores the drawn size. Anyone hand-typing raw px into an
     rc- component re-introduces the shrink. */
  --rcds-text-2xs: calc(10.5px * var(--rcds-z));  /* band 8.5–11.5  n=29 · overline, badge, micro-caps */
  --rcds-text-xs:  calc(12.5px * var(--rcds-z));  /* band 12–13     n=34 · meta, legal, tab label      */
  --rcds-text-sm:  calc(14px   * var(--rcds-z));  /* band 13.5–14.5 n=28 · card copy, secondary body   */
  --rcds-text-md:  calc(16px   * var(--rcds-z));  /* band 15–16.5   n=23 · body / lead base            */
  --rcds-text-lg:  calc(19px   * var(--rcds-z));  /* band 17–21     n=14 · card title, price, stat     */
  --rcds-text-xl:  calc(24px   * var(--rcds-z));  /* band 22–30     n= 7 · panel title, large numeral  */

  /* --- Fluid display scale, 6 steps ---------------------------------------
     Derived from v13's 18 heading clamp()s. The whole clamp is multiplied by
     --rcds-z: the px floor, the px ceiling AND the vw term all need it, because
     a vw length is also rendered through the zoom. `calc(clamp(…) * n)` is
     valid css-values-4 math and is supported everywhere Shopify supports. */
  --rcds-display-1: calc(clamp(46px, 6.6vw, 94px) * var(--rcds-z)); /* page-dominant hero (.h-display) */
  --rcds-display-2: calc(clamp(34px, 4.6vw, 64px) * var(--rcds-z)); /* folds 34/4.8/64, 34/4.4/60, 34/4.2/52 */
  --rcds-display-3: calc(clamp(30px, 4.2vw, 56px) * var(--rcds-z)); /* section head (.h-section) */
  --rcds-display-4: calc(clamp(26px, 3vw,   40px) * var(--rcds-z)); /* folds 28/2.7/40, 30/3/40 */
  --rcds-display-5: calc(clamp(20px, 2vw,   26px) * var(--rcds-z)); /* card head — folds 22/1.7/28, 19/1.5/23, 17/1.5/20 */
  --rcds-display-stat: calc(76px * var(--rcds-z));                  /* rating numeral — the one true outlier */

  /* --- Line heights (unitless — must NOT be scaled) */
  --rcds-lh-display:  .94;   /* uppercase Saira headings */
  --rcds-lh-tight:   1.06;   /* card titles, stat labels */
  --rcds-lh-snug:    1.25;   /* dense meta blocks */
  --rcds-lh-normal:  1.45;   /* card body copy */
  --rcds-lh-body:    1.55;   /* v13 body default */
  --rcds-lh-relaxed: 1.65;   /* long-form: FAQ answers, guides */

  /* --- Tracking (em — rides the scaled font-size, so unscaled here) */
  --rcds-track-display:  -.005em;
  --rcds-track-tight:     .01em;
  --rcds-track-caps:      .06em;   /* buttons, links, uppercase UI */
  --rcds-track-label:     .12em;   /* tags, badges */
  --rcds-track-overline:  .16em;   /* field labels, column heads */
  --rcds-track-eyebrow:   .22em;   /* .eyebrow */

  /* --- Measure (ch — unaffected by zoom) */
  --rcds-measure-tight: 34ch;
  --rcds-measure:       46ch;
  --rcds-measure-lead:  52ch;
  --rcds-measure-long:  70ch;
}


/* ============================================================================
   §4  SPACING
   ----------------------------------------------------------------------------
   v13 ships NO spacing scale — 32 distinct padding/gap/margin literals and 18
   clamp() expressions, all ad hoc. The literals sit on a 2px grid with heavy
   clustering on multiples of 4 plus an 18/22/26 band. Collapsed to an 11-step
   4px-base scale below.

   The 18/20/22 collapse is the only lossy one and it is safe: at the live 0.80
   zoom the largest discarded delta is 2 design px = 1.6 device px.
   ============================================================================ */
:root,
.rcds-scope,
.rcds-unzoom {
  --rcds-space-0:  0;
  --rcds-space-1:  calc(4px  * var(--rcds-z));  /* folds 3,4,5        */
  --rcds-space-2:  calc(8px  * var(--rcds-z));  /* folds 6,7,8,9,10   */
  --rcds-space-3:  calc(12px * var(--rcds-z));  /* folds 11,12,13     */
  --rcds-space-4:  calc(16px * var(--rcds-z));  /* folds 14,15,16,17  */
  --rcds-space-5:  calc(20px * var(--rcds-z));  /* folds 18,20,22 — the two most-used values in v13 */
  --rcds-space-6:  calc(24px * var(--rcds-z));  /* folds 24,26        */
  --rcds-space-7:  calc(32px * var(--rcds-z));  /* folds 28,30,32,34,36 */
  --rcds-space-8:  calc(40px * var(--rcds-z));  /* folds 40,44        */
  --rcds-space-9:  calc(48px * var(--rcds-z));  /* folds 48,52        */
  --rcds-space-10: calc(64px * var(--rcds-z));  /* folds 56,60,64     */

  /* --- Fluid rhythm. Derived from v13's 18 clamps, collapsed to 4 + gutter +
     two section rhythms. Whole clamp × --rcds-z, same rule as §3. */
  --rcds-space-fluid-sm: calc(clamp(16px, 2.2vw, 36px)  * var(--rcds-z)); /* folds 12/1.8/22, 18/2.2/26, 20/2.2/40 */
  --rcds-space-fluid-md: calc(clamp(28px, 3vw,   44px)  * var(--rcds-z)); /* folds 26/3/38, 28/3.5/44 */
  --rcds-space-fluid-lg: calc(clamp(32px, 5vw,   72px)  * var(--rcds-z)); /* folds 30/4.4/60, 32/4/48, 32/6/72 */
  --rcds-space-fluid-xl: calc(clamp(56px, 7.5vw, 116px) * var(--rcds-z)); /* story copy pad */

  /* Canonical vertical section rhythm — ONE value for the WHOLE STORE.
     This single token is the only lever for section white-space; every band on every
     template reads it, so the rhythm cannot drift page-to-page.

     2026-08-10: was clamp(72px,7vw,104px) (=101 physical px at 1440). The client asked
     to cut white space repeatedly, and each request had been answered with a per-section
     or per-template override, which is what produced the drift: the two collection
     templates ended up tight while the homepage, all six trade-hub pages, coverage,
     the generic collection template, cart and search stayed airy. Tightening the TOKEN
     fixes all 14 rcds templates at once and removes the need for any local override.

     --rcds-section-y-tight is now an ALIAS, kept so existing `.rcds-section--tight`
     markup and the per-section "tight" checkboxes stay valid no-ops. Do NOT give it an
     independent value again — that reintroduces the two-tier drift this replaced. */
  /* 2026-08-12: tightened again from clamp(36,4.5vw,60). At 60 the content-to-content
     gap between two adjacent bands measured 120px (each band contributes its own
     padding), which the client read as dead space between the FAQ and the reviews
     band. 44px puts that gap at ~88px. STILL THE ONE LEVER for the whole store. */
  --rcds-section-y:       calc(clamp(28px, 3.4vw, 44px) * var(--rcds-z));
  --rcds-section-y-tight: var(--rcds-section-y);

  /* --- Container. v13 --maxw:1320px / --gutter:clamp(20px,5vw,64px).
     1320 × 1.25 = 1650 authored → renders 1320 device px. */
  --rcds-container:  calc(1320px * var(--rcds-z));
  --rcds-gutter:     calc(clamp(20px, 5vw, 64px) * var(--rcds-z));
  --rcds-container-narrow: calc(980px * var(--rcds-z));
}


/* ============================================================================
   §5  RADIUS  —  ONE SYSTEM: SHARP (0)
   ----------------------------------------------------------------------------
   v13 shipped three competing radius languages across 26 declarations:
     A · 0px       industrial  — 7 explicit `border-radius:0` + every unstyled
                                 surface. Owns the hero, buttons, fitbar,
                                 product cards, categories, story, footer,
                                 compare table — i.e. the entire above-fold and
                                 the whole commerce path.
     B · 8/9/10/12px soft      — 10 declarations, all on sections added AFTER
                                 the homepage: .trade .vcard .rel-card .pk-card
                                 .bf-tile .rev-card .mfeat .mfeat-cta .icon badge
     C · 2/3px badge           — 5 declarations, .trade-badge .trade-soon
                                 .pk-badge .region .flag, focus rings

   DECISION: language A wins outright. Rationale, in order of weight:
     1. The brand line in v13's own file header is "Sharp · Industrial ·
        Australian-made". B is off-brief; it arrived with the contractor pages.
     2. A owns the commerce-critical surfaces; B owns supporting content. If one
        has to bend, it is the smaller, later, non-transactional set.
     3. ZOOM ARGUMENT (decisive, and unique to this theme): border-radius is
        scaled by body{zoom:.8}, so B's three values render at 9.6px, 8.0px and
        6.4px and C's render at 2.4px. Radii that were nominally identical in
        the design (10 vs 12) land 1.6 device px apart, and the 3px badge radius
        lands on a fractional 2.4px that anti-aliases to mush on 1x displays.
        A radius of 0 is the only value in the system that is exactly itself at
        any zoom.
     4. It removes a per-component decision that has no right answer.

   Exactly two escapes survive, both SHAPE semantics rather than decoration:
   a circle is a circle and a pill is a pill.
   ============================================================================ */
:root,
.rcds-scope,
.rcds-unzoom {
  --rcds-radius:        0;      /* THE default. Everything, unless listed below. */
  --rcds-radius-circle: 50%;    /* .trade-arw, .inst-play, count badge dot       */
  --rcds-radius-pill:   999px;  /* .sticky-quote FAB only                        */
}

/* ============================================================================
   §5.1  BASE-CSS VOCABULARY BRIDGE  (added 2026-07-28 — pixel-diff reconciliation)
   ----------------------------------------------------------------------------
   rcds-base.css references ~15 token names this file never declared, so each
   silently rode its literal fallback. Colours/type fallbacks were typed to match
   v13 and rendered correctly, but the elevation + radius names lost the token
   layer's ×1.25 zoom-scaling (shadows + badge radius painted 20% small) and the
   two `--rcds-border*` SHORTHAND names, fed where a colour was expected, dropped
   the card border. These aliases point every base-css name at the declared,
   already-scaled token so the scaling flows through the shared primitives.
   ============================================================================ */
:root,
.rcds-scope,
.rcds-unzoom {
  /* Type sizes base.css consumes by name — scaled, so they paint at v13 size. */
  --rcds-fs-eyebrow: calc(12px * var(--rcds-z));   /* .rcds-eyebrow font-size   */
  --rcds-fs-card:    calc(19px * var(--rcds-z));   /* .rcds-card__title font-size */

  /* Elevation aliases -> the scaled §7 ladder (base.css says --rcds-shadow-*). */
  --rcds-shadow-1: var(--rcds-elev-1);
  --rcds-shadow-2: var(--rcds-elev-2);
  --rcds-shadow-3: var(--rcds-elev-3);

  /* Colour / surface name bridges (base.css vocabulary -> declared tokens). */
  --rcds-muted:        var(--rcds-text-muted);
  --rcds-muted-d:      var(--rcds-text-ondark-muted);
  --rcds-bg:           var(--rcds-surface);
  --rcds-bg-2:         var(--rcds-surface-2);
  --rcds-border-dark:  var(--rcds-line-ondark);
  --rcds-focus-color:  var(--rcds-focus);

  /* Radius aliases. -0 is the sharp default; -sm/-md/-lg scaled so the few
     soft-cornered cards paint at their drawn radius through the zoom. */
  --rcds-radius-0:  0;
  --rcds-radius-sm: calc(3px  * var(--rcds-z));
  --rcds-radius-md: calc(10px * var(--rcds-z));
  --rcds-radius-lg: calc(12px * var(--rcds-z));

  /* Motion alias. base.css media-image scale uses --rcds-dur-5 -> §9 dur-4. */
  --rcds-dur-5: var(--rcds-dur-4);
}

/* --- MIGRATION MAP · every card-shaped surface in v13 -----------------------
   19 selectors, 7 distinct treatment tuples (bg / border / radius / shadow).
   `orphan` = class exists in styles.css but is rendered by ZERO of the 7 v13
   HTML files — delete rather than port.

   TUPLE A — paper + 1px --rcds-line + r0 + no shadow          → rcds-card (base)
     .pcard        r0  → r0            KEEP · ORPHAN (0 renders) → delete, rebuild from Shopify product card
     .veh          r0  → r0            KEEP
     .rev          r0  → r0            KEEP
     .setup-card   r0  → r0            KEEP · ORPHAN (0 renders) → delete
     .guide-row    r0  → r0            KEEP
     .cq-card      r0  → r0            KEEP
     .cmp-card     r0  → r0            KEEP · ORPHAN (0 renders) → delete, fold into rcds-table responsive
   TUPLE B — ink + image + scrim + r0                        → rcds-tile
     .cat          r0  → r0            KEEP  (3 variants: base / v-split / v-spec)
     .inst-card    r0  → r0            KEEP
     .guide-feat   r0  → r0            KEEP
     .tc-card      r0  → r0            KEEP
   TUPLE C — paper + 1px line + r10 + no shadow              → rcds-card (base)
     .rev-card     r10 → r0   CHANGED
     .vcard        r10 → r0   CHANGED   (also: --edge-strong resolved, §2)
     .rel-card     r10 → r0   CHANGED
     .bf-tile      r10 → r0   CHANGED
   TUPLE D — paper + 1px line + r12 + overflow hidden        → rcds-card--framed
     .pk-card      r12 → r0   CHANGED   (--pop ring keeps its 2px inset, §7)
   TUPLE E — dark plate + image + r10                        → rcds-tile
     .trade        r10 → r0   CHANGED   (bg #0F172A → --rcds-ink, §2)
   TUPLE F — surface-2 + r12                                 → rcds-tile--plate
     .mfeat        r12 → r0   CHANGED · ORPHAN (0 renders) → delete with mega menu rebuild
   TUPLE G — ink + no border + generous pad                  → rcds-panel
     .rating-box   r0  → r0            KEEP · ORPHAN (0 renders) → delete

   Badges (tuple C radius family): .trade-badge .trade-soon .pk-badge
     r3 → r0 CHANGED. v13 also shipped 7 distinct badge treatments across
     .tag / .inst-badge / .c2-badge / .pk-badge / .trade-badge / .trade-soon /
     .promo .red — collapse to two: rcds-badge (solid --rcds-red on dark imagery)
     and rcds-badge--muted (rgba(255,255,255,.16) + backdrop-blur, the "soon"
     state). Both r0.

   Net: 11 selectors change radius, 8 keep it, 6 of the 19 are orphans that
   should not be ported at all.
   -------------------------------------------------------------------------- */


/* ============================================================================
   §6  BORDERS, RULES, FOCUS
   ----------------------------------------------------------------------------
   Hairlines are NOT scaled. A 1px border renders at 0.8px and the compositor
   snaps it back to ~1px anyway; scaling it to 1.25px also renders 1px. Same
   pixel, one less indirection. Structural and accent rules ARE scaled: v13's
   4px red topline would otherwise render at 3.2px and read as an artefact.
   ============================================================================ */
:root,
.rcds-scope,
.rcds-unzoom {
  --rcds-rule-hair: 1px;                       /* NOT scaled — see above */
  --rcds-rule-2:    calc(2px * var(--rcds-z));   /* folds v13's 1.5px and 2px strokes */
  --rcds-rule-3:    calc(3px * var(--rcds-z));   /* fitbar done-state, wc-media top    */
  --rcds-rule-4:    calc(4px * var(--rcds-z));   /* topline / left-rule accents        */

  --rcds-border:         var(--rcds-rule-hair) solid var(--rcds-line);
  --rcds-border-strong:  var(--rcds-rule-hair) solid var(--rcds-line-strong);
  --rcds-border-ondark:  var(--rcds-rule-hair) solid var(--rcds-line-ondark);

  /* Focus ring. SCALED deliberately: at 0.8 an unscaled 2px ring renders 1.6px,
     which is below the practical visibility floor on a light surface.
     ⚠ The live theme actively removes focus outlines:
         css-site.css:66  `button:focus, .btn:focus { outline:unset; box-shadow:unset }`
         css-site.css:69  `button:focus-visible, input:focus-visible,
                            select:focus-visible, textarea:focus-visible { outline:unset }`
     Those are specificity (0,1,1). Any `.rcds-scope button:focus-visible` rule is
     (0,2,1) and wins without !important. Restoring focus is a component
     responsibility — the tokens are here, use them. */
  --rcds-focus-width:  calc(2px * var(--rcds-z));
  --rcds-focus-offset: calc(3px * var(--rcds-z));
  --rcds-focus-ring:   var(--rcds-focus-width) solid var(--rcds-focus);
}


/* ============================================================================
   §7  ELEVATION
   ----------------------------------------------------------------------------
   v13 shipped 17 distinct shadow declarations, no two alike, across 5 alpha
   values and 4 near-black bases. Collapsed to 3 elevations + 1 brand glow +
   2 rings. Shadows ARE scaled by zoom, so every length carries --rcds-z.

   Collapse map:
     ELEV 1 ← 0 5px 5px .25 · 0 6px 18px -8px .40 · 0 14px 30px -22px .40
              0 16px 32px -26px .50 · 0 18px 36px -22px .40
     ELEV 2 ← 0 20px 40px -24px .45 · 0 22px 44px -24px .50 · …-24px .55
              0 22px 44px -26px .55 · 0 24px 46px -24px .60
     ELEV 3 ← 0 30px 60px -24px .35 (mega menu) · drop-shadow(0 34px 46px .55)
     BRAND  ← 0 14px 30px -10px rgba(216,31,31,.55)  (sticky FAB — kept, it is
              a brand-coloured glow, not an elevation, and folding it would
              turn the one red-glowing element on the site grey)
     RING   ← 0 0 0 1px rgba(0,0,0,.08) (flag) · inset 0 0 0 2px --red (.pk-card--pop)
   ============================================================================ */
:root,
.rcds-scope,
.rcds-unzoom {
  --rcds-elev-0: none;

  /* rest state of a lifted card, small overlays */
  --rcds-elev-1: 0 calc(16px * var(--rcds-z)) calc(32px * var(--rcds-z)) calc(-24px * var(--rcds-z)) rgba(20,22,25,.45);

  /* hover state of a lifted card, floating panels */
  --rcds-elev-2: 0 calc(22px * var(--rcds-z)) calc(44px * var(--rcds-z)) calc(-24px * var(--rcds-z)) rgba(20,22,25,.55);

  /* mega menu, modals, anything that leaves the document plane */
  --rcds-elev-3: 0 calc(30px * var(--rcds-z)) calc(60px * var(--rcds-z)) calc(-24px * var(--rcds-z)) rgba(20,22,25,.38);

  /* brand glow — semantic, not an elevation step */
  --rcds-elev-brand: 0 calc(14px * var(--rcds-z)) calc(30px * var(--rcds-z)) calc(-10px * var(--rcds-z)) rgba(216,31,31,.55);

  /* filter: drop-shadow() variant for cut-out PNGs (the brochure render). */
  --rcds-elev-cutout: drop-shadow(0 calc(34px * var(--rcds-z)) calc(46px * var(--rcds-z)) rgba(0,0,0,.55));

  /* rings — outline-shaped, do not participate in the elevation ladder */
  --rcds-ring-hair:  0 0 0 var(--rcds-rule-hair) rgba(20,22,25,.08);
  --rcds-ring-brand: inset 0 0 0 var(--rcds-rule-2) var(--rcds-red);
}


/* ============================================================================
   §8  Z-INDEX  —  RE-BASED AGAINST THE MEASURED LIVE LADDER  (defect H6)
   ----------------------------------------------------------------------------
   v13 used 9 literals: 0,1,2,3,5,30,55,60,90. None of them survive contact with
   this theme, and the previous note here ("theme owns 9999+", ceiling 9998) was
   wrong by five orders of magnitude.

   MEASURED, not assumed — `grep -rn 'z-index'` over every .css and every inline
   <style> in the 2026-07-24 pull of live theme 156872999214
   (gsc_data/us-theme-live-20260724T083221Z). The real ladder, top down:

     LIVE VALUE  WHAT HOLDS IT                          WHERE
     ----------  -------------------------------------  ---------------------------------------
     2147483000  geo suggestion overlay, JS-injected    snippets/geo-redirect-head.liquid:63
                 inline cssText, position:fixed         (rendered in <head> on every page)
      999999999  .verify-popup                          assets/css-section.css:2092
          99999  .menu-mobile__inner (99999),           snippets/header-mobile.liquid:167
                 newsletter popup overlay + inner,      assets/css-site.css:7065, :7077
                 size-guide overlay, video wrapper,     assets/css-product.css:515, :552
                 #quoteAddedModal (inline)              layout/theme.liquid:439
          99998  .menu-mobile__overlay                  snippets/header-mobile.liquid:183
     99990-2     ⚠ CHAT WIDGET — .rc-bubble 99990,      snippets/chat-widget.liquid:129,142,188,196
                 .rc-greeting 99991, .rc-overlay 99991, (rendered unconditionally by
                 .rc-panel 99992. position:fixed ON      layout/theme.liquid:580)
                 EVERY PAGE.
     10000-1     .pswp, .vl-lightbox(+__close),         assets/css-product.css:4456,
                 .video-modal, .locator-modal-overlay,  assets/css-section-vehicle-landing.css:404,421
                 .rc-lightbox, contact-card toast       sections/custom-store-locator.liquid:171
      9998-9999  70 rules: .pre-loading, .wpbingo-      assets/css-site.css:176, :245, :759,
                 loading, .menu-dropdown__content,      :5299, :8625; assets/css-section.css:1294
                 quickview body::before, .menu-mobile,
                 cart notifications, page loaders
      1500-1620  PhotoSwipe chrome                      assets/photoswipe.css:48, default-skin.css:156
       999-1000  .cart-drawer + .cart-overlay (1000),   snippets/custom-cart-drawer-right.liquid:57,77
                 .main-menu (1000), .cart-notification  snippets/custom-desktop-menu.liquid:138
                 (1000), .drawer + .drawer__overlay     assets/css-site.css:4467, :4485
                 (999), .header-bottom-fixed (999)      assets/css-section.css:1175
         99-101  THE LIVE STICKY HEADER:                assets/css-section.css:460, :476
                 .bwp-header.sticky .header-desktop 99,
                 .header-top-mobile 100, .header-cart__
                 content 99, collection filter drawer
             90  .sticky-cart-single, mobile search     assets/css-product.css:4713

   WHY THE OLD SCALE SHIPPED A BUG: backdrop 55 / header 60 / drawer 90 sat under
   EVERY band above, including the chat widget. A full-screen rcds mobile drawer
   at 90 had the chat bubble (99990) painted on top of it, on every page.

   RE-BASING RULES, one per layer:
     · --rcds-z-sticky (300) — in-page sticky bars. Clears .sticky-cart-single
       (90) and the live sticky header (99/100); stays out of the 999 drawer band.
     · --rcds-z-header (990) — ABOVE the live sticky header (99/100), because the
       rcds header replaces it, and BELOW the cart/off-canvas band (999/1000) so
       the cart drawer still covers the header exactly as the theme intends.
     · --rcds-z-backdrop (980) — one step under the header: the mega-menu scrim
       dims the page while the header itself stays lit. Same relative order as
       before, new band.
     · --rcds-z-drawer (99995) — MUST clear the chat widget (99990-99992). This
       is the one layer that legitimately jumps bands: it is a full-viewport
       surface and nothing that is not itself a modal may sit on top of it. It
       stays below .verify-popup and the geo overlay, the only two live layers
       above it. The drawer is `inset:0`, so it is its own backdrop; there is
       deliberately no second token for a drawer scrim.
     · --rcds-z-toast (100000) — clears the whole 99999 band, so a confirmation
       is never hidden behind the newsletter popup or the mobile menu.
     · --rcds-z-skip (100010) — top of the rcds band. The skip link is the first
       thing a keyboard user reaches and must not be covered by anything of ours.

   ⛔ RESERVED — NEVER EXCEED: 999999999 (.verify-popup) and 2147483000 (the geo
   dialog, which is designed to sit on top of everything). --rcds-z-ceiling is
   the top of OUR band and sits far below both, on purpose.
   ⚠ z-index only orders siblings within a stacking context. transform, filter,
   opacity<1, will-change and `zoom` on an ancestor all create one — which is
   why the whole page already sits inside the stacking context created by
   body{zoom:.8}, and why .rcds-unzoom creates another.
   ============================================================================ */
:root,
.rcds-scope,
.rcds-unzoom {
  --rcds-z-below:      -1;
  --rcds-z-base:        0;   /* media layer inside a tile                      */
  --rcds-z-scrim:       1;   /* gradient over the media                        */
  --rcds-z-content:     2;   /* copy over the scrim                            */
  --rcds-z-accent:      3;   /* badges, toplines, corner ticks                 */
  --rcds-z-controls:    5;   /* carousel arrows and dots                       */
  --rcds-z-sticky:    300;   /* in-page sticky bars (fitbar) — over live 90/100 */
  --rcds-z-backdrop:  980;   /* mega-menu scrim — under the header             */
  --rcds-z-header:    990;   /* sticky header, sticky quote FAB — under 999/1000 */
  --rcds-z-drawer:  99995;   /* full-screen mobile drawer — over chat 99990-2   */
  --rcds-z-toast:  100000;   /* clears the live 99999 band                     */
  --rcds-z-skip:   100010;   /* first Tab stop, top of the rcds band           */
  --rcds-z-ceiling:100010;   /* hard cap. Live reserves 999999999 + 2147483000 */
}


/* ============================================================================
   §9  MOTION
   ----------------------------------------------------------------------------
   v13 repeated `cubic-bezier(.2,.7,.2,1)` 11 times and used one other curve.
   Durations spread across 21 values; clustered to 4 steps + 2 ambient.
   Durations and easings are TIME, not length — never scaled by zoom.
   ============================================================================ */
:root,
.rcds-scope,
.rcds-unzoom {
  --rcds-ease:       cubic-bezier(.2,.7,.2,1);   /* THE curve — 11 uses in v13 */
  --rcds-ease-inout: cubic-bezier(.65,0,.35,1);  /* hero track only            */
  --rcds-ease-out:   ease-out;

  --rcds-dur-1: .16s;  /* folds .12 .14 .15 .16 .18 — colour, opacity, border  */
  --rcds-dur-2: .24s;  /* folds .20 .22 .25 .26 .28 — transform, underline     */
  --rcds-dur-3: .35s;  /* folds .30 .35 .40 .45 — card lift, panel open        */
  --rcds-dur-4: .60s;  /* folds .50 .55 .60 .70 — image scale, scroll reveal   */

  --rcds-dur-kenburns: 7s;   /* hero background drift (v13 used 6s and 7s)     */

  /* RESOLVED — v13 styles.css:539 `animation:ticker var(--ticker-dur,55s)`.
     --ticker-dur was never declared, so 55s shipped. Declared explicitly so the
     partner ticker can be retimed from one place (longer strip = longer
     duration, or the scroll speed changes when logos are added). */
  --rcds-ticker-dur: 55s;

  /* Ready-made transitions so components stop hand-rolling them. */
  --rcds-transition-fast: var(--rcds-dur-1) var(--rcds-ease);
  --rcds-transition:      var(--rcds-dur-2) var(--rcds-ease);
  --rcds-transition-slow: var(--rcds-dur-3) var(--rcds-ease);
  --rcds-transition-media: transform var(--rcds-dur-4) var(--rcds-ease);
}

/* Reduced motion. Neutralises the tokens at source, so a component that only
   consumes tokens is compliant without writing its own media query.
   The two ambient animations are stopped outright — a 55s infinite translate
   and a 7s scale are exactly what this preference exists to suppress. */
@media (prefers-reduced-motion: reduce) {
  :root,
  .rcds-scope,
  .rcds-unzoom {
    --rcds-dur-1: .01ms;
    --rcds-dur-2: .01ms;
    --rcds-dur-3: .01ms;
    --rcds-dur-4: .01ms;
    --rcds-dur-kenburns: .01ms;
    --rcds-ticker-dur: .01ms;
  }
  .rcds-scope *,
  .rcds-scope *::before,
  .rcds-scope *::after {
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}


/* ============================================================================
   §10  BREAKPOINTS  —  RE-AUTHORED ×0.80
   ----------------------------------------------------------------------------
   v13 has 22 distinct media conditions (20 max-width values + 2 prefers-*).
   Normalised to 5.

   ⚠⚠ BREAKPOINTS GO DOWN, LENGTHS GO UP. ⚠⚠
   A media query is evaluated against the REAL viewport. Inside body{zoom:.8}
   the layout box is viewport ÷ 0.8, so a rule v13 wrote for a 1220px layout box
   must fire when the real viewport hits 1220 × 0.8 = 976px.

     TOKEN          DESIGN px   EMITTED px   v13 values folded in        n
     ------------   ---------   ----------   -------------------------   --
     --rcds-bp-xs        480         384       420, 480                     6
     --rcds-bp-sm        760         608       520, 560, 620, 640, 680,
                                             720, 760                    20
     --rcds-bp-md        900         720       820, 860, 880, 900          18
     --rcds-bp-lg       1100         880       960, 980, 1080, 1100        11
     --rcds-bp-xl       1220         976       1180, 1220, 1260             4

   FOLDING RULE: always round a max-width UP to the cluster's top value. That
   makes a component stack EARLIER than v13 did. Stacking earlier is always
   safe; stacking later squeezes a layout into a width it was never tested at.
   This is why the .fitbar's 980 and the .cats' 980 land on lg(1100/880) rather
   than md — a 6-column filter bar must not be asked to survive 80 design px
   narrower than v13 ever rendered it.

   ⚠ PHONE COVERAGE GAP — read before using xs. Because breakpoints shrink,
   --rcds-bp-xs fires only below 384 REAL px:
       iPhone SE      375 real  →  469 design  →  xs FIRES
       iPhone 14/15   390 real  →  488 design  →  xs DOES NOT FIRE
       iPhone Pro Max 430 real  →  538 design  →  xs DOES NOT FIRE
   This is a FAITHFUL port (v13 also would not stack at 488 design px), but it
   means xs is a small-phone-only tier in production. RULE: if a component MUST
   be single-column on every phone, author it at `--rcds-bp-sm` (608 emitted),
   not xs. Reserve xs for genuinely cramped 320–384px devices.

   ⚠ Media queries cannot read custom properties. The props below exist for JS
   (matchMedia strings, resize observers) and for container queries. The @media
   blocks themselves MUST use the emitted literals. Copy-paste from here:

       @media (max-width:  384px) { }   /* xs */
       @media (max-width:  608px) { }   /* sm */
       @media (max-width:  720px) { }   /* md */
       @media (max-width:  880px) { }   /* lg */
       @media (max-width:  976px) { }   /* xl — nav collapse */

   ⚠ Live-theme adjacency: Wpbingo breaks at 767/768, 991/992, 1199. The rc- md
   (720) sits 47px below the theme's 767. Expect a 720–767 band where an rc-
   section has stacked and the theme chrome around it has not. Verified as
   acceptable; do not "fix" it by moving rc- md to 767, which would shift 18
   folded rules later and break the folding rule above.
   ============================================================================ */
:root,
.rcds-scope,
.rcds-unzoom {
  /* JS-readable. Values are the EMITTED (real-viewport) numbers. */
  --rcds-bp-xs: 384px;   /* design  480px */
  --rcds-bp-sm: 608px;   /* design  760px */
  --rcds-bp-md: 720px;   /* design  900px */
  --rcds-bp-lg: 880px;   /* design 1100px */
  --rcds-bp-xl: 976px;   /* design 1220px */

  /* Design-column values, for anyone diffing against v13 or re-deriving. */
  --rcds-bp-xs-design:  480px;
  --rcds-bp-sm-design:  760px;
  --rcds-bp-md-design:  900px;
  --rcds-bp-lg-design: 1100px;
  --rcds-bp-xl-design: 1220px;
}

/* --- Breakpoint proof utilities -------------------------------------------
   These exist to (a) give components a hand-authoring-free visibility toggle
   and (b) act as a live assertion that the emitted numbers above are the ones
   actually shipping. !important is correct here and only here: a display
   utility whose entire contract is "this is hidden" must not lose to the
   1,292 !important declarations already in the theme cascade. */
@media (max-width: 384px) { .rcds-hide-xs-down { display: none !important; } }
@media (max-width: 608px) { .rcds-hide-sm-down { display: none !important; } }
@media (max-width: 720px) { .rcds-hide-md-down { display: none !important; } }
@media (max-width: 880px) { .rcds-hide-lg-down { display: none !important; } }
@media (max-width: 976px) { .rcds-hide-xl-down { display: none !important; } }

@media (min-width: 384.02px) { .rcds-hide-xs-up { display: none !important; } }
@media (min-width: 608.02px) { .rcds-hide-sm-up { display: none !important; } }
@media (min-width: 720.02px) { .rcds-hide-md-up { display: none !important; } }
@media (min-width: 880.02px) { .rcds-hide-lg-up { display: none !important; } }
@media (min-width: 976.02px) { .rcds-hide-xl-up { display: none !important; } }


/* ============================================================================
   §11  CONTROL SIZES
   ----------------------------------------------------------------------------
   ⚠ ACCESSIBILITY FINDING, and the strongest single argument for §1.
   Every interactive control in the live theme is currently 20% smaller than it
   was authored, because of body{zoom:.8}. v13's 44px rail button renders at
   35.2 device px — below the 44px minimum in WCAG 2.5.8 / iOS HIG. Authoring
   through --rcds-z restores it: 44 × 1.25 = 55px CSS → 44 device px. Every token
   below is at or above the 44 device-px floor except --rcds-control-xs and -sm,
   which are decorative frames (icon wells), never hit targets.

   ----------------------------------------------------------------------------
   DEFECT H5 — FULL SWEEP, closed 2026-07-24. MEASURED in Chromium under
   body{zoom:0.80} with getBoundingClientRect, i.e. PAINTED px, not declared px.
   "sp" = coordinate space (A = counter-zoomed, B = body zoom; see §1).

     CONTROL                       sp  BEFORE   AFTER   HOW
     ---------------------------   --  ------   -----   ---------------------------
     .rcds-mnav__close             B→A  35.19    44.00  drawer moved into SPACE A
     .rcds-mnav__cta               B→A  35.19    44.00  drawer moved into SPACE A
     .rcds-mnav__tel               B→A  15.68    44.00  + min-height
     .rcds-mnav__all               B→A  15.40    44.00  + min-height
     .rcds-mnav__ul a              B→A  19.40    26.25  + padding-block (AA floor)
     .rcds-mnav__summary           B→A  49.51    61.89  already passing, now truer
     .rcds-nav__icon (x3)          A    42.00    44.00  42 → var(--rcds-hit)
     .rcds-nav__burger             A    42.00    44.00  42 → var(--rcds-hit)
     .rcds-nav__quote              A    35.00    44.00  + min-height
     .rcds-skip                    B→A  29.44    44.00  + SPACE A + min-height
     .rcds-promo__link             A    17.50    24.00  + min-height (AA floor)
     .rcds-promo__dist             A    16.10    24.00  + min-height (AA floor)
     .rcds-mega__link              A    19.58    25.56  + padding-block (AA floor)
     .rcds-mega__col-h--link       A    15.40    24.00  + min-height (AA floor)
     .rcds-mega__cta               A    20.55    44.00  + min-height
     .rcds-mega__feat-cta          A    35.00    44.00  + min-height
     .rcds-mega__sub-item          A    45.50    45.50  already passing
     .rcds-btn                     B    32.80    44.00  + min-height
     .rcds-btn--lg                 B    36.00    44.00  inherits the min-height
     .rcds-btn--sm                 B    24.80    26.79  AA floor ON PURPOSE (below)
     .rcds-btn--icon               B    35.19    44.00  44px → var(--rcds-hit)
     .rcds-btn--icon-sm            B    28.80    44.00  36px → var(--rcds-hit)
     .rcds-field__input            B    39.20    44.00  + min-height
     .rcds-pagination__link/       B    35.19    44.00  44px → var(--rcds-hit)
       __current/__gap                                   (and 40px → hit at ≤384)
     .rcds-pagination__link--prev/ B    35.19    44.00  min-width → var(--rcds-hit)
       --next
     .rcds-toast__close            A    24.00    44.00  ::before hit expansion,
                                                        painted glyph unchanged

   TWO CONTROLS SIT AT THE AA FLOOR (24) RATHER THAN 44, DELIBERATELY:
     · dense link stacks (.rcds-mega__link, .rcds-mnav__ul a, the promo links) —
       their row pitch is 37.6px, so a 44px box would OVERLAP its neighbours by
       ~6px on each side. An ambiguous tap sends the user to the WRONG page,
       which is a worse failure than a small-but-unambiguous target. WCAG 2.5.8
       explicitly allows this via its spacing provision.
     · .rcds-btn--sm — holding it at 44 makes it exactly as tall as .rcds-btn and
       the modifier stops meaning anything.
   Both clear WCAG 2.5.8 AA. Neither clears 2.5.5 AAA. That is the trade, and it
   is recorded here so nobody "fixes" it into an overlap.
   ============================================================================ */
:root,
.rcds-scope,
.rcds-unzoom {
  --rcds-control-xs: calc(26px * var(--rcds-z));  /* decorative icon well  → 26 dev px */
  --rcds-control-sm: calc(30px * var(--rcds-z));  /* decorative icon well  → 30 dev px */
  --rcds-control-md: calc(38px * var(--rcds-z));  /* social / footer icon  → 38 dev px */
  --rcds-control-lg: calc(44px * var(--rcds-z));  /* MINIMUM HIT TARGET    → 44 dev px */
  --rcds-control-xl: calc(52px * var(--rcds-z));  /* hero arrow            → 52 dev px */
  --rcds-control-2xl: calc(60px * var(--rcds-z)); /* video play affordance → 60 dev px */

  /* Absolute floor. Apply as min-inline-size/min-block-size to anything
     clickable that does not already use --rcds-control-lg or larger.
     ⚠ SPACE-SENSITIVE (see §1). This resolves to 55px design / 44 device px
     because --rcds-z is 1.25 here. Inside a counter-zoomed subtree (SPACE A:
     .rcds-unzoom, and the .rcds-nav / .rcds-promo / .rcds-mnav /
     .rcds-nav__backdrop / .rcds-skip roots in rcds-nav.css §1) the same token is
     re-declared as a literal 44px, because there 44 declared IS 44 painted.
     One name, correct value in both spaces. Never hard-code 44px again. */
  --rcds-hit: calc(44px * var(--rcds-z));

  /* WCAG 2.5.8 Target Size (Minimum, AA) floor → 24 device px.
     For an inline text link inside a dense list, where lifting the box to
     --rcds-hit would make it OVERLAP its neighbours. An ambiguous tap sends the
     user to the wrong page, which is worse than a small-but-unambiguous one.
     Rule of thumb: use --rcds-hit when the control owns its box, --rcds-hit-min
     when it sits in a gap-separated stack whose pitch is under 44px. */
  --rcds-hit-min: calc(24px * var(--rcds-z));

  /* Icon glyph sizes inside the wells above. */
  --rcds-icon-sm: calc(16px * var(--rcds-z));
  --rcds-icon-md: calc(20px * var(--rcds-z));
  --rcds-icon-lg: calc(24px * var(--rcds-z));

  /* Header / bar heights (v13: promo 30, header bar 60, ticker item 118). */
  --rcds-bar-promo:  calc(30px  * var(--rcds-z));
  --rcds-bar-header: calc(60px  * var(--rcds-z));
  --rcds-ticker-h:   calc(118px * var(--rcds-z));
}


/* ============================================================================
   §12  ASPECT RATIOS
   ----------------------------------------------------------------------------
   Ratios are unitless — zoom-proof. Tokenised because v13 spread 7 of them
   across 11 declarations with no naming.
   ============================================================================ */
:root,
.rcds-scope,
.rcds-unzoom {
  --rcds-ratio-portrait: 3 / 4;      /* category tile            */
  --rcds-ratio-card:     273 / 340;  /* trade proof card         */
  --rcds-ratio-trade:    4 / 3.15;   /* trade tile               */
  --rcds-ratio-landscape: 4 / 3;     /* split-panel photo        */
  --rcds-ratio-wide:     16 / 9;     /* gallery, mobile fallback */
  --rcds-ratio-hero:     16 / 10;    /* vehicle cutout plate     */
  --rcds-ratio-square:   1 / 1;      /* product photo plate      */
}


/* ============================================================================
   §13  ACCENT INTENSITY
   ----------------------------------------------------------------------------
   Ports v13's body[data-accent="low"|"bold"] tweak mechanism, but as token
   overrides instead of the 11 hardcoded selector overrides v13 used. Set
   data-rc-accent on <html>, <body> or any .rcds-scope root.
   Default (attribute absent) = v13's normal accent.
   ============================================================================ */
:root[data-rc-accent="low"],
.rcds-scope[data-rc-accent="low"],
.rcds-unzoom[data-rc-accent="low"] {
  --rcds-accent-rule: var(--rcds-line-strong);
  --rcds-accent-mark: var(--rcds-text);        /* toplines, pins, underlines */
  --rcds-accent-text: var(--rcds-text-muted);  /* eyebrows, kickers          */
}
:root,
.rcds-scope,
.rcds-unzoom {
  --rcds-accent-mark: var(--rcds-red);
  --rcds-accent-text: var(--rcds-text-muted);
}
:root[data-rc-accent="bold"],
.rcds-scope[data-rc-accent="bold"],
.rcds-unzoom[data-rc-accent="bold"] {
  --rcds-accent-rule: var(--rcds-red);
  --rcds-accent-mark: var(--rcds-red);
  --rcds-accent-text: var(--rcds-red);
}


/* ============================================================================
   §14  SCOPE ROOT
   ----------------------------------------------------------------------------
   `.rcds-scope` is the only thing in this file that sets a non-custom property on
   real elements. Put it on each rc- section wrapper (or once on <main>).

   It exists because of the live theme's element-level rules, which DO reach
   rcds- markup even though the theme never names an .rcds-* class. FULL AUDIT
   against the 2026-07-24 pull — note that css-site.css line 1 is
   `@import bootstrap.min.css`, so BOOTSTRAP'S REBOOT IS IN THE CASCADE TOO and
   is listed here:
     css-site.css:33  h1..h6,.h1..h6 { font-family:var(--font-family-second);
                                       font-weight:700; color:var(--gray-dark);
                                       FONT-STYLE: ITALIC }            (0,0,1)
                       ↑ every heading on the store is italic. Unreset, every
                         rcds Saira Condensed heading would render italic.
     css-site.css:50  img { height:auto }        → fights object-fit covers
     css-site.css:54  a   { color:var(--gray-dark) }
     css-site.css:58  a:hover,a:focus { outline:0; color:var(--theme-color) }
                       ↑ leaks the theme's FIFTH red (#be2e1a) into rcds links
                         AND kills the focus outline on every anchor   (0,1,1)
     css-site.css:66  button:focus,.btn:focus { outline:unset; box-shadow:unset }
     css-site.css:69  button/input/select/textarea:focus-visible { outline:unset }
     bootstrap        h1..h6 { margin-top:0; margin-bottom:.5rem; font-weight:500;
                               line-height:1.2 } + per-level font-size 1–2.5rem
     bootstrap        p,ul,ol,dl { margin-top:0; margin-bottom:1rem }
     bootstrap        a { color:#007bff } · a:hover { color:#0056b3;
                          text-decoration:UNDERLINE }                  (0,1,1)
     bootstrap        img { vertical-align:middle; border-style:none }
     bootstrap        svg { overflow:hidden; vertical-align:middle }
     bootstrap        label { display:inline-block; margin-bottom:.5rem }
     bootstrap        summary { display:list-item; cursor:pointer }
     bootstrap        legend { display:block; width:100%; font-size:1.5rem }
     bootstrap        button,input,select,textarea { margin:0; font:inherit }
     bootstrap        button { border-radius:0 } · button:focus { outline:1px dotted }
     bootstrap        table { border-collapse:collapse }
   Nothing in either file carries !important at element level (verified: 0 hits
   for a bare-element selector with !important in css-site.css, bootstrap and
   the two inline <style> blocks in layout/theme.liquid), so specificity alone
   settles every one of these. No @layer: cascade layers lose to unlayered CSS,
   and every rule above is unlayered.

   ⚠ HOW THE ELEMENT IS WRITTEN MATTERS AS MUCH AS THE SPECIFICITY.
   Every element in a reset below is wrapped in `:where()`, which contributes
   ZERO specificity. `.rcds-scope :where(img)` is (0,1,0): still above the
   theme's `img{height:auto}` (0,0,1), but no longer above a component class
   like `.rcds-nav__logo{height:42px}` (0,1,0), which the old un-wrapped
   `.rcds-scope img` (0,1,1) silently beat. A scope reset must sit BETWEEN the
   theme and our own components, never on top of them. The only exceptions are
   the :hover/:focus rules, which use `:is()` (specificity of its most specific
   argument) precisely because they have to clear the theme's (0,1,1).

   ⚠ KNOWN LIMIT, measured so nobody rediscovers it the hard way. These resets
   answer the theme's ELEMENT-level rules. They do NOT answer the theme's
   CONTAINER rules — selectors like `.navbar-light .navbar-text a{color:…}`,
   which are (0,2,1) or higher. Counted on the live pull: 266 such rules set
   `color` on a descendant <a>, 154 set `height` on a descendant <img>, 73 set
   `text-decoration` on <a>, 65 set `color` on <label>, 49 set `color` on
   <button>. None of them reach an rcds component rendered as a TOP-LEVEL
   section. All of them reach one nested inside a legacy Wpbingo container.
   RULE: render rcds sections as siblings of theme sections, never inside one.
   Where nesting is unavoidable the component must clear that specific container
   rule on its own root — check it, do not assume, and do not reach for
   !important as the first answer.
   ============================================================================ */
.rcds-scope {
  font-family: var(--rcds-font-ui);
  font-size: var(--rcds-text-md);
  font-weight: var(--rcds-fw-regular);
  line-height: var(--rcds-lh-body);
  color: var(--rcds-text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

.rcds-scope *,
.rcds-scope *::before,
.rcds-scope *::after { box-sizing: border-box; }

/* Undo the store-wide italic heading and the theme's Barlow.
   H2: `font-style:normal` is the load-bearing declaration here — css-site.css's
   `h1..h6{font-style:italic}` is the ONLY other declaration of that property on
   a heading, so without this line it wins by default, not by specificity. */
.rcds-scope :where(h1, h2, h3, h4, h5, h6) {
  font-family: var(--rcds-font-display);
  font-style: normal;
  font-weight: var(--rcds-fw-black);
  line-height: var(--rcds-lh-display);
  letter-spacing: var(--rcds-track-display);
  text-transform: uppercase;
  color: var(--rcds-text);
  margin: 0;
}

/* margin only. Deliberately NOT `list-style:none` / `padding-left:0`: a rich-text
   <ul> inside an rcds section is editorial content and must keep its bullets.
   The two components that need a bare list (breadcrumb, pagination) strip it
   on their own class. */
.rcds-scope :where(p, ul, ol, dl, figure, blockquote) { margin: 0; }

.rcds-scope :where(a) {
  color: inherit;
  text-decoration: none;
}
/* H3: `:is()` carries the specificity of its most specific argument, so this is
   (0,2,0) and clears css-site.css:58 `a:hover,a:focus{color:var(--theme-color)}`
   plus bootstrap's `a:hover{color:#0056b3;text-decoration:underline}`, both
   (0,1,1). It sits EARLY on purpose: a component that wants a real hover colour
   restates it at (0,2,0) later in rcds-base.css / rcds-nav.css and wins on
   source order. */
.rcds-scope :where(a):is(:hover, :focus, :focus-visible, :active) {
  color: inherit;
  text-decoration: none;
}

.rcds-scope :where(img) { display: block; max-width: 100%; height: auto; }
.rcds-scope :is(.rcds-media, .rcds-cover) > img { height: 100%; }
.rcds-scope :where(svg) { display: block; }

.rcds-scope :where(button) {
  font-family: inherit;
  color: inherit;
  cursor: pointer;
  border: none;
  background: none;
}
.rcds-scope :where(input, select, textarea) { font-family: inherit; }
/* bootstrap ships `label{display:inline-block;margin-bottom:.5rem}` — the
   margin is the part that leaks into every rcds form row. <summary> is left
   alone on purpose: bootstrap's `display:list-item` matches the UA default, and
   removing the marker globally would make an unstyled <details> look broken. */
.rcds-scope :where(label) { margin-bottom: 0; }
.rcds-scope :where(fieldset) { min-width: 0; margin: 0; padding: 0; border: 0; }
.rcds-scope :where(legend) { width: auto; padding: 0; margin-bottom: 0; font-size: inherit; }
.rcds-scope :where(table) { border-collapse: collapse; width: 100%; }

/* Restore the focus ring the theme removes. `:is()` again, not `:where()`:
   this one HAS to beat css-site.css:66/:69 `outline:unset` (0,1,1) and
   css-site.css:58 `a:focus{outline:0}` (0,1,1). (0,2,0) does it. */
.rcds-scope :is(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--rcds-focus-ring);
  outline-offset: var(--rcds-focus-offset);
}

/* Container primitive (v13 `.wrap`). Namespaced away from bootstrap's
   .container (87 matches) and css-site.css's .container (7 matches). */
.rcds-wrap {
  max-width: var(--rcds-container);
  margin-inline: auto;
  padding-inline: var(--rcds-gutter);
}
.rcds-wrap--full { max-width: none; }

/* Vertical rhythm primitive (v13 `.section`). */
.rcds-section       { padding-block: var(--rcds-section-y); }
.rcds-section--tight { padding-block: var(--rcds-section-y-tight); }


/* ============================================================================
   §15  FORCED COLORS + PRINT
   ----------------------------------------------------------------------------
   v13 has zero handling for either. Windows High Contrast drops every
   background-image, which erases the scrim on tiles whose text is white-on-
   photo — the copy becomes white on white. Minimum viable guard below.
   ============================================================================ */
@media (forced-colors: active) {
  :root,
  .rcds-scope,
  .rcds-unzoom {
    --rcds-scrim-weak:   Canvas;
    --rcds-scrim:        Canvas;
    --rcds-scrim-strong: Canvas;
    --rcds-text-ondark:       CanvasText;
    --rcds-text-ondark-2:     CanvasText;
    --rcds-text-ondark-muted: CanvasText;
  }
  .rcds-scope :is(a, button):focus-visible { outline: 2px solid Highlight; }
}

@media print {
  :root,
  .rcds-scope,
  .rcds-unzoom {
    --rcds-z: 1;              /* zoom is not applied to print output */
    --rcds-elev-1: none;
    --rcds-elev-2: none;
    --rcds-elev-3: none;
    --rcds-elev-brand: none;
  }
}
