/* Roof Racks Galore — shared design tokens & component library, used across all four PDP templates */

/* Google Fonts are loaded via <link rel="preconnect">/<link rel="stylesheet"> in each
   page's <head> now, not an @import here (2026-09-11, mobile audit) — @import blocks
   the browser from discovering/fetching the font until after this whole stylesheet is
   parsed, which is a real render/LCP cost on mobile networks that <link> avoids. */

:root{
  --rrg-black:#000;
  --rrg-red:#BB0220;
  --rrg-red-dark:#8f0119;
  --rrg-gold:#BEA98A;
  --rrg-gold-bg:#FFF9E8;
  --rrg-line:#D8D8D8;
  --rrg-bg:#F5F5F5;
  --rrg-fits:#1E7A34;
  --rrg-fits-bg:#EAF7EE;
  --rrg-unknown:#B36B00;
  --rrg-unknown-bg:#FFF4E5;
  --rrg-nofit:#A6192E;
  --rrg-nofit-bg:#FDEAEC;
  --rrg-display:#1A56DB;
  --rrg-display-bg:#EAF1FD;
  --radius:12px;
  --shadow:0 8px 22px rgba(0,0,0,.06);
  --maxw:1280px;
}

*{box-sizing:border-box;}
[hidden]{display:none!important;}
html{scroll-behavior:smooth;}
body{
  margin:0;
  font-family:'Lato',Arial,Helvetica,sans-serif;
  color:#232323;
  background:#fff;
  line-height:1.45;
}
h1,h2,h3,h4{
  font-family:'Barlow Condensed',Arial,sans-serif;
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:.01em;
  margin:0 0 .4em;
  color:var(--rrg-black);
}
/* Product title — was locally overridden per template (23-26px, drifted over time); unified
   2026-09-13 per client request so every template renders the same size. */
.decision-panel h1{font-size:32px;line-height:1.1;margin-bottom:6px;}
p{margin:0 0 1em;}
img{max-width:100%;display:block;}
a{color:inherit;}
button{font-family:inherit;cursor:pointer;}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px;}

/* top strip (legacy — superseded by .rrg-utility-bar/.rrg-main-header below, kept in case any page still references it) */
.rrg-topbar{background:var(--rrg-black);color:#fff;font-size:12px;font-weight:900;letter-spacing:.04em;text-align:center;padding:7px 12px;}
.rrg-header{border-bottom:1px solid var(--rrg-line);padding:14px 0;}
.rrg-header .wrap{display:flex;align-items:center;justify-content:space-between;}
.rrg-logo{font-family:'Barlow Condensed',sans-serif;font-weight:700;font-size:22px;letter-spacing:.02em;}
.rrg-logo b{color:var(--rrg-red);}

/* Site header — matches "Navbar - Logged In - Final.png" */
/* .rrg-header-shell (2026-09-14 fix, wraps .rrg-utility-bar + .rrg-main-header in every
   template's markup) is the ONE positioned/z-indexed ancestor for both bars, replacing an
   earlier attempt that gave each bar its OWN position+z-index directly. That earlier version
   couldn't win both ways at once: .rrg-utility-bar and .rrg-main-header each formed their own
   stacking context, so whichever had the higher z-index trapped the OTHER's cross-boundary
   content behind it regardless of that content's own z-index — the Region Selector dropdown
   (.region-switcher-menu, a descendant of the utility bar, drops DOWN into the main header's
   box) needed the utility bar to win, while the UK region logo (.rrg-main-header .rrg-logo
   img, below) bleeds UP into the utility bar's box and needed main-header to win — no single
   ordering of the two satisfies both. Removing position/z-index from each bar and putting it
   on their shared wrapper instead means neither bar is its own stacking context any more, so
   both cross-boundary elements are compared directly in the SAME context and simply paint
   above the plain (non-positioned) bar backgrounds either direction, as intended. The shell
   still needs its own z-index above .mega-menu-backdrop (mega-menu.css, z-index:80) so the
   whole header stays undimmed while the backdrop dims the rest of the page. */
.rrg-header-shell{position:relative;z-index:85;}
.rrg-utility-bar{background:var(--rrg-red);color:#fff;font-size:12.5px;}
.rrg-utility-inner{display:flex;align-items:center;justify-content:space-between;padding:9px 24px;gap:20px;flex-wrap:wrap;}
.rrg-utility-left,.rrg-utility-right{display:flex;align-items:center;gap:26px;flex-wrap:wrap;}
.u-item{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;}
.u-item svg{flex:0 0 auto;width:14px;height:14px;}
.u-item a{color:#fff;text-decoration:underline;font-weight:700;}
.u-item .flag-emoji{font-size:14px;line-height:1;}

/* Region Selector (2026-09-11, backlog item 21) — the utility bar's country item, previously
   static/decorative, is now a working dropdown. Same toggle-a-class-on-click,
   click-outside-to-close interaction as the Site Admin Panel's own dropdowns
   (admin-panel.css), just recoloured for sitting on the red utility bar (white trigger text)
   instead of the white main header. */
.region-switcher{position:relative;}
.region-switcher-toggle{background:none;border:none;padding:0;font:inherit;font-size:12.5px;color:#fff;cursor:pointer;}
.region-switcher-menu{position:absolute;top:calc(100% + 10px);right:0;background:#fff;border:1px solid var(--rrg-line);border-radius:var(--radius);box-shadow:var(--shadow);min-width:180px;padding:8px;display:none;flex-direction:column;gap:1px;z-index:80;}
.region-switcher.open .region-switcher-menu{display:flex;}
.region-switcher-menu .tsm-label{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:#999;padding:6px 10px 4px;}
.region-switcher-menu a{display:flex;align-items:center;gap:8px;padding:9px 10px;border-radius:7px;font-size:13.5px;font-weight:600;color:var(--rrg-black);text-decoration:none;}
.region-switcher-menu a:hover{background:#f4f4f4;color:var(--rrg-red);}
.region-switcher-menu a.current{color:var(--rrg-red);background:#faf0ef;}

.rrg-main-header{background:#fff;border-bottom:1px solid var(--rrg-line);padding:16px 0;}
.rrg-main-inner{display:flex;align-items:center;gap:32px;padding:0 24px;flex-wrap:wrap;}
.rrg-main-inner .rrg-logo{flex:0 0 auto;}
.rrg-logo img{height:34px;width:auto;display:block;}
.rrg-nav{display:flex;align-items:center;gap:22px;font-size:14.5px;font-weight:700;flex:0 0 auto;}
.rrg-nav a{color:var(--rrg-black);text-decoration:none;display:inline-flex;align-items:center;gap:6px;}
.rrg-nav a:hover{color:var(--rrg-red);}
.rrg-nav .sep{color:var(--rrg-line);}

.rrg-search{flex:1 1 260px;max-width:420px;display:flex;align-items:center;border:1.5px solid var(--rrg-line);border-radius:8px;overflow:hidden;margin-left:auto;}
.rrg-search input{flex:1;border:none;padding:11px 14px;font-size:13.5px;font-family:inherit;outline:none;min-width:0;}
/* Clear (x) button — matched to client-supplied Figma export "Navbar - Logged In -
   Final.png", which shows it beside the search icon on mobile. Generic, so it also shows
   up on desktop where the input has a value; initSearchClear() in shared.js toggles it. */
.rrg-search-clear{background:none;border:none;color:#999;padding:0 8px;font-size:18px;line-height:1;flex:0 0 auto;cursor:pointer;}
.rrg-search-clear:hover{color:#666;}
/* align-self:stretch (not height:100%, 2026-09-11 fix) — .rrg-search has no explicit height
   of its own (it's sized by its tallest child, the input), so a percentage height on this
   button had nothing definite to resolve against and fell back to the button's own content
   height (~16px, just the icon) — the red background covered only that vertically-centered
   16px sliver instead of the full ~40px pill, which read as a rendering bug. align-self
   stretches the button to match the flex line's actual cross-size instead. */
.rrg-search-btn{background:var(--rrg-red);border:none;color:#fff;padding:0 16px;align-self:stretch;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:0 0 auto;}
.rrg-search-btn svg{width:16px;height:16px;flex:0 0 auto;}
.rrg-cart{position:relative;flex:0 0 auto;color:var(--rrg-black);cursor:pointer;}
.rrg-cart svg{width:24px;height:24px;}
.cart-badge{position:absolute;top:-6px;right:-8px;background:var(--rrg-red);color:#fff;font-size:10px;font-weight:900;border-radius:999px;width:16px;height:16px;display:flex;align-items:center;justify-content:center;}

/* Mobile nav toggle (2026-09-11, mobile audit; behaviour replaced 2026-09-13, header
   integration) — hidden by default (desktop hamburger icon would be pointless), shown only
   inside the 900px media query below. Opens the full-screen mega-menu takeover
   (.mm-mobile-takeover, initMobileNav() in shared.js) rather than .rrg-nav itself, which is
   just hidden outright on mobile now — its content (mega menu + the 4 plain nav links) is
   fully mirrored inside the takeover for that viewport instead. */
.mobile-nav-toggle{display:none;background:none;border:none;padding:10px;margin:-10px;color:var(--rrg-black);flex:0 0 auto;}
.mobile-nav-toggle svg{width:22px;height:22px;display:block;}
/* Main header, mobile layout (2026-09-11, matched to client-supplied Figma export "Navbar
   - Logged In - Final.png") — hamburger / centered logo / cart as one row, search bar as
   its own full-width row below, instead of everything crammed into one flex row like
   desktop. Grid (not flex) so the search row can sit on an explicit row 2 without needing
   flex `order` tricks that would also disturb the hamburger/logo/cart row. */
@media (max-width:900px){
  .mobile-nav-toggle{display:flex;align-items:center;justify-content:center;}
  .rrg-main-inner{display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:auto auto;align-items:center;column-gap:12px;row-gap:10px;}
  .mobile-nav-toggle{grid-row:1;grid-column:1;}
  .rrg-main-inner .rrg-logo{grid-row:1;grid-column:2;justify-self:center;}
  .rrg-cart{grid-row:1;grid-column:3;justify-self:end;}
  .rrg-search{grid-row:2;grid-column:1/-1;margin-left:0;max-width:none;}
  .rrg-nav{display:none;}
}

/* Sticky condensed header (2026-09-11, matched to client-supplied Figma export "Mob
   Navbar - Final - Sticky.png") — hamburger/logo/cart only, no utility bar or search,
   fixed to the top once the top-of-page search row scrolls out of view. Reuses
   initPersistentBar()'s existing sentinel/.visible convention (already used for the
   desktop decision bar on vehicle-specific) rather than writing a second scroll observer.
   Hidden entirely on desktop — the whole point is replacing the mobile-only search row
   once it's scrolled away, desktop's header has no equivalent collapsed state. */
.rrg-sticky-header{display:none;}
@media (max-width:900px){
  .rrg-sticky-header{
    display:flex;align-items:center;justify-content:space-between;gap:12px;
    position:fixed;top:0;left:0;right:0;z-index:55;
    background:#fff;border-bottom:1px solid var(--rrg-line);
    padding:10px 16px;
    transform:translateY(-100%);
    transition:transform .2s ease;
    box-shadow:0 4px 14px rgba(0,0,0,.08);
  }
  .rrg-sticky-header.visible{transform:translateY(0);}
  .rrg-sticky-header .rrg-logo img{height:26px;}
  .rrg-sticky-header .mobile-nav-toggle{display:flex;}
}
/* Mobile utility bar (2026-09-11, matched to client-supplied Figma exports "Navbar -
   Logged In - Final.png" / "Mob Navbar - Final - Sticky.png") — condenses to just
   Nearest Store (left) and Vehicle (right), dropping Call Us / country / account.
   display:contents on the two wrapper divs (same technique as .gallery-col's mobile
   reorder above) lifts every .u-item to be a direct flex child of .rrg-utility-inner so
   `order` can freely reposition across the original left/right grouping; hiding every
   .u-item by default then re-showing just the two wanted ones by position keeps this a
   pure-CSS fix with no markup changes needed across all 6 pages. */
@media (max-width:900px){
  .rrg-utility-left,.rrg-utility-right{display:contents;}
  .rrg-utility-inner{justify-content:space-between;text-align:left;flex-wrap:nowrap;}
  .u-item{display:none;min-width:0;}
  .rrg-utility-left .u-item:first-child{display:inline-flex;order:1;}
  .rrg-utility-left .u-item:nth-child(2){display:inline-flex;order:2;}
  /* Figma's mobile utility bar shows icon + value only ("North Lakes", "Toyota Hilux"),
     dropping the "Your Nearest Store:"/"Your Vehicle:" prefix — matches the export exactly
     and was also a real overflow bug fix: that label text couldn't fit both items on one
     390px-wide row with flex-wrap:nowrap above (needed to keep them fixed at opposite
     ends rather than wrapping to a second line under the label). */
  .u-item-label{display:none;}
}
.rrg-crumbs{font-size:12px;color:#767676;padding:14px 0;}
.rrg-crumbs a{color:#767676;text-decoration:none;}
.rrg-crumbs a:hover{text-decoration:underline;}

/* buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;border:none;border-radius:999px;padding:15px 28px;font-weight:900;font-size:15px;text-transform:uppercase;letter-spacing:.03em;text-decoration:none;text-align:center;transition:transform .12s, box-shadow .12s;}
.btn-primary{background:var(--rrg-red);color:#fff;}
.btn-primary:hover{background:var(--rrg-red-dark);}
.btn-primary:active{transform:scale(.98);}
.btn-block{width:100%;}

/* Add to Cart is gold, not red (locked in per client, 2026-09-10) — [data-cta-label] hits
   every Add to Cart button on the page (decision panel, sticky mobile bar, persistent bar)
   without needing per-button wiring; other .btn-primary buttons (e.g. Find Nearest Showroom)
   stay red. */
[data-cta-label].btn-primary{background:#FFCA48;color:#000;}
[data-cta-label].btn-primary:hover{background:#e6b53f;}
.btn-lg{padding:18px 28px;font-size:16px;}
.btn-outline{background:#fff;border:1.5px solid var(--rrg-black);color:var(--rrg-black);}

/* UK brand skin (Region Selector, 2026-09-11) — RRG trades in the UK as "The Roof Box
   Company" (roofbox.co.uk), a real sister brand. Scope confirmed with Brenton: logo + core
   colour only, not a typography change. Overriding --rrg-red/--rrg-red-dark here recolours
   every component already built against those tokens (utility bar, trust icons, links, tab
   underline, sale badges, etc.) for free — see applyRegionBrand() in shared.js, which
   toggles this class. Add to Cart needs its own override since it isn't on the --rrg-red
   token to begin with (RRG's own gold default, directly above) — colours are their real
   scraped brand values: navy #2E41AE / #FFFF19 from their logo SVG itself, green #26B226
   from their live "Click Here To Order" button (confirmed with Brenton as the preferred
   option over keeping RRG's gold). */
body.region-uk{--rrg-red:#2E41AE;--rrg-red-dark:#1F2E82;}
body.region-uk [data-cta-label].btn-primary{background:#26B226;color:#fff;}
body.region-uk [data-cta-label].btn-primary:hover{background:#1e8f1e;}
/* The Roof Box Company's real logo is a tall vertical rectangle (117.89x143.63, ~0.82:1),
   not RRG's wide horizontal wordmark (360x58, ~6.2:1) — Brenton asked for it to actually
   span both header bars (the red/navy Utility Bar above + the white Main Header row below)
   rather than just sit taller within the Main Header alone, since it reads as a nice badge
   effect with a portrait logo like this — on **both** desktop and mobile, not desktop only.
   `.rrg-logo` stays a normal flex/grid item (reserving its own footprint so the other
   header items don't shift), but its `<img>` is pulled out of flow and absolutely
   positioned against it. Neither bar clips overflow, and the Main Header simply paints
   after (on top of) the Utility Bar in normal DOM order, so no z-index juggling is needed
   for the overlap itself — the explicit z-index below is just a safety margin against
   future stacking-context changes nearby.
   Span amount, per Brenton's exact spec (not flush like the first attempt): the logo's
   **bottom** edge sits flush with the base of the white Main Header (or, on mobile, the
   base of the icon row specifically — see below), and its **top** edge reaches only
   halfway up through the blue Utility Bar, not all the way to the Utility Bar's own top.
   `.rrg-utility-left` gets matching left margin (desktop only, where it's a single row of
   text) so "Your Nearest Store" / "Your Vehicle" visibly starts clear of the logo instead
   of sitting underneath it.
   Known gotcha (hit twice building this): once the `<img>` is the ONLY child of `.rrg-logo`
   and gets pulled `position:absolute`, `.rrg-logo`'s own box collapses to ~0 height/width,
   which shifts a *centre*-aligned item's apparent anchor point away from where simple
   "row height" math assumes. `align-self:flex-start` (flex) / `align-self:start` (grid)
   fixes this by anchoring to the row's actual top edge instead of a collapsed box's
   centre — confirmed by measuring the rendered position with Playwright
   (`getBoundingClientRect()`), not just eyeballing a screenshot. */
@media (min-width:901px){
  /* Desktop: Utility Bar 36px tall, Main Header 73px tall, row content starts 52px down
     the page (Main Header's own 36px top + its 16px top padding). Halfway through the
     Utility Bar = 18px down the page; base of the Main Header = 109px down the page. */
  body.region-uk .rrg-main-header .rrg-logo{position:relative;width:90px;flex:0 0 90px;align-self:flex-start;}
  body.region-uk .rrg-main-header .rrg-logo img{position:absolute;top:-34px;left:0;height:91px;width:auto;z-index:5;}
  body.region-uk .rrg-utility-left{margin-left:120px;}
}
@media (max-width:900px){
  /* Mobile: `.rrg-main-inner` is a 2-row grid here (icon row, then the search bar right
     underneath) — "base of the Main Header" means the base of the icon row specifically,
     not the full header including the search row, or the logo would run down through the
     search input. Same 52px row-start and 18px Utility-Bar-halfway values as desktop (the
     Utility Bar itself doesn't change between breakpoints), but the icon row's own base
     sits at 86px down the page (measured — it's shorter than desktop's Main Header).
     Horizontal centring uses left:50%/translateX(-50%) instead of left:0, since
     `.rrg-logo` here is `justify-self:center` in the grid (not left-aligned like desktop)
     and its own collapsed-box width can't be relied on to centre a `left:0` child. */
  /* width:56px on the DIV too (not just the img below) — the real bug here wasn't
     width:auto resolution, it was the global `img{max-width:100%}` reset (this
     file's base image reset) clamping the img's width against its own containing
     block. `.rrg-logo` has no explicit width on mobile once its only child is pulled
     `position:absolute` (unlike desktop, which reserves 90px), so it collapses to 0 —
     and max-width:100% of a 0-width containing block clamps the img itself to 0,
     which is why it visually vanished (confirmed with Playwright: computed width was
     0px despite the rule below plainly saying width:56px in the CSSOM — max-width
     was silently winning). Giving the div the same fixed width the img itself needs
     fixes both the collapse and the max-width clamp in one move. */
  body.region-uk .rrg-main-header .rrg-logo{position:relative;align-self:start;width:56px;}
  body.region-uk .rrg-main-header .rrg-logo img{position:absolute;top:-34px;left:50%;transform:translateX(-50%);height:68px;width:56px;z-index:5;}
}
/* Sticky condensed mobile header (2026-09-11 follow-up): Brenton pointed out that if the
   logo spans "into the blue bar," that has to stay true once the page is scrolled and the
   Utility Bar itself is gone — replaced by this fixed hamburger/logo/cart bar. So the UK
   sticky header grows its own blue band to span into, via a thick `border-top` (adds to
   the element's own box height automatically, no extra markup, no off-screen positioning
   tricks — unlike the Utility Bar above, which already exists in-flow, this fixed bar has
   nothing above it, so the "blue bar" has to be invented as a literal part of this box)
   sized to roughly the same Utility-Bar-to-Main-Header proportion as the top-of-page
   header (~36:73, roughly 2:4). The white hamburger/logo/cart row's own vertical centring
   is unaffected by the border (borders sit outside the padding/content box, so they don't
   compress it) — only the box's total rendered height grows to make room. */
body.region-uk .rrg-sticky-header{border-top:20px solid var(--rrg-red);}
/* width:49px on the div too — same max-width:100%-clamps-a-collapsed-container bug as
   the Main Header logo above, same fix. */
body.region-uk .rrg-sticky-header .rrg-logo{position:relative;align-self:flex-start;width:49px;}
body.region-uk .rrg-sticky-header .rrg-logo img{position:absolute;top:-20px;left:50%;transform:translateX(-50%);height:60px;width:49px;z-index:5;}

/* badges */
.badge{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:900;text-transform:uppercase;letter-spacing:.03em;padding:5px 12px;border-radius:999px;}
/* border-radius override only (spec.md Section 12 item 23, Figma reference) — rectangular,
   not the shared .badge pill shape. Scoped to -save specifically since .badge is never
   reused for anything else in this project (confirmed via repo-wide search). */
.badge-save{background:var(--rrg-red);color:#fff;border-radius:8px;text-transform:none;letter-spacing:normal;}

/* fitment states — softened 2026-09-10 per client feedback: was a full solid-tinted
   box (heavy fill + full-strength border all round); now a near-white card with a
   colored left accent only, so it stays structurally boxed/scannable without
   competing visually with price/Add to Cart. Label + dot keep the state color for
   quick scanning; body copy is neutral gray, not tinted. */
.fitment{display:flex;align-items:flex-start;gap:12px;background:#fff;border:1px solid var(--rrg-line);border-radius:var(--radius);padding:14px 16px;font-size:14px;color:#4a4a4a;}
/* Car icon (2026-09-11) replaces the old plain colour dot — same state colour via
   currentColor/fill, just a more legible fitment-state indicator at a glance.
   align-self:center (2026-09-11 follow-up) centers it against the full bar height,
   not just the text block's top line, and it's sized up to read clearly at a glance. */
.fitment .dot{width:26px;height:26px;flex:0 0 auto;align-self:center;display:inline-flex;}
.fitment .dot svg{width:100%;height:100%;display:block;}
.persistent-bar .fitment .dot,.sticky-cta-mobile .fitment .dot{width:18px;height:18px;}
/* Copy-to-clipboard variant (2026-09-11, backlog item 10) — persistent bar + mobile
   sticky bar only, see [data-fitment-copyable] in applyFitmentState(). Green flash on
   click reuses the same confirmation colour as .sku-copy.copied elsewhere, regardless
   of the icon's current fitment-state colour. */
.dot-copy{cursor:pointer;}
.dot-copy.copied{color:var(--rrg-fits)!important;}
.fitment strong{display:block;font-family:'Barlow Condensed',sans-serif;text-transform:uppercase;font-size:15px;letter-spacing:.02em;margin-bottom:2px;}
.fitment.fits{border-left:3px solid var(--rrg-fits);}
.fitment.fits strong{color:var(--rrg-fits);}
.fitment.fits .dot{color:var(--rrg-fits);}
.fitment.unknown{border-left:3px solid var(--rrg-unknown);}
.fitment.unknown strong{color:var(--rrg-unknown);}
.fitment.unknown .dot{color:var(--rrg-unknown);}
.fitment.no_fit{border-left:3px solid var(--rrg-nofit);}
.fitment.no_fit strong{color:var(--rrg-nofit);}
.fitment.no_fit .dot{color:var(--rrg-nofit);}
.fitment .actions{margin-top:8px;display:flex;gap:8px;flex-wrap:wrap;}
/* min-height 48px (2026-09-11, mobile audit) — was 6px/12px padding at 12px font, well
   under Google's 48px tap-target minimum for a real "change vehicle"-type action. */
.fitment .actions button{display:inline-flex;align-items:center;justify-content:center;min-height:48px;background:#fff;border:1px solid var(--rrg-line);border-radius:999px;padding:6px 16px;font-size:12.5px;font-weight:700;color:#333;}

/* Rack Fit Guarantee (2026-09-10, Graham Sowerby meeting) — real client asset + copy.
   Main decision panel gets icon+text packed into the fitment card's top-right corner;
   the two condensed fitment strips (sticky mobile bar, persistent desktop bar) get an
   icon-only version with a title tooltip since there's no room for the caption there. */
.fitment-wrap{position:relative;}
.fitment-wrap .fitment{padding-right:50px;}
.rack-fit-badge{position:absolute;top:50%;right:10px;transform:translateY(-50%);width:32px;height:auto;cursor:pointer;}
.rack-fit-badge-icon{width:20px;height:auto;flex:0 0 auto;cursor:pointer;}
/* Recolourable placeholder icon (2026-09-12, spec.md Section 12 item 12) — replaces the
   old fitgaurantee.svg (confirmed to be a baked-in raster image wrapped in an <svg>, not
   a real vector, so it couldn't be recoloured at all). Tied directly to --rrg-fits since
   the badge only ever shows in the "Fits your vehicle" state — no dedicated token needed. */
.rack-fit-badge,.rack-fit-badge-icon{color:var(--rrg-fits);}

/* Important Vehicle Fit Notes (2026-09-10, Graham Sowerby meeting) — vehicle-specific only,
   model-specific fitment caveats. Distinct amber/warning accent so it doesn't read as
   another fitment-state box. Starts hidden — see applyVehicleFitNotesFlag() in shared.js. */
.vehicle-fit-notes{background:#FFF8EC;border:1px solid #F0DDB8;border-left:3px solid #B36B00;border-radius:var(--radius);padding:12px 14px;font-size:13px;color:#000;margin-bottom:16px;}
/* Text/icon recoloured black (2026-09-11, legibility fix) — box stays amber-tinted
   (background/border), only the yellow/orange text itself was hard to read. */
.vehicle-fit-notes strong{display:block;font-family:'Barlow Condensed',sans-serif;text-transform:uppercase;font-size:13.5px;letter-spacing:.02em;color:#000;margin-bottom:4px;}
.vehicle-fit-notes p{margin:0;line-height:1.4;}

/* reviews strip */
.reviews-strip{display:flex;align-items:center;gap:8px;font-size:13px;color:#232323;}
.stars{color:#E8A83C;letter-spacing:1px;font-size:15px;}
.stars .stars-empty{opacity:.35;}
.reviews-strip a{font-weight:700;text-decoration:underline;color:var(--rrg-black);}

/* price block — restyled 2026-09-12 (spec.md Section 12 item 23) to a stacked Now/Was
   layout matching Brenton's Figma reference ("Price Layout Design.png"). .price-row is
   kept as-is (still used by the condensed Persistent Bar's single-line price, which stays
   a plain row — see the Persistent Bar/Sticky Mobile Bar rules further down). .price-now/
   .price-was/.badge-save keep their exact class names/semantics so every existing JS hook
   (reapplySaleFlag()/setSaleFlag()/detectInitialSaleState()/syncSaleTag(), plus each
   template's own renderPrice()-equivalent) keeps working unchanged against the new
   surrounding markup — see syncPriceLabels() in shared.js for the new label/line toggling. */
.price-row{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;}
.price-line{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;}
/* line-height:1 on both children (2026-09-12 follow-up) — the inherited body line-height
   of 1.45 was adding a lot of invisible space below .price-now's glyphs specifically (its
   42px font-size makes that space large in absolute terms: a 60.9px line box around text
   that's really only ~29px tall), which is what actually read as "a large gap" between the
   Now/RRP lines even though the explicit margin between them was already only 2px. Scoped
   to the Now line only — the RRP line's own line-height is deliberately left at the
   inherited 1.45 since .price-was's font-size was tuned against that line-height to match
   .badge-save's real rendered height (see below). */
.price-line-now{margin-bottom:2px;}
.price-line-now .price-now,.price-line-now .price-label{line-height:1;}
/* Sale/RRP read as one "widget" (2026-09-12 follow-up), not two loosely-related lines —
   align-items:center (was the .price-line default of baseline, which put the Save badge's
   own centred padding out of true vertical alignment with the RRP text's baseline) plus a
   tight explicit line-height on the RRP text itself (see .price-was/.price-label below —
   the inherited body line-height of 1.45 was adding real invisible space above/below the
   glyphs on both lines, which read as a large gap even though the margin between the two
   line boxes was already only 2px). .badge-save is deliberately left off this line-height
   change since its real rendered height (matched to the RRP price's font-size in the
   previous follow-up) depends on the inherited 1.45 line-height. */
.price-line-was{gap:6px;align-items:center;}
.price-label{font-family:'Barlow Condensed',sans-serif;font-weight:700;font-size:22px;}
/* "Now"/the price share one red once on sale (.price-block.on-sale, see below) — plain
   (non-sale) state keeps the label neutral black, matching the plain price beside it. */
.price-line-now .price-label{color:var(--rrg-black);}
/* "RRP" (2026-09-12 follow-up, renamed from "Was") deliberately does NOT use the shared
   .price-label treatment above — Brenton's feedback was that the bold Barlow Condensed
   label read as heavier/a different colour than the grey RRP price next to it, even though
   the hex was already identical (bold ink coverage reads visually darker/more saturated
   at the same colour). Fixed by making the label match .price-was's actual font exactly
   (family/weight/size/colour) rather than just its colour — the whole "RRP $319.00" then
   reads as one consistent phrase, which also makes the shared text-decoration:line-through
   on both spans look like one continuous strike rather than two different-weight pieces. */
.price-line-was .price-label{font-family:inherit;font-weight:400;font-size:19px;color:#434343;text-decoration:line-through;}
/* "Now" only reads red in contrast against a real "RRP" price (.price-block.on-sale,
   toggled by syncPriceLabels() off the same .price-was.hidden state that already drove
   the old single-row layout) — a plain full price stays neutral black, same as before
   this redesign. Brenton's Figma reference is explicitly an on-sale example; reserving red
   for the sale contrast itself (not every regular price) matches standard practice and
   was flagged as a judgement call at plan review. */
.price-block.on-sale .price-now,.price-block.on-sale .price-line-now .price-label{color:var(--rrg-red);}
.price-now{font-family:'Barlow Condensed',sans-serif;font-size:42px;font-weight:700;color:var(--rrg-black);}
/* font-size 19px (2026-09-12 follow-up) — sized to match .badge-save's real rendered
   height (measured via Playwright: badge ~27.4px tall at 12px/1.45 line-height; 19px at
   the same inherited line-height renders ~27.6px), per Brenton's ask that the RRP price
   visually match the Save-badge pill's height rather than sitting noticeably smaller. */
.price-was{font-size:19px;color:#434343;text-decoration:line-through;}

/* Stock status line — replaces the old generic "estimate shipping" copy with the
   product's actual stock state (mirrors the fitment-state colour language: green/amber/
   red). Driven by the demo admin panel's 4-way "Stock status" control, see
   applyStockStatus() in shared.js — defaults to whatever's in the static markup below. */
.stock-status-line{font-size:12.5px;font-weight:700;display:flex;align-items:center;gap:6px;margin-top:4px;}
.stock-status-line.in-stock{color:var(--rrg-fits);}
.stock-status-line.low-stock{color:var(--rrg-unknown);}
.stock-status-line.not-in-stock{color:var(--rrg-nofit);}
.stock-status-line.special-order{color:var(--rrg-unknown);}
.stock-status-line.discontinued{color:var(--rrg-nofit);}

/* Discontinued state (backlog item 23) keeps the last real selling price on screen
   ("the price it was sold at") rather than hiding it — struck through, same visual
   language as .price-was's original-price crossout when on sale. */
.price-block.discontinued .price-now{text-decoration:line-through;color:#434343;}

/* "On Display" pill — corrected 2026-09-10 (client feedback): belongs on individual store
   rows in the Click & Collect widget / store slide-out (a given store either has this
   product on display or it doesn't), not as a blanket pill beside the product's overall
   stock status. See .stock-chip.in/.order above and rrgStorePillsHTML() in shared.js. */
.stock-chip.display{background:var(--rrg-display-bg);}

/* Payment-plan badges — sits directly under Add to Cart, inside .cta-col, centered to
   match the button above. Real brand wordmarks (official SVGs), amount text computed
   live from the current price via syncPaymentBadges() in shared.js so it tracks sale/
   variant/colour switches automatically (called from reapplySaleFlag()). */
.payment-badges{display:flex;align-items:stretch;justify-content:center;margin-top:12px;}
.payment-badge{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:5px;flex:1;min-width:0;padding:0 14px;text-align:center;}
.payment-badge:not(:first-child){border-left:1px solid var(--rrg-line);}
.pb-logo{height:15px;width:auto;display:block;}
/* white-space:nowrap removed (2026-09-10) — forced the instalment line ("4 payments of
   $473.27") to stay on one line regardless of available width, which at narrow mobile
   widths (~390px) couldn't shrink to fit 3 badges side by side and forced the whole page
   to horizontally scroll. Wrapping to 2 lines when tight fixes it with no visual change
   at desktop widths, where there's already room for one line. */
.pb-text{font-size:11.5px;color:#666;line-height:1.3;}

/* trust icons */
.trust-row{display:grid;grid-template-columns:repeat(4,1fr);gap:0;border-top:1px solid var(--rrg-line);border-bottom:1px solid var(--rrg-line);margin:32px 0;}
.trust-row .item{padding:20px 18px;border-left:1px solid var(--rrg-line);}
.trust-row .item:first-child{border-left:0;}
.trust-icon{width:26px;height:26px;color:var(--rrg-red);margin-bottom:10px;display:block;}
.trust-row h4{font-size:15px;margin-bottom:4px;}
.trust-row p{font-size:12.5px;color:#666;margin:0;}
/* Phone number link (2026-09-11 follow-up) — bold RRG red so the tappable number stands
   out from the surrounding trust-copy grey, no underline needed at that weight/colour. */
.trust-row p a[href^="tel:"]{color:var(--rrg-red);font-weight:900;text-decoration:none;}

/* USP dot points (backlog item 6, 2026-09-11) — real per-product marketing bullets sourced
   from Rackit, count varies 3-6 per SKU. Vertical stacked list (not Trust Row's horizontal
   4-column grid) since the real content is full sentences, not short labels — a rigid
   equal-width column layout would cramp long text and cause uneven column heights across
   a variable item count. Omitted entirely (no markup at all) on SKUs with no USPs set in
   Rackit, rather than rendered empty. */
.usp-row{display:flex;flex-direction:column;gap:10px;margin:28px 0;padding:20px 22px;background:#faf9f7;border:1px solid var(--rrg-line);border-radius:6px;}
.usp-item{display:flex;align-items:flex-start;gap:10px;}
.usp-icon{width:18px;height:18px;flex:0 0 18px;color:var(--rrg-red);margin-top:2px;}
.usp-item p{margin:0;font-size:14.5px;line-height:1.45;color:#333;}

/* tabs (accordion, mirrors live-site pattern). Scoped to the accordion's own direct-child
   radio inputs (`>`, `[type="radio"]`) rather than a blanket `.tabs input` — backlog item
   13 (2026-09-11) nested a real `.dc-widget` postcode text input inside a tab's `.content`,
   and the old blanket selector was silently display:none-ing it along with every other
   input anywhere inside the tabs (the intended target was always just these radio hacks,
   which are real direct children of `.tabs`, siblings of their `<label>`/`.content`). */
.tabs>input[type="radio"]{display:none;}
.tabs label{display:block;padding:16px 4px;font-family:'Barlow Condensed',sans-serif;font-weight:700;font-size:17px;text-transform:uppercase;border-bottom:1px solid var(--rrg-line);cursor:pointer;position:relative;}
.tabs label::after{content:'+';position:absolute;right:4px;font-size:20px;}
.tabs input:checked + label::after{content:'\2212';}
.tabs .content{max-height:0;overflow:hidden;font-size:14.5px;color:#404247;transition:max-height .25s ease;}
.tabs input:checked + label + .content{max-height:30000px;padding:16px 4px 24px;}

/* Desktop: same DOM/inputs, laid out as a horizontal tab bar with one panel below
   instead of a vertical accordion. Flexbox `order` (not CSS Grid track spanning —
   that undersizes to the labels' combined width, not the full container) regroups
   all labels onto one line, then all .content panels onto the next; each content
   forces its own line via flex-basis:100%, and only the :checked one has height,
   so only one panel is ever visible. Mobile is untouched. */
@media (min-width:901px){
  .tabs{display:flex;flex-wrap:wrap;column-gap:8px;border-bottom:1px solid var(--rrg-line);}
  .tabs label{order:1;flex:0 0 auto;padding:14px 18px;border-bottom:3px solid transparent;margin-bottom:-1px;}
  .tabs label::after{display:none;}
  .tabs input:checked + label{color:var(--rrg-red);border-bottom-color:var(--rrg-red);}
  .tabs .content{order:2;flex:0 0 100%;padding:0;}
  .tabs input:checked + label + .content{padding:24px 4px 8px;max-height:none;}
}

/* Specifications as a real 2-column table (2026-09-10, Graham Sowerby meeting) — the
   underlying data is always attribute/value pairs, never free text, so dot-points were
   a display choice worth fixing rather than a data constraint. */
.specs-table{width:100%;border-collapse:collapse;}
.specs-table tr{border-top:1px solid var(--rrg-line);}
.specs-table tr:first-child{border-top:none;}
.specs-table th,.specs-table td{padding:9px 10px 9px 0;text-align:left;font-size:13.5px;font-weight:400;vertical-align:top;}
.specs-table th{color:#767676;font-weight:600;width:44%;white-space:nowrap;}
.specs-table td{color:#222;}
/* Row hover, desktop only (2026-09-11) — a mobile tap can't "hover", so this is a
   pointer-only affordance, not a touch one. */
@media (min-width:901px){
  .specs-table tr:hover{background:#f7f7f7;}
}

/* PDF icon on Fitting Instructions links (2026-09-11) — wraps each link's existing text,
   no markup restructuring beyond adding the icon + this class. */
.pdf-link{display:inline-flex;align-items:center;gap:6px;}
.pdf-link svg{width:14px;height:14px;flex:0 0 auto;color:var(--rrg-red);}

/* SKU moved to the decision panel's top-right (2026-09-11) — sits beside the brand logo
   on one row instead of its own row below it. */
.decision-panel-top{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:12px;}
.decision-panel-top .brand-logo,.decision-panel-top .brand-logo-text{margin-bottom:0;flex:0 0 auto;}
.decision-panel-top .sku-row{margin-bottom:0;flex:0 0 auto;white-space:nowrap;}

/* Gold Guarantee tab condensed to 2 USP lines + a "Learn more" link, rather than the full
   guarantee copy inline (2026-09-10, Graham Sowerby meeting). No dedicated guarantee page
   exists yet to link to — href="#" placeholder, same convention as other not-yet-built
   destinations in this prototype (flag before this leaves prototype stage). */
.guarantee-usps{margin:0 0 12px;padding-left:20px;}
.guarantee-usps li{margin-bottom:4px;font-size:14px;color:#333;}
.guarantee-learn-more{font-size:13px;color:var(--rrg-red);font-weight:700;text-decoration:none;}
.guarantee-learn-more:hover{text-decoration:underline;}

/* Short description, 2-line clamp with an inline "Read more" (2026-09-10, Graham Sowerby
   meeting; consolidated 2026-09-11 — this used to be split across two elements, .value-prop
   (this slot, under the title) and a second unclamped .short-desc paragraph lower on the page
   duplicating the Details tab's opening line. .value-prop was never a real Rackit field;
   .short-desc is, so the real content moved up here and the class name went with it).
   "Read more" is the link's LAST CHILD inside .short-desc itself (not a sibling row below it)
   so it can sit inline at the end of the visible text — CSS line-clamp can't guarantee that on
   its own (it clips straight through an inline child that doesn't fit on the truncated line),
   so layoutShortDesc() in shared.js measures the real rendered height and trims the text
   word-by-word until "<text>… Read more" fits within exactly 2 lines, re-run on resize since
   available width changes how much fits per line. Base font-size/color declared per-template.
   **Changed 2026-09-12 (Section 12 item 40):** "Read more" no longer jumps to the Details tab
   — it expands the full text in place, with a "See less" link to re-collapse, animated via the
   max-height transition below (toggleShortDesc() in shared.js drives .expanded on/off; the
   markup's old data-jump-tab attribute was removed so initTabJumpLinks() no longer binds it). */
.short-desc{overflow:hidden;transition:max-height .3s ease;}
.short-desc-readmore{margin-left:4px;font-size:12.5px;font-weight:700;color:var(--rrg-red);text-decoration:none;cursor:pointer;white-space:nowrap;}
.short-desc-readmore:hover{text-decoration:underline;}

/* Sticky left column (desktop only): when the decision-panel column ends up taller than
   the gallery/video/install column (variant pickers, showroom finder, package contents
   etc. push its height up), pin the shorter gallery column in place while the taller one
   keeps scrolling, instead of leaving blank space under it once it runs out of content.
   Relies on .hero's existing align-items:start (defined per-page) to leave room in the
   grid row to stick into — a no-op if the gallery column happens to be the taller side,
   so it's safe to apply unconditionally. Scoped to a direct .hero child so it has no
   effect once the gallery-placement demo toggle moves this column out of .hero. */
@media (min-width:901px){
  .hero > .gallery-col{position:sticky;top:20px;}
}

/* gallery */
.gallery-main{position:relative;border-radius:var(--radius);overflow:hidden;background:#f0f0f0;aspect-ratio:3/2;}
.gallery-main img{width:100%;height:100%;object-fit:cover;}
/* Mobile-only Sale Tag (2026-09-12, second follow-up — see the Sale Tag comment near
   .price-block) — sits over the main product image's top-right corner instead of the
   price block on mobile. Hidden entirely on desktop, where the original .price-block
   instance is still the one that shows. `.gallery-main .gallery-sale-tag` (two classes)
   is needed to out-specificity `.gallery-main img` above, which would otherwise stretch
   this to fill the whole image box like the real product photo. `.gallery-main`'s own
   overflow:hidden conveniently clips it flush to the image's rounded corner for free. */
.gallery-sale-tag{display:none;}
@media (max-width:900px){
  .gallery-main .gallery-sale-tag{display:block;position:absolute;top:8px;right:8px;width:72px;height:auto;object-fit:contain;pointer-events:none;}
}

/* Thumbnails scroll as a single-row carousel instead of wrapping to a second row — keeps
   the gallery column's height from ballooning past the decision panel beside it once the
   video / Get It Installed row is added below. Sized so exactly 4 fit per view, matching
   the old 4-column grid look when there are <=4 images; 5+ scroll. */
.gallery-thumbs-wrap{position:relative;}
.gallery-thumbs{display:flex;gap:8px;margin-top:10px;overflow-x:auto;scroll-snap-type:x proximity;scrollbar-width:thin;-webkit-overflow-scrolling:touch;}
.gallery-thumbs img{flex:0 0 calc((100% - 24px)/4);width:calc((100% - 24px)/4);aspect-ratio:1/1;object-fit:cover;border-radius:8px;border:1px solid var(--rrg-line);cursor:pointer;scroll-snap-align:start;}
.gallery-thumbs img.active{border-color:var(--rrg-red);border-width:2px;}
.thumb-nav{display:none;position:absolute;top:50%;transform:translateY(-50%);width:30px;height:30px;border-radius:50%;background:#fff;border:1px solid var(--rrg-line);box-shadow:0 2px 6px rgba(0,0,0,.15);align-items:center;justify-content:center;color:var(--rrg-black);padding:0;z-index:2;}
.thumb-nav svg{width:16px;height:16px;}
.thumb-nav.prev{left:-4px;}
.thumb-nav.next{right:-4px;}
.thumb-nav:disabled{opacity:.3;cursor:default;}
.gallery-thumbs-wrap.has-overflow .thumb-nav{display:flex;}
@media (max-width:640px){
  .thumb-nav{display:none!important;} /* touch swipe carries the interaction on mobile */
}

/* Product video — appears under the gallery, paired with the Get It Installed CTA where
   both exist. Prototype stage doesn't embed real video playback anywhere; .video-placeholder
   is a static thumbnail image (video-thumbnail.png) standing in on every product so the
   layout can be previewed/reviewed, not a real per-product video. Shown/hidden purely by
   the demo admin panel's "Product has video" toggle. */
.video-placeholder{display:block;width:100%;border-radius:var(--radius);overflow:hidden;aspect-ratio:16/9;object-fit:cover;}

/* Get It Installed — full-bleed installer photo with real trust points overlaid on a dark
   scrim, and a subdued outline CTA (redesigned 2026-09-11, spec.md item 16; refined twice
   same day after Brenton's review). .install-cta-panel's own aspect-ratio controls the
   card's height — locked to 16/9 when paired with the video so the two stay exactly the
   same height side by side. Deliberately not styled as a second prominent CTA: the button
   uses .btn-outline (site's existing subdued secondary style, reads fine in white over the
   dark scrim), not red or gold, so it never competes with the one purchase CTA in the
   decision panel (confirmed with Brenton — red still pulls the eye even though it isn't the
   Add to Cart colour). .install-media-row pairs it with the product video, side by side,
   under the gallery images. The .no-video modifier (toggled by the demo admin panel, or
   present by default on products with no video at all) drops it to a single full-width
   column instead, with larger text/icon sizing since there's more room and no video height
   to match.
   Second refinement (same day): installer.png itself has a ~10-25px black border baked
   into the source file (confirmed by sampling pixels via canvas — not a CSS bug, the
   getBoundingClientRect box was always pixel-exact). .install-photo is scaled up 1.16x
   around its own centre to crop that border outside the visible/clipped frame — measured
   against the worst-case border edge (top, ~5.2% of the image height) plus a safety margin,
   confirmed clean via the same pixel-sampling technique after. Also fixed: .install-body
   used to rely on height:100% to fill the card, which only resolves correctly when the
   card's own height is *definite* (true for the paired 16/9 state, but not for .no-video's
   min-height-only box) — it silently collapsed to its own content height instead, leaving
   the .no-video card's text stuck at the top instead of vertically centred. Switched to
   position:absolute;inset:0 (same reliable stretch technique .install-photo already used)
   so centring now works in both states regardless of how the card's height is established. */
.install-media-row{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:12px;align-items:start;}
.install-media-row.no-video{grid-template-columns:1fr;}
.install-media-row.no-video .video-placeholder{display:none!important;}
.install-cta-panel{position:relative;border-radius:var(--radius);overflow:hidden;aspect-ratio:16/9;background:#111;}
.install-photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:85% 35%;transform:scale(1.16);}
.install-body{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;gap:8px;padding:16px 18px;background:linear-gradient(90deg, rgba(0,0,0,.82) 0%, rgba(0,0,0,.55) 48%, rgba(0,0,0,.05) 100%);}
.install-head{display:flex;align-items:center;gap:8px;}
.install-badge{width:24px;height:24px;flex:0 0 auto;border-radius:6px;background:var(--rrg-red);color:#fff;display:flex;align-items:center;justify-content:center;}
.install-badge svg{width:13px;height:13px;}
.install-cta-panel h3{font-size:16px;margin:0;color:#fff;}
.install-usps{display:flex;flex-direction:column;gap:4px;}
.install-usps .usp-item{gap:6px;}
.install-usps .usp-icon{width:13px;height:13px;flex:0 0 13px;color:#fff;}
.install-usps .usp-item p{margin:0;font-size:12px;line-height:1.3;color:#eee;}
.install-cta-panel .btn{align-self:flex-start;padding:10px 18px;font-size:12.5px;line-height:1.2;}
.install-media-row.no-video .install-cta-panel{aspect-ratio:auto;min-height:230px;}
.install-media-row.no-video .install-body{max-width:460px;padding:22px 26px;gap:12px;}
.install-media-row.no-video .install-head{gap:12px;}
.install-media-row.no-video .install-badge{width:32px;height:32px;}
.install-media-row.no-video .install-badge svg{width:17px;height:17px;}
.install-media-row.no-video .install-cta-panel h3{font-size:21px;}
.install-media-row.no-video .install-usps{gap:8px;}
.install-media-row.no-video .install-usps .usp-item{gap:10px;}
.install-media-row.no-video .install-usps .usp-icon{width:17px;height:17px;flex:0 0 17px;}
.install-media-row.no-video .install-usps .usp-item p{font-size:14.5px;}
.install-media-row.no-video .install-cta-panel .btn{padding:13px 24px;font-size:14px;}
@media (max-width:900px){
  .install-media-row{grid-template-columns:1fr;}
  .install-cta-panel{aspect-ratio:16/9;}
}

/* Standalone product-video slot for templates with no Get It Installed panel (Simple,
   Sibling-color) — shown/hidden purely by the demo admin panel's "has video" toggle. */
[data-admin-video]{margin-top:10px;}

/* Fitted Photos Gallery — "Gallery" panel widget (2026-09-10, matched to a live-site
   Figma reference; final design locked in 2026-09-12, spec.md Section 12 item 5: full
   width above the Trust Row, non-red, permanently — the placement/red-background Demo
   State Panel toggles that previously existed to help decide this have been removed).
   Vehicle-specific only. Colours still run through --fg-* custom properties rather than
   being inlined directly, in case a future design pass needs to vary them again. */
.fit-gallery-panel{
  --fg-bg:#fff; --fg-fg:var(--rrg-black); --fg-link:var(--rrg-red);
  --fg-btn-bg:var(--rrg-black); --fg-btn-fg:#fff;
  --fg-dot:rgba(0,0,0,.18); --fg-dot-active:var(--rrg-black);
  --fg-nav-bg:rgba(255,255,255,.9); --fg-nav-fg:var(--rrg-black); --fg-nav-border:var(--rrg-line);
  background:var(--fg-bg);color:var(--fg-fg);border:1px solid var(--rrg-line);border-radius:var(--radius);padding:22px 24px 24px;
}
.fit-gallery-head{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:16px;}
.fit-gallery-title{display:flex;align-items:center;gap:10px;}
.fit-gallery-badge{width:26px;height:26px;flex:0 0 auto;border-radius:6px;background:var(--rrg-gold);color:#fff;display:flex;align-items:center;justify-content:center;}
.fit-gallery-badge svg{width:15px;height:15px;}
.fit-gallery-title h2{margin:0;line-height:1;color:var(--fg-fg);}
.fit-gallery-viewall{margin-left:auto;color:var(--fg-link);font-weight:700;font-size:13px;text-decoration:underline;white-space:nowrap;}
.fit-gallery-carousel{position:relative;}
.fit-gallery-track{display:flex;gap:10px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;-webkit-overflow-scrolling:touch;}
.fit-gallery-track::-webkit-scrollbar{display:none;}
.fit-gallery-track img{flex:0 0 calc((100% - 60px)/7);aspect-ratio:16/9;object-fit:cover;border-radius:10px;background:#eee;scroll-snap-align:start;cursor:pointer;transition:opacity .15s ease;}
.fit-gallery-track img:hover{opacity:.8;}
.fit-gallery-nav{display:none;position:absolute;top:50%;transform:translateY(-50%);width:32px;height:32px;border-radius:50%;background:var(--fg-nav-bg);color:var(--fg-nav-fg);border:1px solid var(--fg-nav-border);align-items:center;justify-content:center;font-size:18px;line-height:1;cursor:pointer;z-index:2;}
.fit-gallery-nav:disabled{opacity:.3;cursor:default;}
.fit-gallery-nav.prev{left:-4px;}
.fit-gallery-nav.next{right:-4px;}
.fit-gallery-carousel.has-overflow .fit-gallery-nav{display:flex;}
@media (max-width:640px){
  .fit-gallery-nav{display:none!important;} /* touch swipe carries the interaction on mobile */
}
.fit-gallery-dots{display:flex;align-items:center;justify-content:center;gap:6px;margin-top:14px;}
.fit-gallery-dot{width:7px;height:7px;padding:0;border:none;border-radius:999px;background:var(--fg-dot);cursor:pointer;}
.fit-gallery-dot.active{width:20px;background:var(--fg-dot-active);}

/* Demo state panel (reviewer-only, not part of the shipped design) — a floating button
   that expands into a panel for toggling simulated product states (video, sale, stock,
   shipping/click&collect availability) and, on vehicle-specific, the session vehicle used
   for fitment. Replaces the old fixed top "REVIEWER DEMO" bar. */
.admin-fab{position:fixed;right:20px;bottom:20px;z-index:60;display:flex;align-items:center;gap:8px;background:var(--rrg-black);color:#fff;border:none;border-radius:999px;padding:13px 18px 13px 14px;font-weight:900;font-size:12.5px;text-transform:uppercase;letter-spacing:.03em;box-shadow:0 8px 20px rgba(0,0,0,.25);cursor:pointer;}
.admin-fab svg{width:18px;height:18px;flex:0 0 auto;}
.admin-panel{position:fixed;right:20px;bottom:20px;z-index:61;width:300px;max-width:calc(100vw - 40px);max-height:calc(100vh - 40px);background:#fff;border-radius:14px;box-shadow:0 16px 40px rgba(0,0,0,.28);display:flex;flex-direction:column;overflow:hidden;transform:translateY(12px) scale(.98);opacity:0;pointer-events:none;transition:transform .15s ease, opacity .15s ease;}
.admin-panel.open{transform:translateY(0) scale(1);opacity:1;pointer-events:auto;}
.admin-panel-head{display:flex;align-items:center;justify-content:space-between;background:var(--rrg-black);color:#fff;padding:14px 16px;font-family:'Barlow Condensed',sans-serif;font-weight:700;font-size:15px;text-transform:uppercase;letter-spacing:.02em;}
.admin-panel-head button{background:none;border:none;color:#fff;font-size:18px;line-height:1;padding:2px;opacity:.7;}
.admin-panel-head button:hover{opacity:1;}
.admin-panel-body{padding:16px;overflow-y:auto;}
.admin-section{margin-bottom:18px;}
.admin-section:last-child{margin-bottom:0;}
.admin-section h5{font-size:11.5px;color:#767676;text-transform:uppercase;letter-spacing:.04em;margin:0 0 10px;font-family:'Barlow Condensed',sans-serif;font-weight:700;}
.admin-vehicle-row{display:flex;flex-direction:column;gap:6px;}
.admin-vehicle-row button{background:#f2f2f2;border:1px solid var(--rrg-line);border-radius:8px;padding:9px 12px;font-size:12.5px;font-weight:700;text-align:left;color:var(--rrg-black);}
.admin-vehicle-row button.active{background:var(--rrg-red);border-color:var(--rrg-red);color:#fff;}
.admin-toggle-label{padding:9px 0 0;font-size:13px;color:#232323;}
.admin-toggle{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 0;font-size:13px;color:#232323;border-bottom:1px solid #f0f0f0;cursor:pointer;}
.admin-toggle:last-child{border-bottom:none;}
.admin-toggle input{appearance:none;-webkit-appearance:none;width:36px;height:21px;border-radius:999px;background:#d8d8d8;position:relative;flex:0 0 auto;cursor:pointer;transition:background .15s ease;}
.admin-toggle input::after{content:'';position:absolute;top:2px;left:2px;width:17px;height:17px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.3);transition:left .15s ease;}
.admin-toggle input:checked{background:var(--rrg-fits);}
.admin-toggle input:checked::after{left:17px;}
@media (max-width:640px){
  /* FAB hidden on mobile (2026-09-11, Brenton's ask) — it's reviewer-only tooling that
     was crowding an already tight mobile viewport. Opens instead via the "North Lakes"
     nearest-store link in the utility bar (data-admin-trigger, wired in buildAdminPanel())
     — the panel itself stays fully functional, just without a dedicated floating button
     on small screens. .admin-panel keeps its bottom offset for when it's open. */
  .admin-fab{display:none;}
  .admin-panel{bottom:84px;}
}

/* Out-of-stock banner, inserted above the Add to Cart column by the demo admin panel */
.stock-banner{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:700;color:var(--rrg-nofit);background:var(--rrg-nofit-bg);border:1px solid var(--rrg-nofit);border-radius:8px;padding:10px 12px;margin-bottom:10px;}

/* Shown in place of the Delivery/Click & Collect widget when the demo admin panel has
   both availability toggles switched off */
.dc-unavailable-note{font-size:12.5px;color:#767676;padding:12px 14px;border:1px dashed var(--rrg-line);border-radius:8px;}

/* Special order banner — sits above Add to Cart, demo admin panel "Special order" toggle */
/* Text recoloured black (2026-09-11, legibility fix) — box stays amber-tinted
   (background/border), only the yellow/orange text itself was hard to read. */
.special-order-banner{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:700;color:#000;background:var(--rrg-unknown-bg);border:1px solid var(--rrg-unknown);border-radius:8px;padding:10px 12px;margin-bottom:10px;}

/* Compatibility banner — sits above Add to Cart, demo admin panel "Cart contents"
   toggle (backlog item 24, 2026-09-11 backlog). Same amber informational tier as
   .special-order-banner (never blocks purchase), not the red "not in stock" tier.
   Deliberately NOT display:flex (2026-09-12 fix) — this banner's content is a text
   run with an embedded <strong>, and flex turns each text/element chunk into its own
   anonymous flex item/column instead of one wrapping paragraph, which read as broken
   multi-column text. Plain block flow wraps it correctly as a single paragraph. */
.cart-conflict-banner{font-size:13px;font-weight:700;color:#000;background:var(--rrg-unknown-bg);border:1px solid var(--rrg-unknown);border-radius:8px;padding:10px 12px;margin-bottom:10px;line-height:1.4;}

/* Discontinued banner — sits above Add to Cart in place of the button/payment-badges
   (which are hidden via .cta-col[hidden] while this state is active), demo admin panel
   "Discontinued" stock-status option, backlog item 23, 2026-09-11. */
.discontinued-banner{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:700;color:#000;background:var(--rrg-nofit-bg);border:1px solid var(--rrg-nofit);border-radius:8px;padding:10px 12px;margin-bottom:10px;}

/* Brand logo — required on every product page, sits at the top of the decision panel.
   Fixed height/auto width made MAXTRAX (and Front Runner, same source aspect ratio)
   render ~40% narrower than Rhino Rack/Yakima, since MAXTRAX's source file is a more
   square canvas (148x39, ~3.8:1) than the others (~6.3:1) — a fixed height treats a
   naturally squatter logo as "smaller" even though the artwork itself isn't (2026-09-10,
   Graham Sowerby meeting). Sized against a bounding box instead (max-width + max-height,
   width/height auto) so every brand fills a similar visual footprint regardless of its
   own aspect ratio, without needing better-proportioned source assets. */
.brand-logo{max-width:160px;max-height:32px;width:auto;height:auto;object-fit:contain;display:block;margin-bottom:12px;}
/* Text fallback for brands with no supplied logo file yet (see grouped-bundle template,
   which introduces Yakima — no real logo asset on hand, unlike the other three brands). */
.brand-logo-text{height:26px;line-height:26px;font-family:Arial,Helvetica,sans-serif;font-weight:900;font-size:19px;letter-spacing:.01em;color:#111;text-transform:uppercase;margin-bottom:12px;}

/* Sale tag — absolutely positioned against .price-block (not just .price-row), vertically
   centered against the whole block (price row + stock-status line beneath it), not just
   the price row's own line — matches the same corner-badge pattern as .rack-fit-badge.
   Shown/hidden by the same "on sale" admin flag as the price — syncSaleTag() in shared.js
   toggles every .sale-tag on the page together (this one plus .gallery-sale-tag below),
   not scoped to a single .decision-panel, since a page only ever has one product/one sale
   state to reflect regardless of how many tag instances currently show. */
.price-block{position:relative;}
.price-block .sale-tag{position:absolute;top:50%;right:0;transform:translateY(-50%);width:86px;height:auto;pointer-events:none;}
/* Mobile (2026-09-12 follow-up, Brenton's ask): the pricing widget (both price lines +
   the stock-status line) centers as a unit instead of staying left-aligned. Each is a flex
   row that already shrink-wraps to its own content width, so align-items:center on the
   now-flex-column .price-block centers each one as a whole block with no per-line change
   needed. **Second follow-up, same day:** repositioning the Sale Tag to the price block's
   own top-right corner (the first mobile fix) still read as "weird" per Brenton's review —
   pinning a corner ribbon to a box that's centering its own content already looked
   mismatched, and a wide price could still crowd it. Simpler fix: don't show it near the
   price at all on mobile — hide it here entirely and show a second instance over the main
   product image instead (.gallery-sale-tag below), which is where a "Sale" ribbon
   conventionally belongs anyway. */
@media (max-width:900px){
  .price-block{display:flex;flex-direction:column;align-items:center;}
  .price-block .sale-tag{display:none;}
}

/* Package contents (vehicle-specific kits) — each included item with its own SKU + copy
   button, so instore staff can copy individual part numbers without hunting through specs */
.package-items{margin:16px 0;border:1px solid var(--rrg-line);border-radius:10px;overflow:hidden;}
.package-items h3{font-size:12px;text-transform:uppercase;letter-spacing:.04em;color:#767676;padding:10px 12px;margin:0;background:#f7f7f7;border-bottom:1px solid var(--rrg-line);font-family:'Barlow Condensed',sans-serif;font-weight:700;}
.package-item{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 12px;font-size:12.5px;border-top:1px solid var(--rrg-line);}
.package-item:first-of-type{border-top:none;}
.package-item .pi-name{flex:1;color:#333;text-decoration:none;}
.package-item .pi-name:hover{text-decoration:underline;}
/* Tab-panel sub-headings (Details/Gold Guarantee/Shipping Info content) were plain <h5>
   with no rule of their own, relying entirely on the browser's UA-default h5 styling
   (not the shared h1-h4 Barlow Condensed/uppercase rule above). Promoted to <h3> for a
   correct heading outline (spec.md backlog item 12-6) — this reproduces that exact
   UA-default look (relative sizing/margin, not the shared heading treatment) so nothing
   visually changes. */
.details-sub h3{font-family:'Lato',Arial,Helvetica,sans-serif;font-weight:700;font-size:.83em;text-transform:none;letter-spacing:normal;margin:1.67em 0;color:inherit;}
/* Quantity per row (2026-09-10, Graham Sowerby meeting) — so a customer adding what looks
   like one product isn't confused when a multi-part kit arrives with no visible reason
   why. Real per-component quantities aren't confirmed by the client yet — see spec.md §7. */
.package-item .pi-qty{flex:0 0 auto;color:#999;font-size:12px;font-weight:700;white-space:nowrap;}
.package-item .pi-sku{display:flex;align-items:center;gap:6px;color:#767676;white-space:nowrap;}

/* Generic copy-to-clipboard button, used by the main SKU row and package-item rows */
/* SKU click-to-copy (2026-09-10, Graham Sowerby meeting) — the SKU text itself is the
   click target now, not a separate copy-icon button (main SKU row + What's Included
   rows). Dashed underline in the current text colour signals "clickable" without adding
   a second visual element next to a value that used to look purely static. */
/* Padding + negative margin (2026-09-11, mobile audit) so the click/tap area is bigger
   than the visible underlined text without shifting surrounding layout — a full 48px
   box here would look like an odd gap in an inline text row, so this is a deliberate
   partial improvement (~34px tap height), not a full 48px compliance claim. */
.sku-copy{cursor:pointer;border-bottom:1px dashed currentColor;display:inline-block;padding:8px 2px;margin:-8px -2px;}
.sku-copy.copied{color:var(--rrg-fits);border-bottom-color:var(--rrg-fits);}

/* Ex-Demo / Factory Seconds — demo admin panel "B-Stock" toggle. Appended inline to the
   stock-status line itself (e.g. "In Stock — Ex-Demo/Factory Seconds from $1,495"), not a
   separate button (Graham Sowerby meeting, 2026-09-10 — a standalone button risked being
   missed; this needed to read as part of the existing stock line). Click opens the same
   ex-demo slide-in drawer as before. UK region shows "Graded" instead of "Ex-Demo/Factory
   Seconds" for this umbrella term (see exdemoTermLabel() in shared.js) — AU/NZ unaffected. */
.exdemo-inline-link{color:#1A56DB;font-weight:700;text-decoration:underline;}
.exdemo-inline-link:hover{color:#123f9e;}

/* Paid "Fitted" option — demo-preview only (2026-09-10 client meeting), not wired to
   real cart/checkout. Mode 1 injects this as a third card into .variant-picker (higher
   specificity than each page's own .variant-option rule, so it overrides regardless of
   stylesheet load order); Mode 2 uses the plain upsell-checkbox styling below instead. */
.variant-option.fitted-option{grid-column:1/-1;background:var(--rrg-gold-bg);border-color:var(--rrg-gold);}
.variant-option.fitted-option.selected{border-color:var(--rrg-gold);box-shadow:0 0 0 1px var(--rrg-gold);}
.fitted-upsell-checkbox{display:flex;align-items:flex-start;gap:10px;background:var(--rrg-gold-bg);border:1px solid var(--rrg-gold);border-radius:8px;padding:10px 12px;font-size:12.5px;color:#5c4d34;cursor:pointer;margin-bottom:2px;}
.fitted-upsell-checkbox input{margin-top:2px;flex:0 0 auto;}
.fitted-upsell-checkbox .fitted-sub{display:block;color:#8a7a5c;font-size:12px;margin-top:2px;}

.admin-section h5 .admin-note{text-transform:none;font-weight:400;color:#aaa;letter-spacing:0;}
.admin-radio-row{display:flex;flex-direction:column;gap:6px;margin:8px 0 0;padding-top:8px;border-top:1px dashed #eee;}
.admin-radio-row label{display:flex;align-items:center;gap:8px;font-size:12.5px;color:#333;cursor:pointer;}

/* Ex-Demo slide-out — right-edge drawer, backlog item 4 (2026-09-11: replaces the previous
   centered modal to match the Store Slide-out pattern below). Structurally identical to
   .store-slideout* — same backdrop/drawer/transition/close-button rules, just its own
   class family since the two drawers are independent (only one open at a time in practice,
   but nothing enforces that). */
.exdemo-slideout-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:75;opacity:0;pointer-events:none;transition:opacity .2s ease;}
.exdemo-slideout-backdrop.open{opacity:1;pointer-events:auto;}
.exdemo-slideout{position:fixed;top:0;right:0;bottom:0;width:380px;max-width:90vw;background:#fff;box-shadow:-16px 0 40px rgba(0,0,0,.25);transform:translateX(100%);transition:transform .25s ease;display:flex;flex-direction:column;}
.exdemo-slideout-backdrop.open .exdemo-slideout{transform:translateX(0);}
.exdemo-slideout-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:20px 22px;border-bottom:1px solid var(--rrg-line);flex:0 0 auto;}
.exdemo-slideout-head h2{font-size:19px;margin:0 0 4px;}
.exdemo-slideout-head p{font-size:12.5px;color:#666;margin:0;}
.exdemo-slideout-close{background:#f2f2f2;border:none;border-radius:50%;width:48px;height:48px;font-size:16px;flex:0 0 auto;color:#333;}
.exdemo-slideout-body{padding:16px 22px 22px;overflow-y:auto;display:flex;flex-direction:column;gap:12px;flex:1 1 auto;}
.exdemo-option{border:1px solid var(--rrg-line);border-radius:10px;padding:14px 16px;display:flex;align-items:center;gap:14px;}
.exdemo-option .eo-img{width:64px;height:64px;object-fit:contain;background:#f7f7f7;border-radius:8px;padding:6px;flex:0 0 auto;}
.exdemo-option .eo-info{flex:1;min-width:0;}
/* Sizing kept identical to .stock-chip (padding/font-size/weight) — same status-pill family,
   per Brenton's 2026-09-12 ask to unify every status pill on the page to one look. */
.exdemo-option .eo-tag{display:inline-block;white-space:nowrap;font-size:11px;font-weight:900;text-transform:uppercase;letter-spacing:.03em;padding:2px 8px;border-radius:6px;background:var(--rrg-unknown-bg);color:#333;margin-bottom:6px;}
.exdemo-option .eo-price{font-family:'Barlow Condensed',sans-serif;font-weight:700;font-size:22px;}
.exdemo-option .eo-was{font-size:12px;color:#8a8a8a;text-decoration:line-through;margin-left:6px;}
.exdemo-option .eo-note{font-size:12px;color:#666;margin-top:2px;}
.exdemo-option .btn{padding:10px 16px;font-size:12px;flex:0 0 auto;}
@media (max-width:520px){
  .exdemo-option{flex-wrap:wrap;}
  .exdemo-option .btn{flex:1 0 100%;}
}

/* Delivery / Click & Collect widget — full-width, two tabs. Reworked 2026-09-10 (Graham
   Sowerby meeting): single postcode field shared across both tabs (.dc-postcode-row, sits
   between the tab bar and whichever .dc-panel is active) instead of one per panel, results
   visible by default instead of gated behind a click (see initDcPostcode() in shared.js),
   default active tab flipped to Click & Collect, and small tab icons. */
.dc-widget{border:1px solid var(--rrg-line);border-radius:var(--radius);overflow:hidden;background:#fff;}
.dc-tabs{display:flex;border-bottom:1px solid var(--rrg-line);}
.dc-tab{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:5px;min-height:48px;background:#f7f7f7;border:none;padding:11px 14px;font-family:'Barlow Condensed',sans-serif;font-weight:700;font-size:13px;text-transform:uppercase;letter-spacing:.02em;color:#767676;border-bottom:2px solid transparent;}
.dc-tab.active{background:#fff;color:var(--rrg-black);border-bottom-color:var(--rrg-red);}
.dc-tab-icon{width:14px;height:14px;flex:0 0 auto;}
.dc-postcode-row{display:flex;gap:10px;flex-wrap:wrap;padding:16px 18px 0;}
.dc-panel{padding:12px 18px 16px;}
.dc-row{display:flex;gap:10px;flex-wrap:wrap;}
.dc-input{flex:1 1 220px;border:1px solid var(--rrg-line);border-radius:8px;padding:12px 14px;font-size:14px;font-family:inherit;}
.dc-results{margin-top:16px;display:flex;flex-direction:column;gap:10px;}
.dc-option,.dc-store{display:flex;align-items:center;justify-content:space-between;gap:12px;border:1px solid var(--rrg-line);border-radius:8px;padding:12px 14px;font-size:13.5px;}
.dc-price{font-family:'Barlow Condensed',sans-serif;font-weight:700;font-size:18px;}
.muted{color:#767676;font-size:12.5px;}
.stock-chip{display:inline-block;white-space:nowrap;font-size:11px;font-weight:900;text-transform:uppercase;padding:2px 8px;border-radius:6px;margin-left:6px;color:#333;}
.stock-chip.in{background:var(--rrg-fits-bg);}
.stock-chip.order{background:var(--rrg-unknown-bg);}
.stock-chip.none{background:var(--rrg-nofit-bg);}

/* Delivery / Click & Collect widget v2 — Demo State Panel preview (backlog items 18/19,
   2026-09-12, dcV2*() in shared.js). Explicit postcode "Check" instead of live-as-you-type:
   .dc-shared (prompt + input row + error banner) sits above the two .dc-panel elements and
   is hidden once a postcode is committed, replaced by that tab's own results-head + body. */
.dc-prompt{padding:14px 18px 0;margin:0 0 8px;font-size:13.5px;color:#333;}
.dc-shared .dc-postcode-row{padding-top:0;}
.dc-error-banner{margin:10px 18px 0;padding:10px 14px;border-radius:8px;background:var(--rrg-nofit-bg);color:var(--rrg-nofit);font-size:13px;line-height:1.4;}
.dc-input.error{border-color:var(--rrg-nofit);}
.dc-results-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:10px;}
.dc-results-head h3{margin:0;font-family:'Barlow Condensed',sans-serif;font-weight:700;font-size:18px;text-transform:none;}
.dc-change-link{font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.03em;color:var(--rrg-red);text-decoration:underline;white-space:nowrap;flex:0 0 auto;}
.dc-select-list{display:flex;flex-direction:column;gap:10px;}
.dc-select-option{display:flex;align-items:center;gap:12px;border:1.5px solid var(--rrg-line);border-radius:8px;padding:12px 14px;font-size:13.5px;cursor:pointer;transition:border-color .15s,box-shadow .15s;}
.dc-select-option:hover{border-color:#b8b8b8;}
.dc-select-option:has(input:checked){border-color:var(--rrg-red);box-shadow:0 0 0 1px var(--rrg-red);}
.dc-select-option input[type=radio]{accent-color:var(--rrg-red);width:18px;height:18px;flex:0 0 auto;}
.dc-select-option .dc-select-body{flex:1 1 auto;min-width:0;}
.dc-select-option .dc-price{font-family:'Barlow Condensed',sans-serif;font-weight:700;font-size:18px;flex:0 0 auto;}
.dc-v2-copy{font-size:13.5px;color:#444;line-height:1.5;margin:0 0 14px;}
.dc-v2-actions{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:14px;}
.dc-quote-form{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:14px;}
.dc-quote-form .dc-input{flex:1 1 220px;}
.dc-v2-confirm{font-size:13.5px;color:var(--rrg-fits);font-weight:700;margin:0 0 14px;}

/* "View all stores" — opens the store slide-out drawer, see .store-slideout below and
   buildStoreSlideout() in shared.js. Click & Collect panel and, where present, the Showroom
   Finder widget. The line's leading text swaps between "no postcode entered" and "postcode
   entered" copy — see initDcPostcode() in shared.js. */
.dc-viewall-row{margin-top:10px;font-size:12px;color:#767676;}
.dc-viewall{color:#1A56DB;font-weight:700;text-decoration:underline;cursor:pointer;}
.dc-viewall:hover{color:#123f9e;}

/* Delivery panel's placeholder before a postcode is entered — mirrors the Collect panel
   gating results the same way (2026-09-10, second follow-up: Delivery was left showing
   flat rates regardless of postcode, same bug already fixed on Collect). */
.dc-postcode-prompt{font-size:13.5px;color:#767676;padding:4px 0;}

/* Store slide-out — right-edge drawer, "View all stores" from the Click & Collect and
   Showroom Finder widgets. Real store network (RRG_STORE_NETWORK in shared.js), grouped by
   state to match the live site's own Store Inventory slide-out. Reuses .dc-store/.stock-chip
   row styling for visual consistency with the inline results, same right-edge slide-in
   drawer convention as .exdemo-slideout* above (independent instance). */
.store-slideout-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:75;opacity:0;pointer-events:none;transition:opacity .2s ease;}
.store-slideout-backdrop.open{opacity:1;pointer-events:auto;}
.store-slideout{position:fixed;top:0;right:0;bottom:0;width:380px;max-width:90vw;background:#fff;box-shadow:-16px 0 40px rgba(0,0,0,.25);transform:translateX(100%);transition:transform .25s ease;display:flex;flex-direction:column;}
.store-slideout-backdrop.open .store-slideout{transform:translateX(0);}
.store-slideout-head{display:flex;align-items:center;justify-content:space-between;padding:20px 22px;border-bottom:1px solid var(--rrg-line);flex:0 0 auto;}
.store-slideout-head h2{font-size:19px;margin:0;}
.store-slideout-close{background:#f2f2f2;border:none;border-radius:50%;width:48px;height:48px;font-size:16px;color:#333;flex:0 0 auto;}
.store-slideout-body{padding:16px 22px 22px;overflow-y:auto;display:flex;flex-direction:column;gap:6px;flex:1 1 auto;}
/* Groups (2026-09-11, backlog item 14): native <details>/<summary>, same no-JS accordion
   convention as .faq-item below — "Within 100km" (when a postcode resolves to a state, see
   renderStoreSlideoutBody()/postcodeToState() in shared.js) starts open, every state group
   starts collapsed alongside it so the nearby stores are what a shopper sees first. */
.store-slideout-group{border-bottom:1px solid var(--rrg-line);padding-bottom:6px;}
.store-slideout-group:last-child{border-bottom:none;padding-bottom:0;}
.store-slideout-state{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:8px;font-family:'Barlow Condensed',sans-serif;font-size:13px;text-transform:uppercase;letter-spacing:.03em;color:var(--rrg-red);padding:10px 2px;}
.store-slideout-state::-webkit-details-marker{display:none;}
.store-slideout-state::after{content:'+';font-size:16px;color:#767676;flex:0 0 auto;}
.store-slideout-group[open] .store-slideout-state::after{content:'\2212';}
.store-slideout-group-stores{display:flex;flex-direction:column;gap:10px;padding:0 0 10px;}
/* Padding + negative margin (2026-09-11, mobile audit), same partial-tap-target
   convention as .sku-copy above — these are real conversion actions (call a store, open
   its map) that were plain 12px inline text with no hit-area padding at all. */
.dc-store .store-phone,.dc-store .store-map-link{display:inline-block;font-size:12px;font-weight:700;text-decoration:underline;padding:8px 0;margin:-8px 12px -8px 0;}
.dc-store .store-phone{color:var(--rrg-black);}
.dc-store .store-map-link{color:#1A56DB;}

/* Fitted Photos Gallery slide-out — right-edge drawer, "View All In-store Fitments" from
   the Fitted Photos Gallery panel (vehicle-specific only). Same backdrop/drawer/transition
   convention as .store-slideout / .exdemo-slideout above (independent instance), but wider
   since it holds a photo grid rather than a text list. */
.fit-gallery-slideout-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:75;opacity:0;pointer-events:none;transition:opacity .2s ease;}
.fit-gallery-slideout-backdrop.open{opacity:1;pointer-events:auto;}
.fit-gallery-slideout{position:fixed;top:0;right:0;bottom:0;width:600px;max-width:90vw;background:#fff;box-shadow:-16px 0 40px rgba(0,0,0,.25);transform:translateX(100%);transition:transform .25s ease;display:flex;flex-direction:column;}
.fit-gallery-slideout-backdrop.open .fit-gallery-slideout{transform:translateX(0);}
.fit-gallery-slideout-head{display:flex;align-items:center;justify-content:space-between;padding:20px 22px;border-bottom:1px solid var(--rrg-line);flex:0 0 auto;}
.fit-gallery-slideout-head h2{font-size:19px;margin:0;}
.fit-gallery-slideout-close{background:#f2f2f2;border:none;border-radius:50%;width:48px;height:48px;font-size:16px;color:#333;flex:0 0 auto;}
.fit-gallery-slideout-body{padding:16px 22px 22px;overflow-y:auto;flex:1 1 auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:10px;align-content:start;}
.fit-gallery-slideout-body img{width:100%;aspect-ratio:16/9;object-fit:cover;border-radius:10px;background:#eee;}
.fit-gallery-slideout-body img[data-fgs-open-index]{cursor:pointer;transition:opacity .15s ease;}
.fit-gallery-slideout-body img[data-fgs-open-index]:hover{opacity:.8;}

/* "Back to Grid View" link — swaps into the slide-out head in place of the title (both
   toggled via [hidden]) once a fitment detail is open, see renderFitGallerySlideoutDetail()/
   renderFitGallerySlideoutGrid() in shared.js. */
.fgs-back-link{display:flex;align-items:center;gap:8px;background:none;border:none;color:var(--rrg-red);font-weight:700;font-size:14px;cursor:pointer;padding:0;}
.fgs-back-link svg{width:15px;height:15px;flex:0 0 auto;}

/* Fitment detail view — one photo's "Browse Fitment" popup, matching the live site's own
   reference. Body switches to a simple flex column (overriding the grid display above via
   the extra .fgs-detail-body class) since it's a single-column detail layout, not a grid. */
.fgs-detail-body{display:flex;flex-direction:column;gap:16px;}
.fgs-browse-bar{display:flex;align-items:center;justify-content:space-between;background:#f4f4f4;border-radius:8px;padding:10px 14px;font-size:13px;color:#555;}
.fgs-browse-bar strong{color:var(--rrg-black);}
.fgs-fit-id{font-weight:700;color:var(--rrg-black);}
.fgs-nav-row{display:flex;gap:10px;}
.fgs-nav-row .btn{flex:1 1 0;padding:10px;font-size:13px;}
.fgs-nav-row .btn:disabled{opacity:.35;cursor:default;}
.fgs-main-image img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:10px;background:#eee;}
.fgs-thumbs{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;}
.fgs-thumbs img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:8px;background:#eee;}
.fgs-product-title{margin:0;font-size:17px;line-height:1.3;}
.fgs-vehicle-line{display:flex;align-items:center;gap:8px;color:#555;font-size:13.5px;}
.fgs-vehicle-line svg{width:16px;height:16px;flex:0 0 auto;color:#888;}
.fgs-components{border-top:1px solid var(--rrg-line);padding-top:12px;}
.fgs-components h4{margin:0 0 8px;font-size:12px;text-transform:uppercase;letter-spacing:.04em;color:#767676;}
.fgs-component-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:8px 0;border-bottom:1px solid #f0f0f0;font-size:13.5px;}
.fgs-component-row:last-child{border-bottom:none;}
.fgs-c-qty{background:var(--rrg-black);color:#fff;border-radius:999px;padding:2px 9px;font-size:11px;font-weight:700;flex:0 0 auto;}
.fgs-note{font-size:12px;color:#888;line-height:1.5;margin:0;}
.fgs-back-to-product{width:100%;}

/* Brief highlight when "Back to Product" returns focus to the Decision Panel, so the jump
   reads as intentional rather than a silent scroll. Timed to match the setTimeout in
   closeFitGallerySlideoutAndReturn() (shared.js). */
.decision-panel.fgs-highlight{outline:2px solid var(--rrg-gold);outline-offset:4px;transition:outline-color .3s ease;}

/* Showroom Finder — prominent trust CTA, not a plain widget */
.showroom-widget{background:var(--rrg-black);color:#fff;border-radius:var(--radius);padding:26px 28px;margin-top:20px;}
.showroom-widget h3{color:#fff;margin-bottom:8px;}
.showroom-widget p{color:#ccc;font-size:14px;max-width:640px;}
.showroom-widget .dc-input{background:#fff;}
.showroom-widget .dc-results{margin-top:18px;}
.showroom-widget .dc-store{background:#1c1c1c;border-color:#3a3a3a;color:#fff;}
.showroom-widget .muted{color:#aaa;}
.showroom-widget .stock-chip.display{background:#FFCA48;color:#000;}
.showroom-widget .dc-viewall-row{color:#ccc;margin-top:14px;}
.showroom-widget .dc-viewall{color:#fff;}
.showroom-widget .dc-viewall:hover{color:#e6e6e6;}

/* Experimental interactive map (Vehicle-Specific pilot, 2026-09-10 Graham Sowerby meeting)
   — runs alongside the existing black block (split-view), not as a full swap; corrected
   2026-09-10 after the first version replaced the block outright and lost the postcode
   entry / CTA. .split-view puts #showroomDefaultView and #showroomMap side by side (1:2 —
   text column narrower, map gets the larger two-thirds — client ask, same day follow-up);
   stacks on narrow viewports. The map runs flush to the widget's edges (no padding/black
   border around it, another same-day correction) — padding that used to live on
   .showroom-widget itself moves onto #showroomDefaultView only in split-view, and
   `overflow:hidden` on the widget clips the map's square corners to the widget's own
   rounded ones. `position:relative;z-index:0` on .showroom-map gives Leaflet's internal
   panes/controls (which default to z-index up to 1000) their own local stacking context, so
   they can never render above the fixed Demo State Panel (z-index 60/61) — without this
   they escape onto the whole page since neither Leaflet's container nor this block
   otherwise establishes one. */
.showroom-widget.split-view{display:grid;grid-template-columns:1fr 2fr;align-items:stretch;padding:0;overflow:hidden;min-height:360px;}
.showroom-widget.split-view #showroomDefaultView{margin:0;padding:26px 24px;}
.showroom-widget.split-view .showroom-map{margin:0;height:auto;border-radius:0;}
@media (max-width:900px){
  .showroom-widget.split-view{grid-template-columns:1fr;min-height:0;}
  .showroom-widget.split-view .showroom-map{height:280px;}
}
.showroom-map{margin-top:18px;height:320px;border-radius:10px;overflow:hidden;position:relative;z-index:0;}
.showroom-map .leaflet-container{height:100%;width:100%;font-family:inherit;}

/* Map rework (2026-09-11, backlog item 22) — custom divIcon pins (no image assets) instead
   of Leaflet's default blue marker, and Leaflet.markercluster bubbles restyled to match the
   RRG palette instead of the plugin's default green/yellow/orange. Grey = not on display,
   red = on display (per ON_DISPLAY_STORES) — a cluster renders red the moment any store
   inside it is on display, per rrgClusterIcon() in shared.js, so that signal reads before a
   viewer zooms in. */
.rrg-map-pin span{display:block;width:20px;height:20px;border-radius:50% 50% 50% 0;transform:rotate(-45deg);background:#8a8a8a;border:2px solid #fff;box-shadow:0 1px 4px rgba(0,0,0,.4);}
.rrg-map-pin.on-display span{background:var(--rrg-red);}
.rrg-map-cluster{display:flex;align-items:center;justify-content:center;}
.rrg-map-cluster span{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;background:#8a8a8a;color:#fff;font-weight:800;font-size:13px;border:2px solid #fff;box-shadow:0 1px 4px rgba(0,0,0,.4);}
.rrg-map-cluster.on-display span{background:var(--rrg-red);}

/* Sticky mobile Add-to-Cart bar (2026-09-11 rework, backlog item 26) — visibility is now
   driven by whether the real Add to Cart button is on-screen (initStickyCta() in
   shared.js), not just viewport width. One rule now covers both cases: shows immediately
   on load if Add to Cart starts below the fold, and reappears once the user scrolls past
   it later — previously only the second case worked, since the bar used to be
   unconditionally visible at mobile widths regardless of scroll position. */
.sticky-cta-mobile{display:none;position:fixed;bottom:0;left:0;right:0;background:#fff;border-top:1px solid var(--rrg-line);padding:10px 16px;gap:10px;align-items:center;z-index:40;box-shadow:0 -6px 16px rgba(0,0,0,.08);}
@media (max-width:900px){
  .sticky-cta-mobile.visible{display:flex;}
  body.has-sticky-cta{padding-bottom:74px;}
}

/* Persistent decision bar — appears once the primary decision panel scrolls out of view */
.persistent-bar{position:fixed;top:0;left:0;right:0;background:#fff;border-bottom:1px solid var(--rrg-line);box-shadow:0 4px 14px rgba(0,0,0,.08);z-index:35;transform:translateY(-120%);transition:transform .25s ease;}
.persistent-bar .persistent-inner{display:flex;align-items:center;gap:20px;padding:10px 24px;}
.persistent-bar.visible{transform:translateY(0);}
/* Fitment box now shares the row with .persistent-product instead of taking the whole
   flexible width itself (2026-09-11, backlog item 10) — both flex:1 1 0 so it settles to
   roughly half its old width. */
.persistent-bar .fitment{margin:0;flex:1 1 0;min-width:0;padding:8px 12px;font-size:12px;}
.persistent-bar .fitment strong{font-size:12.5px;}
/* Compact fitment content (icon + short label only, see renderFitmentHTML() in
   shared.js) — centered as a row instead of top-aligned against a taller text block,
   since there's no detail paragraph underneath to align against anymore. */
.persistent-bar .fitment,.sticky-cta-mobile .info.fitment{align-items:center;}
.persistent-bar .fitment strong,.sticky-cta-mobile .info.fitment strong{margin-bottom:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* Condensed price (spec.md Section 12 item 23) — adapted, not the full stacked layout:
   no room for Now/Was labels or the Save badge here, so it's just the same red/dark-grey
   colour language as the Decision Panel applied to the existing single-line price. Applies
   generically to every .price-now/.price-was still using these real classes (Persistent Bar
   on all 5 templates, plus config-variant/sibling-color's #persistentPriceNow/Was) — the
   Sticky Mobile Bar's inline-styled #mobilePrice/static equivalents on config-variant,
   sibling-color, simple and grouped-bundle need their own direct colour edit since inline
   styles don't inherit a class-level change. */
.persistent-bar .price-now{font-size:20px;color:var(--rrg-red);}
.persistent-bar .price-was{font-size:12px;color:#434343;}
.sticky-cta-mobile .price-now{color:var(--rrg-red);}
.sticky-cta-mobile .price-was{color:#434343;}
.persistent-bar .btn{padding:12px 20px;font-size:13px;flex:0 0 auto;}
@media (max-width:900px){.persistent-bar{display:none;}}

/* Product thumbnail + truncated name (2026-09-11, backlog item 10) — gives the sticky
   bars back the "what am I looking at" context lost once the main gallery/title scroll
   out of view. Shared between the desktop persistent bar and the mobile sticky bar. */
.persistent-product{display:flex;align-items:center;gap:10px;flex:1 1 0;min-width:0;}
.persistent-thumb{width:34px;height:34px;object-fit:cover;border-radius:6px;flex:0 0 auto;}
.persistent-name{font-size:13px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
.sticky-cta-mobile .persistent-thumb{width:30px;height:30px;}
.sticky-cta-mobile .persistent-name{font-size:12px;}
/* Icon-only on mobile (see renderFitmentHTML() 'icon-only' mode) needs only its own
   content width, not an even flex:1 split with .persistent-product — that would starve
   the product name of the room it actually needs at this width. */
.sticky-cta-mobile .info.fitment{flex:0 0 auto;}
.sticky-cta-mobile .persistent-product{flex:1 1 auto;}
/* Add to Cart is the one element that must never shrink/wrap here — the product-name
   ellipsis is what absorbs the width squeeze instead. */
.sticky-cta-mobile .btn{flex:0 0 auto;white-space:nowrap;}

/* Related / cross-sell product carousel */
.related-heading{margin-bottom:16px;}

/* Heading above the Tabs widget (2026-09-11) */
.tabs-heading{margin-bottom:16px;}

/* Heading above the Showroom Finder widget (2026-09-11) — sits inside #showroom itself
   (not just .showroom-widget), so it's already hidden/shown by applyShowroomFlag()'s
   existing section.hidden toggle without any extra JS. */
.showroom-heading{margin-bottom:16px;}

/* Section heading style — shared by every top-level section label (Related Products,
   Showroom Finder's "See It In Person...", the Fitment Gallery panel) so they all read as
   one consistent typographic level, per client request 2026-09-10. */
.related-heading,
.showroom-widget h3,
.fit-gallery-title h2,
.faq-heading,
.tabs-heading,
.showroom-heading{
  font-family:'Barlow Condensed',Arial,sans-serif;
  font-weight:700;
  font-style:italic;
  text-transform:uppercase;
  font-size:37px;
  letter-spacing:.01em;
}
.related-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:16px;}
.product-card{border:1px solid var(--rrg-line);border-radius:var(--radius);overflow:hidden;background:#fff;display:flex;flex-direction:column;}
.product-card img{aspect-ratio:1/1;object-fit:contain;background:#f7f7f7;padding:12px;}
.product-card .body{padding:12px 14px 14px;flex:1;display:flex;flex-direction:column;}
.product-card h3{font-family:'Lato',sans-serif;text-transform:none;font-weight:700;font-size:13.5px;margin:0 0 6px;flex:1;letter-spacing:0;color:#232323;}
.product-card .price{font-family:'Barlow Condensed',sans-serif;font-weight:700;font-size:18px;margin-bottom:8px;}
.product-card .btn{padding:9px 12px;font-size:12px;}

/* Reviews tab (2026-09-11, then replaced with a real embed same day) — a real REVIEWS.io
   Polaris widget now renders here (see the inline <script> in each template's Reviews tab
   content, store: 'roof-racks-galore'), which natively provides its own Product/Company
   sub-tabs via options.types: 'product_review,store_review' — this replaced an earlier
   hand-rolled pill-toggle + placeholder review-card scaffold (initReviewTabs(),
   .rvw-tabs/.review-card in shared.css) that's no longer needed now that real data/UI comes
   from the widget itself. */

/* FAQ accordion (2026-09-11) — sits below the Tabs widget, above Related Products. Not a
   tab (spec item 20 is explicit about that), and unlike the Tabs widget's single-open-panel
   radio hack, FAQ items should open independently, so this uses native <details>/<summary> —
   no JS needed, consistent with the project's plain-HTML-first approach. */
.faq-section{margin:40px 0;}
.faq-heading{margin-bottom:16px;}
.faq-list{display:flex;flex-direction:column;gap:10px;}
.faq-item{border:1px solid var(--rrg-line);border-radius:8px;padding:0 16px;background:#fff;}
.faq-item summary{list-style:none;cursor:pointer;padding:14px 26px 14px 0;font-weight:700;font-size:14.5px;position:relative;}
.faq-item summary::-webkit-details-marker{display:none;}
.faq-item summary::after{content:'+';position:absolute;right:2px;top:12px;font-size:19px;color:#767676;}
.faq-item[open] summary::after{content:'\2212';}
.faq-answer{padding:0 0 16px;font-size:13.5px;color:#404247;}
.faq-answer p{margin:0;}

.nav-strip{background:#fff;border-bottom:1px solid var(--rrg-line);padding:12px 0;font-size:13px;}
.nav-strip .wrap{display:flex;gap:16px;align-items:center;justify-content:space-between;flex-wrap:wrap;}
.nav-strip a.tag{padding:6px 14px;border-radius:999px;border:1px solid var(--rrg-line);text-decoration:none;font-weight:700;}
.nav-strip a.tag.current{background:var(--rrg-black);color:#fff;border-color:var(--rrg-black);}

@media (max-width: 900px){
  .trust-row{grid-template-columns:repeat(2,1fr);}
  .trust-row .item:nth-child(2n+1){border-left:0;}
  .trust-row .item:nth-child(n+3){border-top:1px solid var(--rrg-line);}
}

/* ==========================================================================
   Mobile content type scale (2026-09-11, mobile audit)
   ==========================================================================
   Real, structural finding: only headings/prices (Barlow Condensed, 18px+) sit above
   Google's 16px mobile-readability floor. Nearly everything a shopper actually reads —
   fitment status, tab content, specs, delivery/collect info, descriptions — was set
   12.5–15px across the component library, which reads as uniformly small on mobile even
   though the viewport meta tag itself is correct (not a zoom/scaling bug).

   !important is used deliberately, not as a shortcut: several of these selectors are
   re-declared in each template's own local <style> block (e.g. .short-desc, .sku-row),
   which loads after this shared stylesheet in every page's <head> and would otherwise
   silently win the cascade on source order alone despite equal specificity. This block
   is meant to be the authoritative mobile floor regardless of what a given template
   re-set locally — that's the point of centralizing it here rather than patching five
   separate files piecemeal.

   Two tiers only, kept deliberately close to the original design so this reads as a
   readability fix, not a redesign:
   - "Reading" tier → 16px: content meant to be read as sentences/paragraphs (fitment
     copy, tab panels, short description, specs, delivery/collect fields and results).
   - "Secondary" tier → 14px: short supporting lines (stock status, trust copy, package
     rows, view-all links, install tag copy) — still comfortably above the old 11–13px,
     short of full "reading" size since these were never meant to carry equal weight.
   True badges/chips/pills (stock-chip, badge-save, cart-badge count) are intentionally
   left out — enlarging those breaks their fixed pill/circle shapes; the worst offenders
   there (reviews.io badge, ex-demo tag, package quantity, fitted-option sub-copy) were
   already bumped in their base rules above, not gated to mobile only. */
@media (max-width:640px){
  .fitment{font-size:16px!important;}
  .tabs .content{font-size:16px!important;}
  .short-desc{font-size:16px!important;}
  .specs-table th,.specs-table td{font-size:15px!important;}
  .guarantee-usps li{font-size:16px!important;}
  .usp-item p{font-size:16px!important;}
  .vehicle-fit-notes{font-size:15px!important;}
  .dc-option,.dc-store{font-size:15px!important;}
  .product-card h3{font-size:14.5px!important;}
  /* Inputs specifically need >=16px on iOS Safari, or focusing one auto-zooms the whole
     page in — a real, well-known mobile bug, not just a readability nicety here. */
  .dc-input{font-size:16px!important;}

  .muted{font-size:14px!important;}
  .stock-status-line{font-size:14px!important;}
  .package-item{font-size:14px!important;}
  .trust-row p{font-size:14px!important;}
  .pb-text{font-size:13px!important;}
  .rrg-crumbs{font-size:13px!important;}
  .sku-row{font-size:14px!important;}
  .dc-viewall-row{font-size:13px!important;}
  .install-cta-panel .install-tag{font-size:13.5px!important;}
  .exdemo-slideout-head p{font-size:13px!important;}
  .exdemo-option .eo-note{font-size:13px!important;}
}
