@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap');

/* ─── Page transitions (cross-document View Transitions) ─────────
   Same-origin navigations between site pages cross-fade smoothly in supporting
   browsers (Chromium). Unsupported browsers navigate instantly, exactly as
   before — this is purely additive. Both pages must opt in, which they do via
   this shared stylesheet. The new page rises in gently; the old fades out. */
@view-transition { navigation: auto; }

/* The transition is the sole page entrance now, so there are no on-load body/nav
   fade or slide animations to run a second time after it finishes. The nav is a
   named group (see navbar.js), so it stays anchored while the page content and
   footer cross-fade and rise beneath it. */
@media (prefers-reduced-motion: no-preference) {
  /* Outgoing page: a quick, clean fade. Incoming page: a slower, expo-eased
     fade that rises gently into place — calm and expensive, not bouncy. */
  ::view-transition-old(root) { animation: vt-page-out 0.24s cubic-bezier(0.4, 0, 0.2, 1) both; }
  ::view-transition-new(root) { animation: vt-page-in 0.46s cubic-bezier(0.16, 1, 0.3, 1) both; }
  ::view-transition-group(yl-nav) { animation-duration: 0.24s; }
  @keyframes vt-page-out { from { opacity: 1; } to { opacity: 0; } }
  @keyframes vt-page-in  { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
}

/* ─── Animations ─────────────────────────────────────────────── */
@keyframes slideUp {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes popIn {
  from { opacity: 0; transform: scale(0.94); }
  to   { opacity: 1; transform: scale(1); }
}

/* ─── Variables ─────────────────────────────────────────────── */
:root {
  /* Bottom-overlay stacking ladder. The navbar widget owns 98-100; the compare
     picker is the modal layer above sheets/CTAs, while Product Advisor (9990)
     and the Swup transition overlay (10000) remain the global top layers. */
  --z-typeahead:      50;
  --z-filter-backdrop:119;
  --z-filter-sheet:   120;
  --z-compare-tray:   200;
  --z-sticky-cta:     900;
  --z-compare-sheet:  950;
  --z-toast:          999;
  --z-picker-backdrop:1090;
  --z-picker:          1091;

  /* Warm palette — ReBond direction: deep near-black ink + clean warm-neutral
     canvas (replaces the earlier muddier beige). Still warm, never yellow. */
  --red:       #CC2929;   /* primary CTA, accents, eyebrow labels, links */
  --red-dark:  #a82020;   /* link hover on dark */
  --red-hover: #b62525;   /* button hover */
  --red-bright:#ff5a4d;   /* headline highlight word, "+" glyphs on dark */
  --red-on-dark:#e79a9a;  /* eyebrow label on dark backgrounds */
  --red-tint:  #fbe9e4;
  --red-tint-bdr: #f0cfc9;
  --green:     #16803a;
  --green-tint: #eaf5ec;
  --green-tint-bdr: #cfe8d5;
  --green-dot: #16a34a;
  --dark:      #141310;   /* nav + dark hero blocks (deep warm-black, not brown) */
  --dark-2:    #131210;   /* footer dark (canonical) */
  /* Structural ink + neutrals (warm B2B design system) */
  --ink:       #141310;   /* darkest surface (hero/nav background) */
  --ink-2:     #1f1d19;   /* raised warm dark — gradient depth */
  --ink-3:     #322e26;
  --panel:     #faf9f5;   /* surface / input / spec-label cells */
  --panel-2:   #f2f0ea;   /* image well / secondary panel */
  --line:      #e7e3d8;   /* light divider (table rows) */
  --line-2:    #d8d3c5;   /* stronger divider */
  --muted-2:   #767066;   /* captions / meta / mono labels (AA on light) */
  --muted-on-dark: #b9b3a6; /* body text on dark */
  --bg:        #f6f4ef;   /* page canvas — clean warm neutral */
  --card:      #ffffff;   /* card surface (crisp on the canvas) */
  --well:      #f2f0ea;   /* product image well */
  --border:    #dad5c8;   /* card borders (border strong) */
  --text:      #1e1c17;   /* body ink */
  --body:      #47433b;   /* long-form body copy (softer than ink) */
  --muted:     #6a655a;   /* secondary text */
  --radius:    4px;
  --shadow:    0 1px 3px rgba(32,30,24,0.05);
  --shadow-md: 0 6px 20px -6px rgba(32,30,24,0.12);
  --ease:      cubic-bezier(0.23, 1, 0.32, 1);
  --mono:      'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --compare-tray-height: 0px; /* live measured height; compare.js owns the value */
}

/* When the compare tray is open, reserve its height so it never occludes the
   last products or the bottom filter rows. Set live from JS (compare.js). The
   space is added inside the (dark) footer rather than as body padding, so the
   reserved strip matches the footer instead of exposing a cream band of page
   background beneath it. The tray sits flush with the viewport edge (no float
   gap); the +16px is just breathing room above it. */
@media (min-width: 641px) {
  body.compare-open .site-footer { padding-bottom: calc(var(--compare-tray-height) + 16px); }
  body.compare-open .filter-sidebar {
    max-height: var(--compare-filter-max-height,
      calc(100vh - 104px - var(--compare-tray-height)));
  }
  html:has(body.compare-open) {
    scroll-padding-bottom: calc(var(--compare-tray-height) + 16px);
  }
}

@media (max-width: 640px) {
  body.compare-open:not(.cmp-sheet-open) .site-footer {
    padding-bottom: calc(var(--compare-tray-height) + 14px);
  }
  html:has(body.compare-open:not(.cmp-sheet-open)) {
    scroll-padding-bottom: calc(var(--compare-tray-height) + 14px);
  }
}

/* CMP-001: while the mobile nav menu is open (navbar.js sets this class), the
   bottom overlays must never float over the menu or its backdrop. Hidden, not
   restacked, so the menu is the single interactive layer while open. */
body.nav-drawer-open .sticky-cta,
body.nav-drawer-open .compare-tray { visibility: hidden; }

/* The shared footer injects its own styles at runtime; this higher-specificity
   public-site override keeps the compact contact labels AA-readable on black. */
body .site-footer-contact dt { color: #a49d90; }

/* navbar.js injects the 60px shared header from the head script. Reserve that
   exact flow space before injection, then hand it back when .nav exists, so a
   cold page load does not shove every public-page section downward. */
@supports selector(body:has(> .nav)) {
  body:not(.nf-body):not(:has(> .nav)) > #swup { padding-top: 60px; }
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

::selection { background: var(--red); color: #fff; }

/* Screen-reader only utility */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

/* Belt-and-braces against the thin cream edge-slivers some mobile browsers
   render beside full-bleed sections (footer, trust strip, toolbar) when the
   layout viewport ends up a fraction wider than the visual viewport. Clipping
   horizontal overflow at the root keeps full-bleed sections filling the exact
   viewport width. `clip` (NOT `hidden`) does not establish a scroll container,
   so the sticky mobile toolbar keeps sticking. */
html, body {
  max-width: 100%;
  overflow-x: clip;
  /* Stop the page rubber-banding past its content, so scrolling ends cleanly at
     the footer instead of over-pulling to reveal the cream page background. */
  overscroll-behavior-y: none;
}
html {
  /* Fallback for browsers that still bounce despite the above: the exposed sliver
     shows THIS near-black (matches the dark nav + footer), never the cream page. */
  background: #131210;
  /* Kill iOS's default tap box: it's a hard rectangle that ignores border-radius,
     so it flashes an ugly corner-square on our rounded buttons/rows. Interactive
     elements supply their own :active feedback, so nothing is lost. */
  -webkit-tap-highlight-color: transparent;
  /* Stop iOS Safari from auto-inflating text when the phone rotates to landscape
     (the reported "everything looks zoomed in" bug) — hold text at its authored size. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* NEVER let a form control trigger iOS focus-zoom: Safari zooms the whole page
   in the instant you focus any field whose font-size is below 16px, and it
   deliberately IGNORES maximum-scale / user-scalable=no — so 16px is the ONLY
   lever. !important is required here: several inputs (.search-bar input at
   0.95rem, .yl-adv-input, etc.) carry equal-or-higher-specificity font-size
   rules that appear LATER in the file and would otherwise win the tie. Blanket
   every control so no field is ever missed. Do not lower this below 16px. */
@media (max-width: 640px) {
  input, textarea, select { font-size: 16px !important; }
}

/* Display typeface for headings — engineered, B2B character */
h1, h2, h3,
.detail-product-name {
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  letter-spacing: -0.01em;
}

/* ─── Nav ────────────────────────────────────────────────────── */
/* All nav styling is owned by js/widgets/navbar.js (injected at runtime). */

/* ─── Page Hero / Search (locked final design: warm light hero) ──
   One shared hero pattern for every owned public page: warm cream band,
   dark editorial type, red mono eyebrow, and an optional industrial photo
   pinned to the right edge behind a soft cream fade. */

.page-hero {
  background: linear-gradient(180deg, #f9f7f2 0%, var(--bg) 100%);
  color: var(--text);
  padding: 0;
  text-align: left;
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
}

/* Shared content container inside the hero. */
.page-hero-inner {
  max-width: 1400px;
  margin: 0 auto;
  padding: 2.4rem 2rem 2.3rem;
  position: relative;
  z-index: 1;
}

/* Small breadcrumb inside the hero (enquiry page). */
.hero-breadcrumb {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.8rem;
  color: var(--muted);
  margin-bottom: 1rem;
}
.hero-breadcrumb a { color: var(--muted); text-decoration: none; }
.hero-breadcrumb a:hover { color: var(--red); }
.hero-breadcrumb [aria-current] { color: var(--text); font-weight: 500; }

.page-hero .hero-eyebrow {
  display: block;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 0.85rem;
}

.page-hero h1 {
  font-size: clamp(1.9rem, 3.6vw, 2.8rem);
  line-height: 1.08;
  margin-bottom: 0;
  letter-spacing: -0.015em;
  font-weight: 700;
  color: var(--text);
  max-width: 22ch;
}

.page-hero p {
  color: var(--muted);
  margin: 0.85rem 0 0;
  font-size: 1rem;
  max-width: 52ch;
}

/* Industrial photo treatment: pinned right, fading into the cream canvas so
   the copy column stays crisp. Decorative only (aria-hidden container). */
.page-hero-img {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(54%, 780px);
  background: url("/images/hero/industrial-dispense.jpg") right top / cover no-repeat;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 42%);
  mask-image: linear-gradient(90deg, transparent 0%, #000 42%);
  pointer-events: none;
}

@media (max-width: 900px) {
  /* Phones: the photo stays a top-right corner accent behind the heading,
     double-masked (left + bottom) so the copy always sits on readable cream. */
  .page-hero-img {
    width: 82%;
    bottom: auto;
    height: 72%;
    opacity: 0.5;
    -webkit-mask-image: linear-gradient(90deg, transparent 6%, #000 62%),
      linear-gradient(180deg, #000 40%, transparent 96%);
    -webkit-mask-composite: source-in;
    mask-image: linear-gradient(90deg, transparent 6%, #000 62%),
      linear-gradient(180deg, #000 40%, transparent 96%);
    mask-composite: intersect;
  }
  .page-hero-inner { padding: 1.9rem 1.25rem 1.8rem; }
}

/* Products-only responsive hero media. Other public pages (including protected
   Home) retain the existing shared industrial-dispense treatment above. */
.products-hero .products-hero-media { background: none; }
.products-hero-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 100% 50%;
}
@media (min-width: 901px) {
  .products-hero .products-hero-media {
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 48%);
    mask-image: linear-gradient(90deg, transparent 0%, #000 48%);
  }
}
@media (min-width: 641px) and (max-width: 900px) {
  .products-hero .products-hero-media {
    width: 68%;
    height: 68%;
    opacity: 0.32;
    -webkit-mask-image: linear-gradient(90deg, transparent 8%, #000 68%),
      linear-gradient(180deg, #000 34%, transparent 96%);
    mask-image: linear-gradient(90deg, transparent 8%, #000 68%),
      linear-gradient(180deg, #000 34%, transparent 96%);
  }
}
@media (max-width: 640px) {
  .products-hero .products-hero-media { display: none; }
}

.search-bar {
  display: flex;
  align-items: stretch;
  max-width: 620px;
  margin: 1.6rem 0 0;
  background: #fff;
  border: 1px solid var(--line-2);
  border-radius: 6px;
  overflow: hidden;
  box-shadow: var(--shadow);
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

/* Leading magnifier so the field reads unmistakably as search. */
.search-bar-icon {
  display: flex;
  align-items: center;
  padding-left: 1rem;
  color: var(--muted);
  flex-shrink: 0;
  transition: color 0.2s var(--ease);
}

.search-bar input {
  flex: 1;
  padding: 0.9rem 1rem 0.9rem 0.65rem;
  border: none;
  background: transparent;
  font-size: 0.95rem;
  font-family: inherit;
  color: var(--text);
  outline: none;
  min-width: 0;
}

.search-bar input::placeholder {
  color: var(--muted);
}

/* Red square action button with the white magnifier glyph. */
.search-bar button {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--red);
  color: #fff;
  border: none;
  min-width: 56px;
  padding: 0 1.1rem;
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 700;
  font-family: inherit;
  transition: background 0.2s;
}

.search-bar button:hover { background: var(--red-hover); }

/* Crisp focus: red border + 1px hairline ring. No soft outer glow. */
.search-bar:focus-within {
  border-color: var(--red);
  box-shadow: 0 0 0 1px var(--red);
}
.search-bar:focus-within .search-bar-icon { color: var(--red); }

/* ─── Hero search typeahead ──────────────────────────────────────
   Lightweight suggestion dropdown under the hero search bar. The hero inner
   uses overflow:hidden for its two-column layout, which would clip an absolute
   child, so the panel is position:fixed (escaping the clip) and its left/top/
   width are set in JS from the search bar's rect, repositioned on scroll. */
.hero-search { position: relative; }
.search-typeahead {
  position: fixed;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: var(--shadow-md);
  z-index: var(--z-typeahead);
  /* Controlled height: the panel must never sprawl over the filters/grid.
     JS may lower this further to fit the viewport, never raise it. */
  max-height: 420px;
  overflow-y: auto;
}
.search-typeahead[hidden] { display: none; }
.search-typeahead-row {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.55rem 0.7rem;
  border-radius: 6px;
  cursor: pointer;
}
.search-typeahead-row:hover,
.search-typeahead-row[aria-selected="true"] { background: var(--red-tint); }
.search-typeahead-row .st-name {
  font-weight: 600;
  color: var(--ink);
  font-size: 0.9rem;
}
.search-typeahead-row .st-brand {
  color: var(--muted);
  font-size: 0.78rem;
  white-space: nowrap;
}
/* Red highlight on the matched substring (override the default yellow mark). */
.search-typeahead-row .st-hit {
  background: none;
  color: var(--red);
  font-weight: 700;
}
.search-typeahead-empty {
  padding: 0.7rem;
  color: var(--muted);
  font-size: 0.85rem;
}

/* ─── Grouped suggestions (SEARCH-001) ────────────────────────── */
.search-typeahead { overscroll-behavior: contain; } /* inner scroll never drags the page */
/* While suggestions are open, lift the hero container above later page
   sections so the fixed panel always paints over them. 60 sits above the
   sticky toolbar (40), below the nav (98-100). */
.page-hero-inner.st-elevate { z-index: 60; }
.st-group {
  padding: 0.55rem 0.7rem 0.25rem;
  font-family: var(--mono);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.st-group + .st-group { border-top: 1px solid var(--line-2); }
.search-typeahead-row { align-items: center; }
.st-thumb {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: 6px;
  object-fit: contain;
  background: var(--img-well, #f2f0ea);
  border: 1px solid var(--line-2);
}
.st-thumb-ph { display: inline-block; }
.st-main { display: flex; flex-direction: column; min-width: 0; }
.st-main .st-name,
.st-main .st-brand { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-row-filter { justify-content: space-between; }
.st-count {
  color: var(--muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex-shrink: 0;
}
.st-row-action {
  color: var(--red);
  font-weight: 600;
  font-size: 0.85rem;
}
/* A9: comfortable touch rows on phones */
@media (max-width: 640px) {
  .search-typeahead-row { min-height: 44px; }
}

/* ─── Layout: Sidebar + Grid ─────────────────────────────────── */
.catalogue-layout {
  display: flex;
  max-width: 1400px; /* shared content container (matches the hero) */
  margin: 1.5rem auto 4rem;
  padding: 0 2rem;
  gap: 2rem;
  align-items: flex-start;
}

/* ─── Filter Sidebar ──────────────────────────────────────────── */
.filter-sidebar {
  width: 304px;
  flex-shrink: 0;
  position: sticky;
  top: 84px;
  /* Cap to the viewport; the heading stays fixed and the inner .drawer-body
     scrolls, so a tall filter list never runs off-screen once pinned. */
  max-height: calc(100vh - 104px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 1.25rem;
}
.filter-heading { flex-shrink: 0; }

/* The scrolling region (filter groups + clear). Edge fades appear only when it
   actually overflows (.has-overflow, toggled in JS) so rows never hard-cut.
   Thin warm scrollbar, transparent track, visible only while scrollable. */
.filter-sidebar .drawer-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding-bottom: 12px;
  scrollbar-width: thin;
  scrollbar-color: #d8d3c5 transparent;
  overscroll-behavior: contain; /* FILTER-001: sidebar scroll never chains into the page */
}
.filter-sidebar .drawer-body.has-overflow {
  --fade-top: 14px;
  --fade-bot: 14px;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--fade-top), #000 calc(100% - var(--fade-bot)), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 var(--fade-top), #000 calc(100% - var(--fade-bot)), transparent 100%);
}
/* Only fade an edge that has content hidden past it: no top fade at the very
   top (so the first heading + count read clean), no bottom fade at the end. */
.filter-sidebar .drawer-body.has-overflow.at-top { --fade-top: 0px; }
.filter-sidebar .drawer-body.has-overflow.at-bottom { --fade-bot: 0px; }
.filter-sidebar .drawer-body::-webkit-scrollbar { width: 8px; }
.filter-sidebar .drawer-body::-webkit-scrollbar-track { background: transparent; }
.filter-sidebar .drawer-body::-webkit-scrollbar-thumb { background: #d8d3c5; border-radius: 4px; }
.filter-sidebar .drawer-body::-webkit-scrollbar-thumb:hover { background: #c4bdac; }

/* Panel title: mono "FILTERS" eyebrow + live "n filters active" summary. */
.filter-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: 0.9rem;
}
.filter-active-total {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--red);
  white-space: nowrap;
}

.filter-group {
  margin-bottom: 1.5rem;
}

.filter-group h3 {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 0.6rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.filter-group-badge {
  display: none;
}

.filter-group label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
  color: var(--text);
  padding: 0.2rem 0;
  cursor: pointer;
}

.filter-group input[type="checkbox"] {
  accent-color: var(--red);
  width: 15px;
  height: 15px;
  cursor: pointer;
}

.filter-clear {
  width: 100%;
  padding: 0.62rem;
  background: none;
  border: 1px solid #d8d3c5;
  border-radius: 7px;
  color: #47433b;
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.18s, color 0.18s, background 0.18s;
  margin-top: 0.5rem;
}

.filter-clear:hover {
  border-color: var(--red);
  color: var(--red);
  background: var(--red-tint);
}

/* Filters backdrop: hidden by default at every width (the ≤640 drawer block
   restyles it as the fixed dim layer). Without this base rule it sits in the
   catalogue flex flow as a zero-height item and adds a phantom flex gap. */
.filter-backdrop { display: none; }

/* Mobile filter toggle */
.filter-toggle {
  display: none;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.75rem 1rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: 0.95rem;
  cursor: pointer;
  margin-bottom: 1rem;
  text-align: left;
  font-weight: 600;
  min-height: 44px;
}
.filter-toggle svg { flex-shrink: 0; color: var(--muted); }

/* ─── Product Grid ────────────────────────────────────────────── */
.product-grid-section {
  flex: 1;
}

/* Flat editorial results row (locked ReBond direction): no box, no pill, no
   divider — the count reads as a page caption, the sort control is the only
   chrome, and spacing alone separates it from the grid. */
.grid-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.3rem;
  padding: 0.15rem 0.1rem;
  font-size: 0.875rem;
  color: var(--muted);
}

.grid-sort {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
}

.grid-sort-label {
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-2);
}

.product-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem;
}

/* ─── Product Card (locked final design) ──────────────────────────
   White card: brand mark + labelled Compare checkbox on a head row, image
   well, product number, name, truthful subtype, labelled Best for / Works on
   rows, and two equal actions. Same structure at every breakpoint. */
.product-card.animate {
  animation: slideUp 0.4s cubic-bezier(0.23, 1, 0.32, 1) both;
}

.product-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  position: relative;
  transition: box-shadow 0.2s, border-color 0.2s;
}

.product-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--line-2);
}

/* Desktop: a no-op wrapper, so the card stays the SAME head/image/body/actions
   flex column it always was. At <=640px it becomes the compact two-column
   (image + info) grid — see the phones block. */
.pcard-main { display: contents; }

/* Head row: official brand mark left, Compare checkbox right. */
.pcard-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.8rem 1rem 0.55rem;
}
.pcard-brand { display: inline-flex; align-items: center; gap: 0.45rem; min-height: 22px; min-width: 0; }
/* The official marks sit centred on large padded canvases; a fixed window with
   a CSS zoom crops the padding without touching (or redrawing) the asset. */
.pcard-brand-ic {
  position: relative;
  width: 24px;
  height: 24px;
  overflow: hidden;
  flex-shrink: 0;
}
.pcard-brand-ic img {
  position: absolute;
  width: 240%;
  height: 240%;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  object-fit: contain;
}
.pcard-brand-name {
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pcard-brand-text {
  font-family: var(--mono);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-2);
  border: 1px solid var(--line-2);
  border-radius: 4px;
  padding: 3px 7px;
  line-height: 1;
}

/* Labelled Compare checkbox (the same control on every breakpoint). */
.pcard-cmp {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  background: none;
  border: none;
  padding: 0.25rem 0.1rem;
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--muted);
  cursor: pointer;
}
.pcard-cmp .pcard-cb {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 17px;
  height: 17px;
  border: 1.5px solid var(--line-2);
  border-radius: 4px;
  background: #fff;
  transition: background 0.15s, border-color 0.15s;
}
.pcard-cmp .pcard-cb svg { width: 11px; height: 11px; color: #fff; opacity: 0; }
.pcard-cmp.on { color: var(--text); }
.pcard-cmp.on .pcard-cb { background: var(--red); border-color: var(--red); }
.pcard-cmp.on .pcard-cb svg { opacity: 1; }
.pcard-cmp:disabled { opacity: 0.45; cursor: not-allowed; }
.pcard-cmp:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; border-radius: 4px; }

.product-card-image {
  width: 100%;
  aspect-ratio: 4 / 3;
  /* Uniform light plate so mismatched product photo backgrounds (some white,
     some grey) read as one consistent set rather than scraped shots. */
  background: var(--panel-2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: 0.8rem;
  overflow: hidden;
  position: relative;
}

.product-card-image img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 1rem;
}

/* Clickable image -> product detail. The compare button + status badge sit
   above this (z-index 3), so they stay independently clickable. */
.product-card-image-link {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  text-decoration: none;
}
.product-card-image-link img { transition: transform 0.35s cubic-bezier(0.23, 1, 0.32, 1); }
.product-card:hover .product-card-image-link img { transform: scale(1.04); }

/* Soften the imagery of unavailable products so the state reads at a glance */
.product-card.is-unavailable .product-card-image img {
  opacity: 0.78;
  filter: saturate(0.85);
}

.product-card-body {
  padding: 1.05rem 1.1rem 0; /* bottom padding now lives on the moved-out actions row */
  flex: 1;
  display: flex;
  flex-direction: column;
}

/* One consistent internal card grid (no standalone product-number line — the
   number already lives inside the real product name): a controlled two-line
   title area, then the subtype, rows and actions all start on the same
   baselines across a row regardless of title length. */
.product-card-body h3 {
  font-size: 1.05rem;
  font-weight: 700;
  margin-bottom: 0.3rem;
  color: var(--text);
  line-height: 1.3;
  /* Reserve exactly two lines: long names clamp, short names keep the same
     title-area height, so the type line begins at one shared baseline. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.75rem;
}

/* Truthful subtype line under the name. */
.pcard-subtype {
  font-size: 0.82rem;
  color: var(--muted);
  margin-bottom: 0.75rem;
}

/* Clickable product title -> product detail. */
.product-card-title-link {
  color: inherit;
  text-decoration: none;
  transition: color 0.15s;
}
.product-card-title-link:hover { color: var(--red); text-decoration: underline; text-underline-offset: 2px; }
.product-card-title-link:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; border-radius: 2px; }

.product-card-body p {
  font-size: 0.82rem;
  color: var(--muted);
  margin-bottom: 0.65rem;
  line-height: 1.45;
}

/* Labelled data rows: icon + label left, real value right. Hairline dividers
   give the card its structured, industrial read. */
.pcard-rows { border-top: 1px solid var(--line); margin-bottom: 0.85rem; }
.pcard-main > .pcard-rows { margin-left: 1.1rem; margin-right: 1.1rem; }

.card-application {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8rem;
  color: var(--text);
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--line);
  min-width: 0;
}

.card-application-ic {
  display: inline-flex;
  color: var(--muted-2);
  flex-shrink: 0;
}

.card-application-label {
  font-weight: 600;
  color: var(--text);
  font-size: 0.8rem;
  flex-shrink: 0;
}

.card-application-val {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  margin-left: auto;
  text-align: right;
  color: var(--muted);
}

/* Reserves the Works-on row height so no-surface cards stay aligned with row-mates */
.card-workson-spacer { min-height: 2.35rem; }

/* "View details" secondary (locked reference): white surface, red hairline
   border, red label + chevron. Clearly secondary to the red primary. */
.product-card-actions .pcard-view {
  border-width: 1px;
  border-color: var(--red);
  color: var(--red);
  font-weight: 600;
  gap: 0.35rem;
}
.product-card-actions .pcard-view:hover {
  border-color: var(--red-dark);
  background: var(--red-tint);
  color: var(--red-dark);
}

/* Premium shared action row (Home + catalogue + any page using the card):
   comfortable spacing, balanced equal widths, icons only where the card is
   wide enough for them to sit cleanly. The row is its own inline-size
   container so the icon/stacking decisions follow the CARD's real width,
   not the viewport. */
.product-card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: auto;
  padding: 0 1.1rem 1.15rem; /* the card's side + bottom padding (actions is now a card child) */
  container-type: inline-size;
}

.product-card-actions .btn {
  padding: 0.66rem 0.8rem;
  gap: 0.45rem;
}

/* Narrow cards: drop the decorative icons before anything can crowd. */
@container (max-width: 264px) {
  .product-card-actions .pcard-enq svg,
  .product-card-actions .pcard-view svg { display: none; }
}

/* Very narrow cards: stack the two actions full-width (deliberate, calm)
   instead of letting labels shrink or wrap awkwardly side by side. */
@container (max-width: 236px) {
  .product-card-actions { flex-direction: column; }
  .product-card-actions .pcard-enq,
  .product-card-actions .pcard-view { flex: 1 1 auto; width: 100%; }
}

.btn {
  padding: 0.55rem 0.95rem;
  border-radius: var(--radius);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background 0.18s, border-color 0.18s, color 0.18s, box-shadow 0.18s, transform 0.1s;
  text-decoration: none;
  text-align: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  font-family: inherit;
  line-height: 1.2;
  letter-spacing: 0.1px;
  white-space: nowrap;
  flex-shrink: 0;
}

.btn:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

.btn:active:not(:disabled) { transform: scale(0.97); }

.btn-primary {
  background: var(--red);
  color: #fff;
  border-color: var(--red);
}

.btn-primary:hover { background: var(--red-dark); border-color: var(--red-dark); }

.btn-outline {
  background: #fff;
  border: 1px solid var(--border);
  color: var(--text);
  font-weight: 600;
}

.btn-outline:hover {
  border-color: #c4bdac;
  color: var(--text);
  background: #faf9f5;
}

/* Two equal actions per the locked design: red primary + outlined secondary.
   flex:1 keeps each a fixed half-width so the row never reflows when the
   enquiry label toggles between "Add to Enquiry" and "In Enquiry". */
.product-card-actions .pcard-enq  { flex: 1 1 0; min-width: 0; }
.product-card-actions .pcard-view { flex: 1 1 0; min-width: 0; }

/* Selected ("In Product Enquiry") state: calm, confirmed red-tint. Not an
   alert, not a checkbox, not a cart button. Same height/width as the default
   so toggling never shifts the card. */
.btn-added {
  background: var(--red-tint) !important;
  color: var(--red) !important;
  border: 1px solid var(--red-tint-bdr) !important;
}


/* ─── Empty State ─────────────────────────────────────────────── */
.empty-state {
  text-align: center;
  padding: 4rem 2rem;
  color: var(--muted);
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}

.empty-state-icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  color: #c4bdac;
  margin-bottom: 0.5rem;
}

.empty-state h2, .empty-state h3 { font-size: 1.05rem; margin-bottom: 0.25rem; color: var(--text); font-weight: 700; }
.empty-state p { margin-bottom: 1rem; font-size: 0.9rem; }
.empty-state .btn { padding: 0.6rem 1.25rem; }
.empty-state-actions { display: flex; gap: 0.6rem; justify-content: center; flex-wrap: wrap; }

/* Inline field validation message (enquiry form). Matches the summary error
   red (#c0392b) so genuine errors stay visually distinct from brand red. */
.field-error {
  color: #c0392b;
  font-size: 0.8rem;
  margin: 0.35rem 0 0;
}

/* ─── Toast Notification ──────────────────────────────────────── */
.toast {
  position: fixed;
  bottom: 1.5rem;
  right: 1.5rem;
  background: var(--dark);
  color: #fff;
  padding: 0.75rem 1.25rem;
  border-radius: var(--radius);
  font-size: 0.875rem;
  z-index: var(--z-toast);
  opacity: 0;
  transform: translateY(10px);
  transition: all 0.3s;
  pointer-events: none;
}

.toast.show {
  opacity: 1;
  transform: translateY(0);
}

/* The toast is now shown ONLY for real errors (add-to-enquiry success is silent +
   announced to screen readers). Style errors distinctly so they never read as a
   success/confirmation, and lift them above the fixed product-detail action bar
   so an error is never hidden behind it. */
.toast--error {
  background: #9a2018;
  border-left: 3px solid #ffd7d1;
}
body.detail-has-cta .toast {
  bottom: calc(4.9rem + env(safe-area-inset-bottom, 0px) + 0.75rem);
}

/* ─── Filter chip pop-in ──────────────────────────────────────── */
.filter-chip { animation: popIn 0.2s cubic-bezier(0.23, 1, 0.32, 1) both; }

/* ─── Product Detail Page ─────────────────────────────────────── */
.breadcrumb {
  max-width: 1280px;
  margin: 1.5rem auto 0;
  padding: 0 1.5rem;
  font-size: 0.85rem;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.breadcrumb a { color: var(--muted); text-decoration: none; }
.breadcrumb a:hover { color: var(--red); }
.breadcrumb [aria-current] { color: var(--text); font-weight: 500; }

/* ─── Light page breadcrumb (replaces dark hero band) ────────── */
/* Detail page breadcrumb: shares the SAME 1180px/40px content container as the
   gallery/tabs/related sections below it, so every band starts on one left edge. */
.page-breadcrumb {
  max-width: 1180px;
  margin: 0.6rem auto 0;
  padding: 0 40px;
  font-size: 0.85rem;
  color: var(--muted);
}

@media (max-width: 768px) {
  .page-breadcrumb { padding: 0 24px; }
}
@media (max-width: 560px) {
  .page-breadcrumb { padding: 0 16px; }
}

.related-section { animation: slideUp 0.4s cubic-bezier(0.23, 1, 0.32, 1) 0.3s both; }

/* ─── Application & Suitable Uses tab content ────────────────────
   Richer structured layout (follow-up reference, real data only): up to
   three columns — Application Method (numbered steps only when the real
   instructions have genuine sequential sentences), Suitable Uses, and Key
   Benefits (recorded claim strings). Hairline vertical separators between
   columns on desktop; clean stack with horizontal rules on phones. Sparse
   products naturally render fewer columns — never fake filler. */
.apply-grid {
  display: grid;
  gap: 1.9rem;
  padding: 0.25rem 0.1rem 0.2rem;
}
.apply-cols-1 { grid-template-columns: 1fr; }
.apply-cols-2 { grid-template-columns: 1fr 1fr; }
.apply-cols-3 { grid-template-columns: 1.08fr 1fr 0.98fr; }

.apply-col { min-width: 0; }
.apply-grid .apply-col + .apply-col {
  border-left: 1px solid var(--line);
  padding-left: 1.9rem;
}

/* Proper section heading (matches the richer reference): dark ink, real
   weight, small red leading icon — one heading style shared by every section
   so all products read as one design generation, whatever their section count. */
.apply-heading {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--text);
  margin: 0 0 0.95rem;
}
.apply-heading-ic { display: inline-flex; color: var(--red); flex-shrink: 0; }

/* Single designed method statement (one real instruction, e.g. "Apply by brush
   or roll."): a red icon chip + text row in the same family as the other rows,
   never a bare sentence in an empty panel. */
.apply-statement { margin: 0; padding: 0; list-style: none; }
.apply-statement li {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-size: 0.9rem;
  color: var(--text);
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.apply-statement-ic {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 7px;
  background: var(--red-tint);
  color: var(--red);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 1px;
}

/* Clean readable prose for an un-delimited Suitable-for value (never bold; the
   heading carries the emphasis). Designed body text, not a run-on blob. */
.apply-prose {
  font-size: 0.9rem;
  color: var(--text);
  font-weight: 400;
  line-height: 1.6;
  margin: 0;
  overflow-wrap: anywhere;
}

/* Numbered steps: real sequential sentences from the recorded instructions,
   verbatim, with quiet red counters. */
.apply-steps {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  counter-reset: applystep;
}
.apply-steps li {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  counter-increment: applystep;
}
.apply-step-n {
  flex-shrink: 0;
  width: 21px;
  height: 21px;
  border: 1.5px solid var(--red);
  border-radius: 50%;
  color: var(--red);
  font-size: 0.68rem;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 1px;
  font-variant-numeric: tabular-nums;
}
.apply-step-n::before { content: counter(applystep); }
.apply-step-text {
  font-size: 0.9rem;
  color: var(--text);
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.apply-uses {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.apply-uses li {
  position: relative;
  padding-left: 1.05rem;
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.5;
  color: var(--text);
  overflow-wrap: anywhere;
}

.apply-uses li::before {
  content: "";
  position: absolute;
  left: 0.1rem;
  top: 0.62em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--red);
}

/* Key Benefits: recorded claim strings with quiet red check circles. */
.apply-claims {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.apply-claims li {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--text);
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.apply-claim-ic { display: inline-flex; flex-shrink: 0; color: var(--red); margin-top: 2px; }

/* Unified Suitable Uses + Key Benefits list: one restrained red check per item,
   so both columns read as a single consistent system. */
.apply-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.apply-list li {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.5;
  color: var(--text);
  overflow-wrap: anywhere;
}
.apply-mark { display: inline-flex; flex-shrink: 0; color: var(--red); margin-top: 3px; }

.apply-empty {
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.6;
}
.apply-empty a { color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.apply-empty a:hover { color: var(--red); }
.apply-empty a:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

@media (max-width: 860px) {
  .apply-cols-3 { grid-template-columns: 1fr 1fr; }
  .apply-cols-3 .apply-col:nth-child(3) {
    grid-column: 1 / -1;
    border-left: none;
    padding-left: 0;
    border-top: 1px solid var(--line);
    padding-top: 1.25rem;
  }
}
@media (max-width: 640px) {
  .apply-grid { grid-template-columns: 1fr; gap: 1.25rem; }
  .apply-grid .apply-col + .apply-col {
    border-left: none;
    padding-left: 0;
    border-top: 1px solid var(--line);
    padding-top: 1.25rem;
  }
  .apply-cols-3 .apply-col:nth-child(3) { grid-column: auto; }
}

/* Product Documents (SDS / TDS downloads) on the product detail page. */
.detail-downloads {
  margin-top: 0;
}

.doc-download-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0.75rem;
  margin-top: 0.85rem;
}

.doc-download {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  background: var(--card);
  text-decoration: none;
  color: var(--text);
  transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;
}

.doc-download:hover {
  border-color: var(--red);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

/* Honest COMPACT empty state (follow-up reference): a larger document/
   download icon, one concise line, plain quiet support text (no competing
   text link), Talk to Yee Lim as the single action — the panel ends just
   after. Never a giant white rectangle. */
.doc-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.55rem;
  padding: 0.9rem 1rem 0;
}
.doc-empty-icon {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--red);
}
.doc-empty-icon svg { width: 38px; height: 38px; }
.doc-empty-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.doc-empty-main { font-size: 0.94rem; font-weight: 700; color: var(--text); line-height: 1.4; }
.doc-empty-sub  { font-size: 0.8rem; color: var(--muted); line-height: 1.4; }
.doc-empty-link { color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.doc-empty-link:hover { color: var(--red); }
.doc-empty-link:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; border-radius: 3px; }

/* WhatsApp fallback centred under the empty-downloads state. */
.doc-empty-wa {
  display: flex;
  width: max-content;
  flex: 0 0 auto;
  margin: 0.55rem auto 0.1rem;
  padding: 0.5rem 1rem;
}

.doc-download-icon {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(204, 41, 41, 0.08);
  color: var(--red);
}

.doc-download-text {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.doc-download-label {
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--text);
}

.doc-download-sub {
  font-size: 0.74rem;
  color: var(--muted);
}

.doc-download-go {
  margin-left: auto;
  flex-shrink: 0;
  color: var(--muted);
  transition: color 0.2s, transform 0.2s;
}

.doc-download:hover .doc-download-go {
  color: var(--red);
  transform: translateX(2px);
}

/* Product Advice band on the product detail page (locked design): white
   functional card, red headset icon, copy left, red CTA right. Sits once,
   outside the tab panels, aligned to the SAME content container as the
   gallery/tabs above and Related Products below (previously unconstrained,
   so it spanned the full browser width instead of the page's max-width). */
#detailAdvice {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 40px;
}

.enquiry-guidance {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 1.25rem;
  flex-wrap: wrap;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.85rem 1.15rem;
  margin-top: 1rem;
  margin-bottom: 1.1rem;
}

.enquiry-guidance-ic {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  color: var(--red);
}
.enquiry-guidance-ic svg { width: 22px; height: 22px; }

.enquiry-guidance-copy { min-width: 0; flex: 1; }

.enquiry-guidance-title {
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  font-size: 1.03rem;
  font-weight: 700;
  color: var(--text);
  margin: 0 0 0.3rem;
  letter-spacing: -0.01em;
}

.enquiry-guidance p {
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--muted);
  margin: 0;
  max-width: 68ch;
}

.enquiry-guidance-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  flex-shrink: 0;
  background: var(--red);
  color: #fff;
  font-size: 0.9rem;
  font-weight: 600;
  padding: 0.68rem 1.1rem;
  border-radius: var(--radius);
  text-decoration: none;
  /* Also rendered as a <button> (PD-CTA-001 opens the advisor): neutralise UA button chrome. */
  border: none;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.18s, transform 0.1s;
}

.enquiry-guidance-link:hover { background: var(--red-hover); }
.enquiry-guidance-link:active { transform: scale(0.98); }

.enquiry-guidance-link:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.related-section {
  max-width: 1180px;
  margin: 0 auto 2.5rem;
  padding: 0 40px;
}

.related-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.9rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
}

.related-section h2 {
  font-size: 1.15rem;
  font-weight: 700;
  margin: 0;
}

.related-view-all {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--red);
  text-decoration: none;
  white-space: nowrap;
}
.related-view-all:hover { text-decoration: underline; text-underline-offset: 3px; }
.related-view-all:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; border-radius: 3px; }

/* Exactly three compact cards on desktop (locked design). */
.related-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

/* ─── Related product cards (locked design: brand head, image, actions) ── */
.related-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  color: inherit;
  transition: box-shadow 0.25s var(--ease), border-color 0.25s var(--ease);
}

.related-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--line-2);
}

/* Head row: brand mark left, the same compare checkbox as the catalogue
   cards on the right (locked reference). */
.related-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.55rem 0.9rem 0.3rem;
}

.related-card-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}

/* Compact media row (locked reference): small product image on the left,
   name/summary beside it — not a full-width photo band. */
.related-card-media {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.3rem 0.9rem 0.7rem;
  flex: 1;
}

.related-card-img {
  flex: 0 0 92px;
  height: 92px;
  /* Near-white plate: the product shots carry baked-in white backgrounds, so a
     white plate makes that white seamless instead of a hard rectangle on cream. */
  background: radial-gradient(circle at 50% 46%, #ffffff 0%, #ffffff 60%, #fbfaf7 100%);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.related-card-img img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  padding: 0.45rem;
  box-sizing: border-box;
  transition: transform 0.4s var(--ease);
}

.related-card:hover .related-card-img img { transform: scale(1.05); }

.related-card-img.no-image .no-image-mark {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: -0.25px;
  color: #cdc4b2;
  user-select: none;
}

.related-card-info {
  min-width: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.related-card-name {
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--text);
  line-height: 1.3;
  letter-spacing: -0.01em;
  margin: 0 0 0.25rem;
  transition: color 0.2s var(--ease);
}

.related-card-desc {
  font-size: 0.78rem;
  color: var(--muted);
  line-height: 1.45;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.related-card-name a { color: inherit; text-decoration: none; }
.related-card-name a:hover { color: var(--red); }
.related-card-name a:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; border-radius: 2px; }

/* Base type as a quiet mono meta line under the summary. */
.related-card-base {
  margin-top: 0.4rem;
  font-family: var(--mono);
  font-size: 0.64rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted-2);
}

/* Card actions row: red text enquiry toggle left, quiet view link right. */
.related-card-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: auto;
  padding: 0.5rem 0.9rem;
  border-top: 1px solid var(--line);
}
.related-card-enq {
  background: none;
  border: none;
  padding: 0.25rem 0;
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--red);
  cursor: pointer;
  white-space: nowrap;
}
.related-card-enq:hover { text-decoration: underline; text-underline-offset: 3px; }
.related-card-enq.added { color: var(--green); }
.related-card-enq:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; border-radius: 3px; }
.related-card-view {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
}
.related-card-view:hover { color: var(--red); }
.related-card-view:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; border-radius: 3px; }

/* Phones: one horizontal scroll-snap carousel instead of squeezed columns. */
@media (max-width: 640px) {
  .related-grid {
    display: flex;
    gap: 0.8rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 0.5rem;
    scrollbar-width: none;
  }
  .related-grid::-webkit-scrollbar { width: 0; height: 0; }
  .related-card {
    flex: 0 0 82%;
    max-width: 330px;
    scroll-snap-align: start;
  }
  .related-card-enq,
  .related-card-view { min-height: 44px; display: inline-flex; align-items: center; }
  .enquiry-guidance-link { min-height: 46px; justify-content: center; }
}

/* ─── Product Enquiry Page ────────────────────────────────────── */

.page-content {
  max-width: 1180px;
  margin: 0 auto;
  padding: 36px 40px 64px;
}

/* Enquiry hero shares the SAME 1180px/40px container as the content below,
   so breadcrumb, title, intro and cards all start on one left edge. */
.page-hero-inner.hero-inner-narrow { max-width: 1180px; padding-left: 40px; padding-right: 40px; }
@media (max-width: 900px) {
  .page-hero-inner.hero-inner-narrow { padding-left: 24px; padding-right: 24px; }
  .page-content { padding-left: 24px; padding-right: 24px; }
}
@media (max-width: 640px) {
  /* Phones: both bands share the 1.25rem gutter (page-content already does). */
  .page-hero-inner.hero-inner-narrow { padding-left: 1.25rem; padding-right: 1.25rem; }
}

/* Two-column body: selected products / details form. Collapses to one
   column (form below the list) on tablet and phone. */
.enquiry-grid {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: 32px;
  align-items: start;
}

/* Empty basket: the form (right column) is hidden, so collapse to one full-width
   column. The empty state reads as one deliberate panel spanning the content
   width, with its own centred Browse CTA — so the separate "continue browsing"
   link below it is redundant and hidden here. */
.enquiry-grid.is-empty { grid-template-columns: 1fr; }
.enquiry-grid.is-empty .enquiry-col-right { display: none; }
.enquiry-grid.is-empty .enquiry-col-left { width: 100%; text-align: center; }

.enquiry-col-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 16px;
}

.enquiry-col-head h2 {
  font-size: 20px;
  font-weight: 700;
  margin: 0;
}

/* Clear all: quiet text control — light at rest, red underline on intent. */
.enquiry-clear-all {
  background: none;
  border: none;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  cursor: pointer;
  padding: 0.35rem 0.1rem;
  min-height: 44px;
}

.enquiry-clear-all:hover { color: var(--red); text-decoration: underline; text-underline-offset: 2px; }
.enquiry-clear-all:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; border-radius: 2px; }

/* White basket card wrapping the head + item rows (locked design). The
   Total Products summary band below fuses onto this card's bottom edge
   (radius squared off here, rounded there) so basket + summary read as ONE
   component with an internal divider, not two floating cards. */
.enquiry-basket-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 20px 20px 12px;
  box-shadow: var(--shadow);
  overflow: hidden; /* clip the full-bleed summary footer to the card's radius */
}
/* The empty state renders its own full panel inside the card shell. */
.enquiry-grid.is-empty .enquiry-basket-card {
  background: none;
  border: none;
  padding: 0;
  box-shadow: none;
}

.enquiry-basket-sub {
  font-size: 0.82rem;
  color: var(--muted);
  margin: 0.2rem 0 0;
}

/* Basket items: hairline-divided rows inside the one card (locked ReBond
   reference) — not nested card-in-card boxes. */
.basket-list {
  display: grid;
  gap: 0;
}

.basket-item {
  display: flex;
  align-items: center;
  gap: 1rem;
  background: none;
  border: none;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  padding: 16px 2px;
}
.basket-item:last-child { border-bottom: none; padding-bottom: 6px; }

.basket-item-thumb {
  width: 80px;
  height: 80px;
  flex-shrink: 0;
  background: var(--well);
  border: 1px solid var(--line);
  border-radius: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.65rem;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: #bcae95;
  position: relative;
  overflow: hidden;
  text-align: center;
  line-height: 1;
  padding: 0 4px;
}

.basket-item-thumb::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(45deg, transparent 0 8px, rgba(0,0,0,0.025) 8px 9px);
  pointer-events: none;
}

/* Real product photo inside the compact enquiry thumb. */
.basket-item-thumb img { width: 100%; height: 100%; object-fit: contain; padding: 4px; box-sizing: border-box; }
.basket-item-thumb:has(img) { background: #fff; }
.basket-item-thumb:has(img)::after { display: none; }
.basket-item-thumb .no-image-mark { font-size: 0.6rem; letter-spacing: 0.3px; padding: 0 3px; text-align: center; }

.basket-item-info { flex: 1; min-width: 0; }
.basket-item-info .basket-item-name {
  font-size: 0.95rem;
  font-weight: 700;
  margin-bottom: 0.15rem;
  color: var(--text);
  line-height: 1.3;
}
.basket-item-sub {
  display: block;
  font-size: 0.8rem;
  color: var(--muted);
  margin-bottom: 0.2rem;
}
.basket-item-brand {
  display: block;
  font-family: var(--mono);
  font-size: 0.64rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted-2);
}

/* Labelled remove button (trash icon + "Remove"). */
.basket-remove {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  padding: 0.5rem 0.85rem;
  cursor: pointer;
  flex-shrink: 0;
  min-height: 40px;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.basket-remove:hover {
  border-color: var(--red);
  color: var(--red);
  background: var(--red-tint);
}

.basket-remove:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

/* Total-products summary: one balanced horizontal strip, following the supplied
   reference's count-left / advisor-right hierarchy without copying its brand. */
.enquiry-total-band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 16px 0 0;
  min-height: 76px;
  padding: 12px 18px;
  background: #faf9f5;
  border: 1px solid var(--line);
  border-radius: 6px;
}
.enquiry-total-count-group {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  min-width: 0;
}
.enquiry-total-ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: var(--red-tint);
  color: var(--red);
  flex-shrink: 0;
}
.enquiry-total-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  line-height: 1.15;
}
.enquiry-total-text strong {   /* quiet label on top */
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: 0.005em;
}
.enquiry-total-text span {     /* count line: emphasised number + quiet unit */
  font-size: 0.86rem;
  font-weight: 500;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.enquiry-total-text span b {   /* the number itself carries the weight */
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--text);
  margin-right: 1px;
}
.enquiry-total-advice {
  margin-left: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  min-height: 48px;
  justify-content: center;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  border-radius: 5px;
  padding: 0.35rem 0.25rem 0.35rem 0.8rem;
  font-family: inherit;
  font-size: 0.76rem;
  color: var(--muted);
  text-align: right;
  cursor: pointer;
  transition: background 0.15s ease;
}
.enquiry-total-advice:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.enquiry-advice-helper { line-height: 1.3; }
.enquiry-advice-link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--red);
}
.enquiry-advice-link svg { transition: transform 0.18s ease; }
/* Hover affordance lives on the "Get Product Advice" link only, not the whole
   button: the old full red-tint wash covered both lines and read as an awkward
   slab. The button stays clickable everywhere, but only the link underlines and
   nudges its arrow. */
.enquiry-advice-link:hover { color: var(--red-hover); text-decoration: underline; text-underline-offset: 3px; }
.enquiry-advice-link:hover svg { transform: translateX(3px); }
@media (max-width: 640px) {
  .enquiry-total-band {
    flex-direction: column;
    align-items: stretch;
    gap: 0.7rem;
    padding: 14px;
  }
  .enquiry-total-advice {
    margin-left: 0;
    align-items: flex-start;
    text-align: left;
    width: 100%;
    padding: 0.7rem 0 0.15rem;
    border-top: 1px solid var(--line);
    border-radius: 0;
  }
}

/* Full-width, deliberate empty panel — generous vertical rhythm and a soft warm
   wash so it reads as an intentional state, not a lonely box in a sea of cream. */
.basket-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 4.5rem 2rem;
  color: var(--muted);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.basket-empty-icon {
  width: 68px;
  height: 68px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  border: 1px solid var(--line-2);
  box-shadow: 0 1px 3px rgba(32, 30, 24, 0.06);
  color: var(--red);
  margin-bottom: 1.35rem;
}

.basket-empty-icon svg { width: 30px; height: 30px; }

.basket-empty h2 {
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
  margin: 0 0 0.5rem;
}

.basket-empty p {
  font-size: 0.98rem;
  color: var(--body);
  line-height: 1.6;
  max-width: 44ch;
  margin: 0 0 1.75rem;
}

.basket-empty .btn { padding: 0.85rem 1.8rem; font-size: 0.95rem; }

/* Right-column sticky card: "Enquiring about" strip + padded form body. */
.enquiry-form {
  display: block;
  position: sticky;
  top: 84px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  box-shadow: var(--shadow);
}

.enquiry-form-body { padding: 24px; }

/* One deliberate spacing scale for the whole form: 0.45rem label-to-control,
   1.15rem between control groups, 1.4rem before the consent/action region —
   no one-off margins, no cramped Subject/Message/Notes stack. */
.enquiry-form-body > .form-group { margin-bottom: 1.15rem; }

.enquiry-form-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}
.enquiry-form-head h2 { font-size: 19px; margin: 0; }
.enquiry-required-note { font-size: 0.72rem; color: var(--muted); white-space: nowrap; }
.enquiry-form-sub {
  font-size: 0.82rem;
  color: var(--muted);
  margin: 0.25rem 0 1.35rem;
}

/* Security note under the form card. */
.enquiry-security-note {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 0.8rem 1rem;
  border-top: 1px solid var(--line);
  background: var(--panel);
  font-size: 0.76rem;
  color: var(--muted);
  margin: 0;
}
.enquiry-security-note svg { flex-shrink: 0; opacity: 0.75; }

.enquiry-submit-btn {
  width: 100%;
  padding: 13px;
  font-size: 15px;
  font-weight: 700;
  border-radius: 5px;
}

/* Privacy consent row above the submit action (locked ReBond reference). */
.form-check {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  margin: 1.4rem 0 0;
  font-size: 0.8rem;
  color: var(--body);
  line-height: 1.5;
  cursor: pointer;
}
.form-check input[type="checkbox"] {
  accent-color: var(--red);
  width: 15px;
  height: 15px;
  margin-top: 2px;
  flex-shrink: 0;
  cursor: pointer;
}
.form-check input[type="checkbox"]:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.form-check a { color: var(--red); text-decoration: none; font-weight: 600; }
.form-check a:hover { text-decoration: underline; text-underline-offset: 2px; }

/* Live character counter under the message / notes textareas. */
.ta-counter {
  align-self: flex-end;
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
  color: var(--muted-2);
  margin-top: 4px;
}

.enquiry-reassurance {
  font-size: 12px;
  color: var(--muted-2);
  text-align: center;
  line-height: 1.5;
  margin: 12px 0 0;
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.05rem;
  margin-bottom: 1.15rem;
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}

.form-group label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--body);
}

.form-group input,
.form-group textarea,
.form-group select {
  padding: 0.66rem 0.85rem;
  border: 1px solid #ded9cd;
  border-radius: 5px;
  font-size: 0.9rem;
  font-family: inherit;
  color: var(--text);
  background: #fff;
  outline: none;
  transition: border-color 0.18s, box-shadow 0.18s;
}

.form-group input,
.form-group select { min-height: 46px; }

.enquiry-form .form-group .custom-select-trigger { min-height: 46px; }
.enquiry-form .custom-select-trigger.is-placeholder .custom-select-trigger-label { color: #6a655a; }

.form-group input::placeholder,
.form-group textarea::placeholder {
  color: #6a655a;
}

.form-group input:hover,
.form-group textarea:hover,
.form-group select:hover {
  border-color: #c4bdac;
}

.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus {
  border-color: var(--red);
  box-shadow: 0 0 0 1px var(--red);
}

.form-group textarea { resize: vertical; min-height: 100px; }
/* Deliberate textarea hierarchy: the primary Message field is tallest. */
#eMessage { min-height: 120px; }

.form-submit { margin-top: 1.5rem; }

.confirmation {
  text-align: center;
  padding: 3rem;
  display: none;
}

.confirmation h2 { color: var(--text); font-size: 1.25rem; margin-bottom: 0.5rem; }
.confirmation .check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--red-tint);
  color: var(--red);
  font-size: 1.75rem;
  font-weight: 700;
  margin: 0 auto 1rem;
  border: 1px solid var(--red-tint-bdr);
}
.confirmation p { color: var(--muted); margin-bottom: 1.5rem; }

/* ─── Footer ──────────────────────────────────────────────────── */
.footer {
  background: var(--dark);
  color: #aaa;
  text-align: center;
  padding: 1.5rem;
  font-size: 0.85rem;
}

/* ─── Hamburger & Mobile Nav ──────────────────────────────────── */
.nav-right {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.nav-hamburger {
  display: none;
  background: none;
  border: none;
  color: #fff;
  font-size: 1.4rem;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
  line-height: 1;
}

.nav-mobile {
  background: var(--dark-2);
  display: none;
  flex-direction: column;
  padding: 0.75rem 2rem;
  gap: 0;
}

.nav-mobile.open { display: flex; }

.nav-mobile a {
  color: #ccc;
  text-decoration: none;
  font-size: 0.95rem;
  padding: 0.65rem 0;
  border-bottom: 1px solid #222;
  transition: color 0.2s;
}

.nav-mobile a:last-child { border-bottom: none; }
.nav-mobile a:hover { color: #fff; }

/* ─── Sort Dropdown ───────────────────────────────────────────── */
.sort-select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding: 0.55rem 2.25rem 0.55rem 0.95rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text);
  background-color: #fff;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23666666' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  cursor: pointer;
  font-family: inherit;
  outline: none;
  transition: border-color 0.18s, box-shadow 0.18s;
  line-height: 1.3;
}

.sort-select:hover { border-color: #c4bdac; }

.sort-select:focus,
.sort-select:focus-visible {
  border-color: var(--red);
  box-shadow: 0 0 0 1px var(--red);
}

/* ─── Active Filter Chips ─────────────────────────────────────── */
/* The active-filter state is shown ONCE per breakpoint (locked design):
   desktop = the "Active filters" block inside the filter sidebar; mobile =
   the compact #activeChips summary strip above the grid. */

/* Desktop sidebar block */
.sidebar-active {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  padding: 0.7rem 0.8rem;
  margin-bottom: 1rem;
}
.sidebar-active[hidden] { display: none; }
.sidebar-active-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-bottom: 0.55rem;
}
.sidebar-active-label {
  font-family: var(--mono);
  font-size: 0.64rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: var(--muted-2);
}
.sidebar-active-clear {
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--red);
  cursor: pointer;
  white-space: nowrap;
}
.sidebar-active-clear:hover { text-decoration: underline; text-underline-offset: 2px; }
.sidebar-active-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }

/* Retired from the product page entirely: the active filters already show
   inside the filter sheet, and the "Filters (n)" button + the "N of 31 found"
   count already signal an active filter — the on-page strip above the grid was
   redundant clutter. Kept in the DOM (JS still populates it) but never shown. */
.active-filter-bar { display: none !important; }

.active-filter-bar-inner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.7rem;
}

.active-filter-label {
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: #a49d90;
  white-space: nowrap;
}

.active-filter-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.active-filter-clear {
  margin-left: auto;
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.15s var(--ease);
}
.active-filter-clear:hover { color: var(--red); }

/* Active-filter chip: low-radius, quiet neutral at rest (an applied filter is
   normal state, not a warning). Hover shifts to red to signal removal. */
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.34rem;
  background: #fff;
  border: 1px solid var(--line-2);
  color: var(--body);
  font-size: 0.77rem;
  font-weight: 600;
  padding: 0.26rem 0.6rem;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.18s var(--ease), color 0.18s var(--ease), border-color 0.18s var(--ease);
  font-family: inherit;
}

.filter-chip:hover {
  background: var(--red);
  color: #fff;
  border-color: var(--red);
}

/* ─── No-Image Placeholder ────────────────────────────────────── */
.product-card-image.no-image {
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  position: relative;
}

.product-card-image.no-image::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle at 1px 1px, rgba(14,17,22,0.06) 1px, transparent 0);
  background-size: 16px 16px;
  pointer-events: none;
}

.no-image-mark {
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ink-3);
  line-height: 1;
  user-select: none;
  position: relative;
  z-index: 1;
}

/* ─── Admin Image Preview ─────────────────────────────────────── */
.image-preview-box {
  width: 100%;
  height: 110px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: 0.78rem;
  margin-top: 0.5rem;
  transition: border-color 0.2s;
}

.image-preview-box img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ─── Responsive ──────────────────────────────────────────────── */
@media (max-width: 1024px) {
  .product-grid { grid-template-columns: repeat(2, 1fr); }
  .related-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Sidebar → collapsible filter panel (opened by the "Refine Products" button)
   below 900px, matching the handoff's drawer breakpoint. The full slide-in
   drawer + mobile filter bar take over at ≤640 (the mobile-redesign block). */
@media (max-width: 900px) {
  .catalogue-layout { flex-direction: column; }
  .filter-toggle { display: flex; }
  .filter-sidebar {
    width: 100%;
    display: none;
    position: static;
    max-height: none;
    overflow: visible;
  }
  .filter-sidebar.open { display: block; }
}

@media (max-width: 768px) {
  .nav-links { display: none; }
  .nav-hamburger { display: block; }
  .catalogue-layout { padding: 0 1rem; }
  .active-filter-bar { padding: 0 1rem; }
  .product-grid { grid-template-columns: repeat(2, 1fr); }
  .related-grid { grid-template-columns: repeat(2, 1fr); }
  .form-row { grid-template-columns: 1fr; }
  .hero-inner { padding: 3rem 1.25rem 2.4rem; }
  .page-hero h1 { font-size: clamp(1.75rem, 7vw, 2.2rem); }
  .search-bar { margin-top: 1.5rem; }
}

/* ─── Detail Page: Gallery + Summary Row ────────────────────── */
/* Desktop: gallery and summary share ONE stretched grid row — both start at
   the same Y and end on the same baseline (the white gallery surface fills
   the full row height; the image inside stays contained and centred at its
   controlled scale). Mobile returns to natural stacked heights. */
.detail-top {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 2rem;
  max-width: 1180px;
  margin: 0.9rem auto 0;
  padding: 0 40px;
  align-items: stretch;
}

.detail-summary {
  display: flex;
  flex-direction: column;
}

@media (min-width: 769px) {
  #detailGallery { display: flex; flex-direction: column; }
  .gallery-wrap { flex: 1; height: 100%; }
  .gallery-wrap:not(.has-rail) { display: flex; }
  .gallery-wrap:not(.has-rail) .gallery-main {
    flex: 1;
    height: auto;
    aspect-ratio: auto;
    min-height: 300px; /* guard for unusually short summaries */
  }
  .gallery-wrap.has-rail { align-items: stretch; }
  .gallery-wrap.has-rail .gallery-main {
    height: 100%;
    aspect-ratio: auto;
    min-height: 300px;
  }
  .gallery-wrap.has-rail .gallery-rail { max-height: 100%; }
  /* The photo must never drive the row height (that would push the white
     surface past the summary): absolutely centred inside the stage, it keeps
     its contained scale caps while the SUMMARY column defines the shared
     bottom baseline. */
  .detail-top .gallery-stage { position: relative; }
  .detail-top .gallery-main img {
    position: absolute;
    inset: 0;
    margin: auto;
    max-width: 78%;
    max-height: 86%;
  }
}

/* ─── Three-tab container (Specifications / Application / Downloads) ──
   Shares the fold row's max-width and 40px inline padding so it lines up on
   the same left edge as the gallery/summary and the related grid below. The
   visible white/bordered "card" is split across .detail-tablist (top half)
   and the currently visible .detail-tabpanel (bottom half, only one is ever
   in flow at a time via [hidden]) so it fuses into one seamless container
   without needing an extra wrapper element around both. */
.detail-tabs {
  max-width: 1180px;
  margin: 1rem auto 0;
  padding: 0 40px;
}

.detail-tablist {
  display: flex;
  border: 1px solid var(--border);
  border-radius: 6px 6px 0 0;
  background: var(--card);
  overflow: hidden;
}

.detail-tab {
  flex: 1;
  background: none;
  border: none;
  padding: 0.75rem 1rem;
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--muted);
  border-bottom: 2.5px solid transparent;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}

.detail-tab:hover { color: var(--text); }

.detail-tab[aria-selected="true"] {
  color: var(--text);
  border-bottom-color: var(--red);
}

.detail-tab:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: -2px;
}

/* Content-driven height: the visible panel hugs its content ([hidden] keeps
   the others out of flow entirely) — no equal-height forcing anywhere. */
.detail-tabpanel {
  padding: 1.1rem 1.4rem 1.2rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-top: none;
  border-radius: 0 0 6px 6px;
}

/* Accordion heads: desktop drives the panels from the tablist, so these are
   hidden there and revealed only at ≤640px (see below). */
.detail-acc-head { display: none; }

@media (max-width: 640px) {
  /* ─── Mobile: tabs → stacked accordion ─────────────────────────
     A three-tab row with a label as long as "Application & Suitable Uses"
     can't sit on a phone width, so the panels restack as an independent
     accordion. .detail-tabs keeps its inline padding (the inset that lines
     it up with the gallery); the card is built from per-section borders so
     nothing has to fight that padding. */
  .detail-tablist { display: none; }

  .detail-section {
    background: var(--card);
    border: 1px solid var(--border);
    border-top: none;
  }
  .detail-section:first-of-type { border-top: 1px solid var(--border); border-radius: 8px 8px 0 0; }
  .detail-section:last-of-type  { border-radius: 0 0 8px 8px; }

  .detail-acc-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    width: 100%;
    padding: 0.95rem 1.1rem;
    background: none;
    border: none;
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text);
    text-align: left;
    cursor: pointer;
  }
  .detail-acc-head:focus-visible { outline: 2px solid var(--red); outline-offset: -2px; }
  .detail-acc-chev { flex-shrink: 0; color: var(--muted); transition: transform 0.2s ease; }
  .detail-section.is-open .detail-acc-chev { transform: rotate(180deg); }

  /* Panels are driven by the accordion's open state, not the desktop [hidden]
     attribute — the .is-open selector outranks the UA [hidden] rule. */
  .detail-tabpanel {
    display: none;
    border: none;
    border-radius: 0;
    padding: 0 1.1rem 1.15rem;
    background: transparent;
  }
  .detail-section.is-open .detail-tabpanel { display: block; }
}

/* ─── Gallery ────────────────────────────────────────────────── */
/* Locked reference layout: a vertical thumbnail rail beside the main image
   surface when a product has more than one real image; a full-width surface
   (no rail, no blank column) with a single image. The rail becomes a
   horizontal row UNDER the image at phone widths. */
.gallery-wrap { width: 100%; }

.gallery-wrap.has-rail {
  display: grid;
  grid-template-columns: 68px minmax(0, 1fr);
  gap: 0.6rem;
  align-items: start;
}

/* Soft-white plate (reference): the product shots carry their own white
   backgrounds, so a white surface makes them seamless. aspect-ratio keeps the
   photo compact and lets it scale with the column, no fixed heights. */
.gallery-main {
  position: relative;
  width: 100%;
  /* Controlled, realistic media proportion (locked reference): tall enough to
     balance the summary column, never a giant fixed height. */
  aspect-ratio: 1.72 / 1;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: default;
}

.gallery-stage {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.9rem;
  box-sizing: border-box;
}

/* Product shots sit cleanly inside the frame: contained, centred, no crop and
   no stretch. The caps keep extreme shapes sane — wide tins/guns never blow up
   to the full frame width, narrow bottles still stand tall. */
.gallery-main img {
  width: auto;
  height: auto;
  max-width: 82%;
  max-height: 92%;
  margin: auto;
  object-fit: contain;
  display: block;
}

.gallery-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  color: var(--muted);
  font-size: 0.78rem;
  letter-spacing: 0.3px;
  width: 100%;
  height: 100%;
}

.gallery-placeholder-brand {
  font-size: 3.5rem;
  font-weight: 800;
  letter-spacing: -1px;
  color: #cdc4b2;
  line-height: 1;
  user-select: none;
}

/* Vertical thumbnail rail (desktop). Scrolls quietly if a product ever has
   more real images than the main surface is tall. */
.gallery-rail {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  overflow-y: auto;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}

.gallery-thumb {
  width: 68px;
  height: 56px;
  background: #fff;
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  padding: 0;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.gallery-thumb:hover { border-color: #aaa; }
.gallery-thumb.active { border-color: var(--red); border-width: 2px; }
.gallery-thumb:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.gallery-thumb img { width: 100%; height: 100%; object-fit: contain; padding: 4px; box-sizing: border-box; }

/* Phones (locked mobile reference): main image first, real thumbnails as a
   horizontal row beneath it — never a vertical rail squeezed beside the image. */
@media (max-width: 768px) {
  .gallery-wrap.has-rail { grid-template-columns: minmax(0, 1fr); }
  .gallery-rail {
    order: 2;
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    padding-bottom: 2px;
  }
  .gallery-main { order: 1; }
}

@media (max-width: 560px) {
  .gallery-stage { padding: 0.75rem; }
  .gallery-thumb { width: 60px; height: 54px; }
}

/* ─── Product Header (brand mark, name, summary, availability) ───
   Locked design: boxed official brand mark, name, the ONE complete summary,
   then a restrained availability row (small dot + status + muted note —
   never a large green pill). */
.detail-product-header {
  margin-bottom: 0.85rem;
}

.detail-brand-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  border: 1px solid var(--red-tint-bdr);
  border-radius: 4px;
  padding: 3px 9px 3px 5px;
  margin-bottom: 0.6rem;
}
.detail-brand-chip .pcard-brand-name { color: var(--red); }
.detail-brand-chip.is-text {
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--muted-2);
  border-color: var(--line-2);
  padding: 4px 9px;
}

/* One meta row (B2B standard): the status leads, a thin divider, then the quiet
   advisory note as clear secondary info — hierarchy does the work, not a badge. */
.detail-avail-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 0.65rem;
}

.detail-avail {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.88rem;
  font-weight: 600;
}
.detail-avail.is-in  { color: var(--green); }
/* "Enquire to order" is not an error and not a dead product — amber reads as
   "ask us", where grey reads disabled and red reads unavailable. */
.detail-avail.is-out { color: #8a5a12; }

.detail-avail .avail-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}
.detail-avail.is-in .avail-dot { background: var(--green-dot); }

.detail-avail-sep {
  width: 1px;
  height: 12px;
  background: var(--border);
  flex-shrink: 0;
}

.detail-avail-note {
  font-size: 0.8rem;
  color: var(--muted);
}

/* On phones the note wraps to its own line under the status, which left the
   divider dangling after "Available" with nothing beside it. Drop the divider
   there and tighten the wrap gap so the status reads cleanly on its own row. */
@media (max-width: 640px) {
  .detail-avail-row { gap: 0.3rem 0.6rem; }
  .detail-avail-sep { display: none; }
}

/* Locked hierarchy: Space Grotesk display, ~32-36px on desktop, tight leading. */
.detail-product-name {
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  font-size: clamp(1.65rem, 2.6vw, 2.1rem);
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--text);
  line-height: 1.15;
  margin-bottom: 0.55rem;
}

.detail-product-desc {
  font-size: 0.95rem;
  color: var(--body);
  line-height: 1.55;
  max-width: 62ch;
}

/* ─── Spec rows (locked ReBond design) ──────────────────────────
   Compact two-column definition table built from truthful fields only:
   two balanced halves, label/value rows, thin dividers, aligned baselines.
   No pills, no chips, no checkmark clusters. */
.spec-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 3rem;
  margin: 0.15rem 0;
}

.spec-col { min-width: 0; }

.spec-row {
  display: grid;
  grid-template-columns: 168px minmax(0, 1fr);
  gap: 0 1rem;
  border-bottom: 1px solid var(--line);
  padding: 0.68rem 0;
}

.spec-col .spec-row:last-child { border-bottom: none; }

.spec-key {
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: -0.005em;
  color: var(--text);
  display: flex;
  gap: 0.5rem;
  /* Top-align the label with the first line of its value so multi-row values
     (Key Features) read as "label heading its rows". */
  align-items: flex-start;
}

/* Restrained red label icon (locked reference: small outline mark per row). */
.spec-ic {
  flex-shrink: 0;
  display: inline-flex;
  color: var(--red);
  margin-top: 0.12em;
}

.spec-val {
  font-size: 0.85rem;
  color: var(--body);
  line-height: 1.45;
  align-self: start;
}

@media (max-width: 768px) {
  /* One stacked column of label/value rows; the divider between the two
     halves collapses into the continuous row rhythm. */
  .spec-cols { grid-template-columns: 1fr; column-gap: 0; }
  .spec-col:first-child .spec-row:last-child { border-bottom: 1px solid var(--line); }
}

/* ─── Summary actions (locked design: one compact horizontal row) ────
   Add to Enquiry is the red primary; Compare and Talk to Yee Lim are
   coordinated secondary buttons beside it. Wraps responsively when the
   column narrows. */
.sidebar-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin-top: auto; /* anchor the buttons to the bottom so they align with the image */
}

/* One coordinated group (locked reference): equal ~46px heights, the red
   primary visually dominant, both secondaries white with dark labels. */
.sidebar-actions .detail-act-enq {
  flex: 1.4 1 auto;
  min-width: 170px;
  min-height: 2.85rem;
  font-size: 0.88rem;
}
.sidebar-actions .btn-compare-sidebar,
.sidebar-actions .btn-whatsapp-sidebar {
  white-space: nowrap;
  flex: 1 0 auto;
  min-height: 2.85rem;
  padding: 0.6rem 0.95rem;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--text);
}

/* WhatsApp quick-chat button — sits beside Compare in the action row. Green
   brand accent kept subtle so it never competes with the primary red CTA. */
.btn-whatsapp-sidebar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  flex: 1;
  min-width: 0;
  padding: 0.55rem;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s, transform 0.1s;
}

.btn-whatsapp-sidebar:hover { border-color: #16a34a; color: #128c3d; background: #f2faf4; }
.btn-whatsapp-sidebar:active { transform: scale(0.97); }
.btn-whatsapp-sidebar:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.btn-whatsapp-sidebar svg { flex-shrink: 0; color: #25D366; }

.sidebar-actions .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
}

/* Foot: just the honest availability note, sitting cleanly below the action
   row (the redundant "View Product Enquiry" link is gone — the navbar count
   already carries that path). */
.sidebar-foot {
  padding-top: 0.7rem;
  margin-top: 0.7rem;
  border-top: 1px solid var(--line);
}

/* Quiet info note under the actions (dot icon + honest availability copy). */
.sidebar-note {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  font-size: 0.78rem;
  color: var(--muted);
  text-align: left;
  line-height: 1.5;
}
.sidebar-note svg { flex-shrink: 0; margin-top: 2px; opacity: 0.75; }

.btn-compare-sidebar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  flex: 1;
  min-width: 0;
  padding: 0.55rem;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s, transform 0.1s;
  font-family: inherit;
}

.btn-compare-sidebar:hover { border-color: var(--red); color: var(--red); }
.btn-compare-sidebar.in-compare { border-color: var(--red); color: var(--red); background: #fff5f5; font-weight: 600; }
.btn-compare-sidebar:active { transform: scale(0.97); }

/* ─── Responsive — detail page ───────────────────────────────── */
@media (max-width: 768px) {
  /* Single column, gallery first (its natural DOM order), summary below.
     A taller ratio than desktop: the stacked column is narrower, so the
     landscape 1.9:1 well would leave the photo too small. Capped width keeps
     the stacked well from ballooning on tablets (no effect at phone widths,
     which are already narrower than the cap). */
  .detail-top { grid-template-columns: 1fr; }
  .gallery-wrap { max-width: 560px; margin: 0 auto; }
  .gallery-main { aspect-ratio: 4 / 3; }
}

/* Trim the shared 40px inline padding on smaller viewports so no section can
   push the page into horizontal overflow. */
@media (max-width: 768px) {
  .detail-top,
  .detail-tabs,
  #detailAdvice,
  .related-section { padding-left: 24px; padding-right: 24px; }
  .enquiry-guidance { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 560px) {
  .detail-top,
  .detail-tabs,
  #detailAdvice,
  .related-section { padding-left: 16px; padding-right: 16px; }
  .spec-row { grid-template-columns: 128px minmax(0, 1fr); }
}

@media (max-width: 430px) {
  .spec-row { grid-template-columns: 1fr; gap: 0.35rem; padding: 0.8rem 0; }
  .spec-val { padding-left: 22px; }
}

/* Phones: the in-flow action group duplicated the persistent sticky bar, so
   it's hidden here — the fixed bar at the bottom edge is the single action
   surface. The availability note + advice band still carry the summary's
   context below the description. */
@media (max-width: 640px) {
  .sidebar-actions { display: none; }
  /* With the inline actions hidden, the foot's top divider would sit as a stray
     line directly under the availability note — drop it (and its spacing) so the
     note flows straight into the "prefer to check first" line. */
  .sidebar-foot { border-top: none; padding-top: 0; margin-top: 0.35rem; }
}

/* ─── Compare Tray (subtle bottom trigger + on-demand panel) ─────
   Canyon-style interaction hierarchy in the Yee Lim language: with products
   selected, only a small centred white tab shows at the bottom edge —
   compare icon, "Compare (N)", chevron. The full-width slots/actions panel
   reveals only when the tab is deliberately expanded, and collapses back to
   the quiet tab. body.compare-open reserves the tray's live measured height
   (see updateCompareTrayHeight in compare.js). */
.compare-tray {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-compare-tray);
  display: flex;
  flex-direction: column;
  align-items: center;
  background: none;
  border: none;
  pointer-events: none; /* the trigger/panel re-enable their own hit areas */
  transform: translateY(110%);
  visibility: hidden; /* fully out of paint once the slide-out ends */
  transition: transform 0.26s var(--ease), visibility 0s linear 0.26s;
}
.compare-tray.visible {
  transform: translateY(0);
  visibility: visible;
  transition: transform 0.26s var(--ease), visibility 0s;
}
@media (prefers-reduced-motion: reduce) {
  .compare-tray,
  .compare-tray-panel,
  .compare-tray.is-expanded .compare-tray-panel,
  .compare-tray-inner { transition: none; }
}

/* The collapsed trigger tab: restrained white surface, hairline border,
   soft lift. Sits flush on the viewport bottom edge. */
.compare-tray-trigger {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.46rem;
  background: var(--card); /* SAME white surface token as .compare-tray-panel */
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: 5px 5px 0 0;
  min-height: 44px;
  min-width: 168px;
  padding: 0.62rem 1rem calc(0.62rem + env(safe-area-inset-bottom, 0px) / 2);
  font-family: inherit;
  font-size: 0.84rem;
  font-weight: 600;
  line-height: 1.1;
  color: var(--text);
  cursor: pointer;
  box-shadow: 0 -5px 16px -8px rgba(32, 30, 24, 0.15);
  transition: box-shadow 0.18s, border-color 0.18s;
}
/* Hover expresses interactivity through elevation only — NOT a warm fill.
   A darker/off-white tab beside the white panel read as two unrelated
   components (the reported mismatch); trigger and panel now share one white
   surface in every state, differing only by a subtle lift. */
.compare-tray-trigger:hover { box-shadow: 0 -7px 20px -8px rgba(32, 30, 24, 0.22); }
.compare-tray.is-expanded .compare-tray-trigger:hover { box-shadow: inset 0 2px 0 var(--red); }
.compare-tray-trigger:focus-visible { outline: 2px solid var(--red); outline-offset: -3px; }
.compare-tray-trigger svg { flex-shrink: 0; }
.compare-tray-trigger .ctt-ic { color: var(--red); }
.compare-tray-trigger #compareTrayCount {
  /* Sizes to the actual "(N)" now (no fixed 3ch box + centring left over from the
     old "(N/3)" format, which floated the number in too much space). */
  margin-left: -0.18rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.compare-tray-trigger .ctt-chev {
  color: var(--muted);
  transform-origin: center;
  transition: transform 0.2s var(--ease);
}
.compare-tray.is-expanded .compare-tray-trigger .ctt-chev { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .compare-tray-trigger .ctt-chev { transition: none; } }

/* Expanded panel: the familiar full-width drawer, revealed on demand.
   No hard border-top: a full-width hairline there pokes out on both sides of the
   centred trigger tab and reads as a stray horizontal seam. The panel's top edge
   is defined by a soft lift shadow instead, so the tab and the drawer read as one
   continuous white surface with no flanking line. */
.compare-tray-panel {
  pointer-events: auto;
  width: 100%;
  background: var(--card);
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  pointer-events: none;
  overflow: hidden;
  box-shadow: none;
  transition: grid-template-rows 0.24s var(--ease), box-shadow 0.2s ease,
    visibility 0s linear 0.24s;
}
.compare-tray.is-expanded .compare-tray-panel {
  grid-template-rows: 1fr;
  visibility: visible;
  pointer-events: auto;
  box-shadow: 0 -10px 30px -14px rgba(32, 30, 24, 0.2);
  transition: grid-template-rows 0.24s var(--ease), box-shadow 0.2s ease,
    visibility 0s;
}
/* Tab merges into the drawer when open — drop its own lift shadow so there is no
   doubled shadow where the two surfaces meet. */
.compare-tray.is-expanded .compare-tray-trigger { box-shadow: inset 0 2px 0 var(--red); }

.compare-tray-inner {
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  padding: 0 1.5rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  transition: padding-top 0.24s var(--ease), padding-bottom 0.24s var(--ease);
}
.compare-tray.is-expanded .compare-tray-inner {
  padding-top: 0.78rem;
  padding-bottom: calc(0.78rem + env(safe-area-inset-bottom, 0px));
}

.compare-tray-head {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  flex: 0 0 154px;
  padding-right: 0.25rem;
}
.compare-tray-title {
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.005em;
  white-space: nowrap;
}
.compare-tray-title #compareTrayFull { color: var(--muted); font-weight: 600; font-variant-numeric: tabular-nums; }
.compare-tray-sub { font-size: 0.72rem; color: var(--muted); white-space: nowrap; }

.compare-tray-slots {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  padding: 4px;
}

/* Selected slot and add-slot share one silhouette (same height, radius and
   inner rhythm) so the row reads as one component family. */
.cmp-slot {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1 0 180px;
  min-width: 180px;
  max-width: 220px;
  height: 60px;
  box-sizing: border-box;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.4rem 0.45rem 0.4rem 0.4rem;
  font-family: inherit;
}

.cmp-slot-img {
  width: 44px;
  height: 44px;
  border-radius: 4px;
  background: var(--well);
  border: 1px solid var(--border);
  flex-shrink: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.cmp-slot-img img { width: 100%; height: 100%; object-fit: contain; padding: 3px; box-sizing: border-box; }
.cmp-slot-img .no-image-mark { font-size: 0.55rem; font-weight: 700; letter-spacing: 0.3px; text-align: center; padding: 0 2px; color: var(--muted); }

.cmp-slot-name {
  flex: 1;
  min-width: 0;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text);
  line-height: 1.25;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  white-space: normal;
  overflow: hidden;
}

.cmp-slot-x {
  background: none;
  border: 1px solid transparent;
  color: var(--muted);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  cursor: pointer;
  padding: 0;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.cmp-slot-x:hover { border-color: var(--red-tint-bdr); color: var(--red); background: var(--red-tint); }

/* Dashed "add another product" slot, shown only while list.length < 3.
   Same height/radius as the filled slots so the row is one coherent system. */
.cmp-slot-add {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  height: 60px;
  box-sizing: border-box;
  background: transparent;
  border: 1px dashed var(--line-2);
  border-radius: var(--radius);
  padding: 0.4rem 0.9rem 0.4rem 0.6rem;
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  transition: border-color 0.15s, background 0.15s;
}
.cmp-slot-add:hover { border-color: var(--red); background: var(--red-tint); }
.cmp-slot-add-icon {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1px dashed var(--line-2);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--red);
  font-size: 0.95rem;
  line-height: 1;
}
.cmp-slot-add-text { display: flex; flex-direction: column; gap: 1px; }
.cmp-slot-add-text strong { font-size: 0.76rem; font-weight: 600; color: var(--text); }
.cmp-slot-add-text small { font-size: 0.68rem; color: var(--muted); }

.compare-tray-actions { display: flex; align-items: center; gap: 0.6rem; flex-shrink: 0; }

.compare-tray-clear {
  background: none;
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 5px;
  min-width: 92px;
  min-height: 44px;
  padding: 0.58rem 1rem;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
  transition: color 0.15s, border-color 0.15s;
}
.compare-tray-clear:hover { color: var(--red-dark); border-color: var(--red-tint-bdr); background: var(--red-tint); }

.compare-tray-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: var(--red);
  color: #fff;
  border: none;
  border-radius: 5px;
  min-width: 140px;
  min-height: 44px;
  justify-content: center;
  padding: 0.58rem 1.25rem;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, opacity 0.15s, transform 0.1s;
  font-family: inherit;
  white-space: nowrap;
}
.compare-tray-btn:disabled { background: #d8d3c9; color: #6f695f; opacity: 1; cursor: not-allowed; }
.compare-tray-btn:not(:disabled):hover { background: var(--red-dark); }
.compare-tray-btn:not(:disabled):active { transform: scale(0.97); }

/* Tablet band (641-860px): keep the slot row single-line by scrolling it
   horizontally rather than wrapping, so the head and actions stay pinned
   and the tray height is constant. Phones (<=640px) use the stacked
   layout below. */
@media (min-width: 641px) and (max-width: 860px) {
  .compare-tray-inner { gap: 0.75rem; }
}

/* Mobile compare: thumb-reachable bottom bar + modal detail sheet. */
@media (max-width: 640px) {
  /* COLLAPSED — a vertical side-tab pinned to the left edge (Canyon-style), so
     compare no longer stacks on top of / duplicates the bottom enquiry CTA.
     Tapping it opens the same modal comparison sheet below. */
  .compare-tray:not(.is-expanded) {
    top: auto;
    bottom: calc(92px + env(safe-area-inset-bottom, 0px));
    left: 0;
    right: auto;
    width: auto;
    align-items: flex-start;
    transform: translateX(-101%);
    transition: transform 0.32s cubic-bezier(0.23, 1, 0.32, 1), visibility 0s linear 0.32s;
  }
  .compare-tray.visible:not(.is-expanded) {
    transform: translateX(0);
    transition: transform 0.32s cubic-bezier(0.23, 1, 0.32, 1), visibility 0s;
  }
  .compare-tray:not(.is-expanded) .compare-tray-trigger {
    writing-mode: vertical-rl;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    width: auto;
    min-width: 0;
    min-height: 0;
    padding: 0.95rem 0.5rem;
    border: 1px solid var(--line-2);
    border-left: none;
    border-radius: 0 12px 12px 0;
    box-shadow: 4px 8px 20px -10px rgba(32, 30, 24, 0.5);
    font-size: 0.82rem;
    letter-spacing: 0.02em;
  }
  .compare-tray:not(.is-expanded) .compare-tray-trigger .ctt-ic { writing-mode: horizontal-tb; color: var(--red); }
  .compare-tray:not(.is-expanded) .compare-tray-trigger #compareTrayCount { margin: 0; min-width: 0; }
  .compare-tray:not(.is-expanded) .compare-tray-trigger .ctt-chev { display: none; }
  @media (prefers-reduced-motion: reduce) {
    .compare-tray:not(.is-expanded),
    .compare-tray.visible:not(.is-expanded) { transition: none; }
  }

  /* EXPANDED — bottom sheet, raised above the product-detail sticky CTA (900). */
  .compare-tray.is-expanded {
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    width: auto;
    transform: none;
    z-index: var(--z-compare-sheet);
  }
  .compare-tray.is-expanded .compare-tray-trigger { display: none; }
  .compare-tray.is-expanded .compare-tray-panel {
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -14px 34px -14px rgba(32, 30, 24, 0.34);
    max-height: min(88dvh, calc(100dvh - 24px));
    animation: cmpSheetUp 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
  }
  @keyframes cmpSheetUp { from { transform: translateY(22px); } to { transform: translateY(0); } }
  @media (prefers-reduced-motion: reduce) { .compare-tray.is-expanded .compare-tray-panel { animation: none; } }

  .compare-tray-inner {
    flex-wrap: wrap;
    padding: 0 1rem;
    gap: 0.65rem;
  }
  .compare-tray.is-expanded .compare-tray-inner {
    padding-top: 0.6rem;
    padding-bottom: calc(0.95rem + env(safe-area-inset-bottom, 0px));
    max-height: min(88dvh, calc(100dvh - 24px));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .compare-tray-head { flex: 1 1 auto; min-width: 0; }
  .compare-tray-slots {
    order: 3;
    flex-basis: 100%;
    width: 100%;
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.5rem;
    overflow: visible;
    padding: 0;
  }
  .compare-tray-slots .cmp-slot {
    width: 100%;
    min-width: 0;
    max-width: none;
    min-height: 64px;
  }
  .compare-tray-actions { order: 4; flex-basis: 100%; width: 100%; min-width: 0; gap: 0.6rem; }
  .compare-tray-clear,
  .compare-tray-btn { flex: 1 1 50%; justify-content: center; min-height: 48px; }

  /* Close control (injected by compare.js), top-right of the sheet header. */
  .compare-tray.is-expanded .cmp-sheet-close {
    display: inline-flex;
    order: 1;
    flex: 0 0 auto;
    margin-left: auto;
    align-self: flex-start;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    align-items: center;
    justify-content: center;
    background: var(--panel);
    border: 1px solid var(--border);
    color: var(--muted);
    cursor: pointer;
  }
  .compare-tray.is-expanded .cmp-sheet-close:hover { color: var(--text); border-color: var(--line-2); }
  .compare-tray.is-expanded .cmp-sheet-close:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

  /* Dimmed backdrop behind the sheet (injected by compare.js). */
  .cmp-sheet-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(16, 14, 10, 0.45);
    z-index: calc(var(--z-compare-sheet) - 1);
    animation: ylCompareBackdropIn 0.18s ease both;
  }
  @keyframes ylCompareBackdropIn { from { opacity: 0; } to { opacity: 1; } }
  @media (prefers-reduced-motion: reduce) {
    .cmp-sheet-backdrop,
    .compare-tray.is-expanded .compare-tray-panel { animation: none; }
  }
  /* While the sheet is open the product-detail sticky CTA must not poke through. */
  body.cmp-sheet-open .sticky-cta { visibility: hidden; }

  /* page-transitions.js gives #swup an opacity stacking context. Lift that
     context only while either modal sheet owns the page so its backdrop also
     intercepts the persistent navbar; picker/chat/progress layers stay above. */
  body.cmp-sheet-open #swup { position: relative; z-index: var(--z-compare-sheet); }
  body.filter-drawer-open #swup { position: relative; z-index: var(--z-filter-sheet); }

  /* The side-tab is left-anchored and clears the bottom CTA on its own, so it no
     longer needs to be lifted above the sticky bar the way the old bottom bar did. */
  body.filter-drawer-open .compare-tray { visibility: hidden; }
}

/* The injected close control is hidden everywhere except the mobile expanded
   sheet (rule above). */
.cmp-sheet-close { display: none; }

/* ─── Compare picker (dedicated add-product flow) ─────────────────
   Slide-in side panel opened from the compare tray's / compare page's
   "Add a product" slot. Canyon-inspired interaction model (segmented
   Recently viewed / All products + search + direct add) rendered in the
   Yee Lim language: white surface, warm hairlines, restrained red. */
.cmp-picker-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(16, 14, 10, 0.5);
  z-index: var(--z-picker-backdrop);
  animation: ylPickerFade 0.2s ease both;
}
@keyframes ylPickerFade { from { opacity: 0; } to { opacity: 1; } }
.cmp-picker {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(430px, 100%);
  background: #fff;
  border-left: 1px solid var(--line);
  box-shadow: -18px 0 44px -22px rgba(16, 14, 10, 0.4);
  z-index: var(--z-picker);
  display: flex;
  flex-direction: column;
  animation: ylPickerIn 0.28s var(--ease) both;
}
@keyframes ylPickerIn { from { transform: translateX(40px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .cmp-picker,
  .cmp-picker-backdrop { animation: none; }
}

.cmp-picker-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1.05rem 1.25rem 0.8rem;
  border-bottom: 1px solid var(--line);
}
.cmp-picker-eyebrow {
  display: block;
  font-family: var(--mono);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-2);
  margin-bottom: 0.3rem;
}
.cmp-picker-title {
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
  margin: 0;
}
.cmp-picker-count {
  font-size: 0.78rem;
  color: var(--muted);
  margin-top: 0.25rem;
  display: block;
}
.cmp-picker-x {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}
.cmp-picker-x:hover { color: var(--text); border-color: var(--muted); }
.cmp-picker-x:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

.cmp-picker-tools { padding: 0.85rem 1.25rem 0.75rem; border-bottom: 1px solid var(--line); }
/* Quiet segmented control: a soft inset track with a white raised chip for
   the selected segment — clear, but integrated (never an oversized dark
   pill competing with the actual actions). */
.cmp-picker-tabs {
  display: flex;
  width: 100%;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 3px;
  gap: 3px;
  margin-bottom: 0.8rem;
}
.cmp-picker-tab {
  flex: 1;
  min-height: 44px;
  background: transparent;
  border: none;
  border-radius: 3px;
  padding: 0.42rem 0.75rem;
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s, box-shadow 0.15s;
}
.cmp-picker-tab:hover { color: var(--text); }
.cmp-picker-tab[aria-pressed="true"] {
  background: #fff;
  color: var(--text);
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(32, 30, 24, 0.12), inset 0 0 0 1px var(--line-2);
}
.cmp-picker-tab:focus-visible { outline: 2px solid var(--red); outline-offset: -2px; }

.cmp-picker-search {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  border: 1px solid var(--line-2);
  border-radius: 5px;
  background: #fff;
  padding: 0 0.7rem;
}
.cmp-picker-search svg { color: var(--muted); flex-shrink: 0; }
.cmp-picker-search input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: none;
  font-family: inherit;
  font-size: 0.88rem;
  color: var(--text);
  padding: 0.55rem 0;
}
.cmp-picker-search:focus-within { border-color: var(--red); box-shadow: 0 0 0 1px var(--red); }

.cmp-picker-list {
  flex: 1;
  overflow-y: auto;
  padding: 0.5rem 0.75rem 0.9rem;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.cmp-picker-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  width: 100%;
  padding: 0.6rem 0.5rem;
  border-bottom: 1px solid var(--line);
  transition: background 0.12s;
}
.cmp-picker-row:hover { background: var(--panel); }
.cmp-picker-row:last-child { border-bottom: none; }
.cmp-picker-thumb {
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.cmp-picker-thumb img { width: 100%; height: 100%; object-fit: contain; padding: 3px; box-sizing: border-box; }
.cmp-picker-thumb .no-image-mark { font-size: 0.5rem; font-weight: 700; color: var(--muted-2); text-align: center; padding: 0 2px; }
.cmp-picker-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.cmp-picker-name {
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cmp-picker-sub { font-size: 0.72rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cmp-picker-add {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  gap: 0.3rem;
  background: #fff;
  border: 1px solid var(--red);
  border-radius: 4px;
  color: var(--red);
  font-family: inherit;
  font-size: 0.76rem;
  font-weight: 600;
  padding: 0.4rem 0.7rem;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.cmp-picker-add:hover { background: var(--red); color: #fff; }
.cmp-picker-add.is-added { background: var(--red-tint); border-color: var(--red-tint-bdr); color: var(--red); }
.cmp-picker-add:disabled { border-color: var(--line-2); color: var(--muted-2); background: #fff; cursor: not-allowed; }
.cmp-picker-add:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.cmp-picker-empty { padding: 1.5rem 1rem; text-align: center; color: var(--muted); font-size: 0.85rem; }

/* Designed Recently-viewed empty state: the segment stays clickable and this
   explains it, with a real route on to All products. */
.cmp-picker-empty-recent {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 2.4rem 1.5rem;
}
.cmp-picker-empty-ic {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--panel-2);
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 0.8rem;
}
.cmp-picker-empty-recent h3 {
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  font-size: 0.98rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
  margin: 0 0 0.3rem;
}
.cmp-picker-empty-recent p {
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.5;
  margin: 0 0 1.1rem;
  max-width: 30ch;
}
.cmp-picker-browse {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  gap: 0.35rem;
  background: #fff;
  border: 1px solid var(--red);
  border-radius: 4px;
  color: var(--red);
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0.5rem 0.95rem;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.cmp-picker-browse:hover { background: var(--red); color: #fff; }
.cmp-picker-browse:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

@media (max-width: 560px) {
  .cmp-picker { width: 100%; border-left: none; }
}

/* ─── Comparison overlay removed; comparison now uses dedicated compare.html page ─── */

.compare-table { width: 100%; border-collapse: collapse; table-layout: fixed; }

.compare-label-col { width: 180px; min-width: 180px; }

.compare-col-header {
  padding: 1.5rem 1.25rem 1.25rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
  height: 100%; /* fill the row so .compare-col-inner can stretch to equal height */
}

/* Equal-height columns: each product is a full-height flex stack so the CTA can
   be pinned to the bottom regardless of how tall the name/availability above is,
   keeping every "Add to Product Enquiry" button on the same baseline. */
.compare-col-inner {
  display: flex;
  flex-direction: column;
  height: 100%;
}

/* No decorative image card: the product photo sits directly on the clean white
   product column (editorial reference direction) — no border, radius, fill or
   shadow. Controlled whitespace comes from the aspect box + object-fit:contain. */
.compare-product-img {
  width: 100%;
  aspect-ratio: 4/3;
  max-height: 200px;
  margin-bottom: 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  /* Query container so the brand monogram below can size to THIS column's
     width (cqi), not the viewport. Column width depends on how many products
     are compared, so vw-based sizing overflowed narrow 3-4 col layouts. */
  container-type: inline-size;
}

.compare-product-img img { width: 100%; height: 100%; object-fit: contain; box-sizing: border-box; }

.compare-product-name {
  font-size: 1rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 0.2rem;
  line-height: 1.3;
}

/* Red mono brand line above the name (locked design). */
.compare-product-brand {
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 0.3rem;
}

/* The in-table × remove control was removed: product removal lives in the top
   selection panel (.csel-x) so the destructive action is not duplicated in the
   table header. The image now sits cleanly on the white column. */

/* Attribute (label) column: WHITE like the product columns so the whole
   table reads as one integrated surface (locked full-design reference). The
   rail is distinguished by typography, its red icons and a subtle stronger
   right rule — never a separate beige block. */
.compare-row-label {
  padding: 0.875rem 1rem 0.875rem 1.25rem;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: -0.005em;
  color: var(--text);
  background: var(--card);
  border-top: 1px solid var(--line);
  border-right: 1px solid var(--line-2);
  white-space: normal;
  vertical-align: middle;
  /* Sticky first column (also the thead "Product" corner cell, which shares
     this class): stays pinned and readable while the table scrolls
     horizontally inside .cx-scroll on narrow viewports. */
  position: sticky;
  left: 0;
  z-index: 2;
}

/* Corner "PRODUCT" cell keeps the quiet mono-caps eyebrow treatment. */
.compare-corner {
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted-2);
}

.compare-row-value {
  padding: 0.875rem 1.25rem;
  font-size: 0.85rem;
  color: var(--text);
  border-top: 1px solid var(--line);
  vertical-align: top;
  line-height: 1.55;
}

/* Thin vertical rules between product columns so each product reads as its
   own scannable rail (labels column supplies the first rule itself). */
.compare-row-value + .compare-row-value,
.compare-col-header + .compare-col-header { border-left: 1px solid var(--line); }

@media (max-width: 480px) {
  .compare-col-header { padding: 1rem 0.4rem 0.75rem; }
}

/* ─── Comparison Page ────────────────────────────────────────── */
/* No band divider under the intro (locked ReBond reference): the heading
   flows straight into the white selection panel below. */
.compare-page-top {
  max-width: 1280px;
  margin: 0 auto;
  padding: 1.4rem 1.5rem 0.35rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.compare-page-top .breadcrumb {
  margin: 0 0 0.15rem;
  max-width: none;
  padding: 0;
}

.compare-page-lead {
  margin: 0;
  font-size: 0.92rem;
  color: var(--muted);
  line-height: 1.5;
}

/* ─── Selection panel ("Products to compare (n/3)") ─────────────
   Sits above the comparison table: one card per selected product, a
   dashed add-slot while under COMPARE_MAX, and the grouped actions.
   Mirrors the bottom .compare-tray drawer's cmp-slot pattern. ──── */
/* Inset white panel: always keeps left/right breathing room inside the page
   (width cap + viewport margin), never touching the viewport edges. */
.compare-select-panel {
  width: min(1280px - 3rem, calc(100% - 3rem));
  margin: 1.1rem auto 0;
  padding: 1.25rem 1.5rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: var(--shadow);
}
.compare-select-panel[hidden] { display: none; }

/* Remove-× on each comparison table column header. Hidden on desktop + landscape
   (the selection panel carries removal there); revealed on portrait phones where
   that panel is hidden, so the table stays self-managing (see ≤640 block). */
.compare-col-x { display: none; }

/* ── Flip-to-landscape hint (compare page, mobile portrait) ──────
   Injected/removed by compare-page.js: modal, dismissible, one-time per session,
   and never a blocker (the table is still swipeable in portrait). */
.cmp-rotate {
  position: fixed;
  inset: 0;
  z-index: 1100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}
.cmp-rotate-backdrop { position: absolute; inset: 0; background: rgba(16, 14, 10, 0.5); }
.cmp-rotate-card {
  position: relative;
  width: 100%;
  max-width: 340px;
  background: var(--card);
  border-radius: 18px;
  padding: 2rem 1.5rem 1.6rem;
  text-align: center;
  box-shadow: 0 26px 64px -22px rgba(0, 0, 0, 0.55);
  animation: cmpRotateIn 0.24s cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes cmpRotateIn { from { opacity: 0; transform: translateY(12px) scale(0.98); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .cmp-rotate-card { animation: none; } }
.cmp-rotate-x {
  position: absolute;
  top: 0.7rem;
  right: 0.7rem;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.cmp-rotate-x:hover { color: var(--text); border-color: var(--line-2); }
.cmp-rotate-ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 74px;
  height: 74px;
  border-radius: 20px;
  background: var(--red-tint);
  color: var(--red);
  margin-bottom: 1rem;
}
.cmp-rotate-title {
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  font-size: 1.28rem;
  font-weight: 700;
  color: var(--text);
  margin: 0 0 0.5rem;
}
.cmp-rotate-text { font-size: 0.9rem; color: var(--muted); line-height: 1.55; margin: 0 0 1.25rem; }
.cmp-rotate-ok { width: 100%; justify-content: center; min-height: 48px; }
body.cmp-rotate-open { overflow: hidden; }

.csel-head {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--muted);
  margin-bottom: 0.85rem;
}

/* Tiles left, grouped actions right (desktop); stacks on mobile. */
.csel-body {
  display: flex;
  align-items: stretch;
  gap: 1.25rem;
}

.csel-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.9rem;
  flex: 1;
  min-width: 0;
}

.csel-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-height: 76px;
  box-sizing: border-box;
  padding: 0.6rem 1.85rem 0.6rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: #fff;
}

.csel-img {
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  border-radius: 7px;
  overflow: hidden;
  background: var(--card);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
}
.csel-img img { width: 100%; height: 100%; object-fit: contain; padding: 3px; box-sizing: border-box; }
.csel-img .no-image-mark { font-size: 0.55rem; font-weight: 700; letter-spacing: 0.3px; text-align: center; padding: 0 2px; color: var(--muted); }

.csel-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.csel-brand {
  font-family: var(--mono);
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--red);
}

.csel-name {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--text);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.csel-sub {
  font-size: 0.7rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.csel-x {
  position: absolute;
  top: 0.45rem;
  right: 0.45rem;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 50%;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}
.csel-x:hover { color: var(--red); border-color: var(--red-tint-bdr); }
.csel-x:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

.csel-add {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  min-height: 76px;
  box-sizing: border-box;
  padding: 0.6rem 0.75rem;
  background: none;
  font-family: inherit;
  cursor: pointer;
  border: 1px dashed var(--line-2);
  border-radius: 5px;
  text-decoration: none;
  text-align: center;
  transition: border-color 0.15s, background 0.15s;
}
.csel-add:hover { border-color: var(--red); background: var(--red-tint); }
.csel-add:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.csel-add-icon {
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--bg);
  color: var(--red);
  font-size: 1.1rem;
  font-weight: 700;
  line-height: 1;
}
.csel-add-text { display: flex; flex-direction: column; gap: 1px; }
.csel-add-text strong { font-size: 0.78rem; font-weight: 600; color: var(--text); }
.csel-add-text small { font-size: 0.68rem; color: var(--muted); }

.csel-actions {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.6rem;
  flex-shrink: 0;
  border-left: 1px solid var(--line);
  padding-left: 1.25rem;
  min-width: 168px;
}
.csel-compare { text-decoration: none; justify-content: center; }
.csel-actions .compare-page-clear {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 0.55rem 0.75rem;
}

@media (max-width: 640px) {
  .csel-body { flex-direction: column; gap: 0.9rem; }
  .csel-row { grid-template-columns: 1fr; }
  /* Hidden on portrait phones: it duplicates the table columns and eats scarce
     height. It returns in landscape (wider than 640px); the column × below keeps
     removal available in portrait. */
  .compare-select-panel { display: none; }
  .compare-col-inner { position: relative; }
  .compare-col-x {
    display: inline-flex;
    position: absolute;
    top: 4px;
    right: 4px;
    width: 26px;
    height: 26px;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 1px solid var(--line-2);
    background: var(--card);
    color: var(--muted);
    cursor: pointer;
    z-index: 1;
  }
  .csel-card { min-height: 80px; padding-right: 3.35rem; }
  .csel-x {
    top: 50%;
    right: 0.35rem;
    width: 44px;
    height: 44px;
    transform: translateY(-50%);
  }
  .csel-actions {
    flex-direction: row-reverse;
    border-left: none;
    padding-left: 0;
    min-width: 0;
  }
  .csel-actions .compare-page-clear,
  .csel-actions .csel-compare { flex: 1 1 50%; justify-content: center; min-height: 46px; }

  .compare-label-col { width: 132px; min-width: 132px; }
  .compare-row-label { padding: 0.78rem 0.65rem; font-size: 0.78rem; }
  .compare-row-value { padding: 0.78rem 0.9rem; }
  .compare-page-body { padding: 0 12px; }
}

.compare-img-placeholder {
  font-size: clamp(0.85rem, 26cqi, 2.5rem);
  font-weight: 800;
  letter-spacing: -1px;
  color: #cdc4b2;
  user-select: none;
  line-height: 1;
  max-width: 100%;
  padding: 0 0.5rem;
  box-sizing: border-box;
  text-align: center;
  overflow-wrap: break-word;
}

.compare-img-placeholder-sub {
  font-size: 0.72rem;
  color: #bbb;
  margin-top: 0.4rem;
  letter-spacing: 0.3px;
}

/* When a product photo fails to load in the compare grid, ylImageFallback()
   drops a .no-image-mark monogram into this column. The base mark is a fixed
   1.5rem with no width cap, so a long brand word (e.g. "HORSEMEN") overflows
   the narrow column and clips. Scope it to scale with the column instead. */
.compare-product-img .no-image-mark {
  font-size: clamp(0.8rem, 18cqi, 1.5rem);
  max-width: 100%;
  padding: 0 0.5rem;
  box-sizing: border-box;
  text-align: center;
  overflow-wrap: break-word;
}

.compare-page-clear {
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.35rem 0.75rem;
  font-size: 0.82rem;
  color: var(--muted);
  cursor: pointer;
  font-family: inherit;
  transition: border-color 0.15s, color 0.15s;
  white-space: nowrap;
}

.compare-page-clear:hover {
  border-color: var(--red);
  color: var(--red);
}

.compare-page-body {
  max-width: 1280px;
  margin: 1rem auto 3rem;
  padding: 0 1.5rem;
}

.compare-page-table-wrap {
  overflow-x: auto;
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: 0 1px 3px rgba(0,0,0,0.06);
}

/* Scroll container for the comparison table at every breakpoint (shares the
   element with .compare-page-table-wrap above). The sticky .compare-row-label
   column below keeps row labels in view while the rest scrolls horizontally. */
.cx-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.compare-page-table-wrap .compare-table { border-radius: var(--radius); }

/* Each product column's readable min-width (~220px) is set inline per render
   (compare-page.js), scaled to the product count, so the table forces the
   .cx-scroll wrapper to scroll horizontally on narrow screens instead of
   crushing columns flat. The scroll is contained in the wrapper, so the
   page itself never overflows. */

.compare-product-name {
  font-size: 1rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 0.2rem;
  line-height: 1.3;
  text-decoration: none;
  /* Clamp to two lines and reserve that height, so a 1-line and a 2-line name
     take the same vertical space and the rows below them stay aligned. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.6em; /* 2 lines at line-height 1.3 */
}

.compare-product-name:hover { color: var(--red); }

/* Truthful subtype under the product name in the table header cells. */
.compare-product-sub {
  font-size: 0.78rem;
  color: var(--muted);
  margin-top: 0.15rem;
}

/* Row-label icon + red check circles + em-dash empty values (locked design). */
.compare-label-wrap {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
}
.compare-label-wrap > span:last-child { min-width: 0; }

.compare-label-ic {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--red);
  margin-top: 0.1em;
}

.compare-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  border: 1.5px solid var(--red);
  color: var(--red);
  margin-right: 0.5rem;
  flex-shrink: 0;
}
.compare-feature {
  display: flex;
  align-items: center;
  padding: 0.2rem 0;
  font-size: 0.85rem;
}

.compare-empty-val { color: var(--muted-2); }

.compare-disclaimer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  margin: 1.1rem 0 0;
  font-size: 0.8rem;
  color: var(--muted);
  text-align: center;
}
.compare-disclaimer svg { flex-shrink: 0; opacity: 0.7; }

/* ─── Focus states ───────────────────────────────────────────── */
.gallery-thumb:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

.btn-compare-sidebar:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

.compare-tray-btn:focus-visible,
.compare-tray-clear:focus-visible,
.compare-tray-collapse:focus-visible,
.cmp-slot-x:focus-visible,
.cmp-slot-add:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

/* ─── Toast offset when compare tray is open ─────────────────── */
body:has(.compare-tray.visible) .toast {
  bottom: calc(var(--compare-tray-height) + 1.5rem);
  transition: bottom 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

/* ════════════════════════════════════════════════════════════════
   SPRINT 2 ADDITIONS — filter counts, skeleton
   ════════════════════════════════════════════════════════════════ */

/* ─── Filter checkbox: label + count ─────────────────────────── */
.filter-group label {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.875rem;
  color: var(--text);
  /* Consistent row height + inset so the whole-row hover reads as a rounded pill.
     min-height keeps each row an easy click target (FILTER-001). */
  padding: 0.42rem 0.5rem;
  min-height: 38px;
  border-radius: 6px;
  margin-bottom: 2px;
  cursor: pointer;
  line-height: 1.3;
  transition: background 0.14s ease, color 0.14s ease;
}
.filter-group label:last-child { margin-bottom: 0; }

/* "Show more" for long groups + the heading's active-total chip (FILTER-001) */
.fg-more-btn {
  display: block;
  background: none;
  border: none;
  padding: 0.4rem 0.5rem;
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--red);
  cursor: pointer;
  border-radius: 6px;
}
.fg-more-btn:hover { background: var(--red-tint); }
.fg-more-btn:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
/* Short desktop viewports: a tiny nested scroll area is worse than letting the
   page scroll the sidebar naturally (FILTER-001 fallback). */
@media (min-width: 769px) and (max-height: 620px) {
  .filter-sidebar { position: static; max-height: none; }
  .filter-sidebar .drawer-body { overflow-y: visible; max-height: none; }
}

/* Whole-row hover (the row is a <label>, so clicking anywhere toggles it). */
.filter-group label:hover:not(.is-empty) { background: var(--well); }

/* Applied row: faint warm tint (never a dark fill), heavier label. Rows keep
   a small margin-bottom (above) so two adjacent checked rows never merge
   into one block. */
.filter-group label:has(input:checked) { background: var(--red-tint); }
/* Hover on an already-checked row must not flip it back to the neutral hover
   fill (0,3,2 beats the plain :hover rule's 0,3,1). */
.filter-group label:hover:has(input:checked) { background: var(--red-tint); }
.filter-group label:has(input:checked) .filter-label-text {
  color: var(--text);
  font-weight: 600;
}

/* Keyboard focus lands on the checkbox — keep it clearly visible. */
.filter-group input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

.filter-group label.is-empty {
  opacity: 0.4;
  cursor: not-allowed;
}

.filter-label-text {
  font-size: 0.875rem;
}

.filter-count {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  min-width: 18px;
  text-align: right;
  padding-right: 2px;
}

.filter-group label:hover:not(.is-empty) .filter-count {
  color: var(--body);
}

/* Checked rows emphasise the count with ink weight, not red — red here read as
   an alert/"unavailable" badge rather than a neutral availability tally. */
.filter-group label input:checked ~ .filter-count {
  color: var(--text);
  font-weight: 700;
}

/* ─── Skeleton loading state for product grid ────────────────── */
@keyframes shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position: 400px 0; }
}

.skeleton-card {
  pointer-events: none;
}

.skeleton-card::before {
  display: none;
}

.skeleton-img,
.skeleton-line {
  background: linear-gradient(90deg, #edebe3 0%, #e1ded4 50%, #edebe3 100%);
  background-size: 800px 100%;
  animation: shimmer 1.4s linear infinite;
  border-radius: 4px;
}

.skeleton-img {
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: 0;
}

.skeleton-line {
  height: 12px;
  margin-bottom: 0.6rem;
}

.skeleton-line-short { width: 35%; height: 14px; margin-bottom: 0.75rem; }
.skeleton-line-title { width: 80%; height: 16px; margin-bottom: 0.6rem; }
.skeleton-line-mid   { width: 60%; }

.detail-gallery-skeleton {
  aspect-ratio: 1.72 / 1;
  border-radius: 6px;
}
.detail-skeleton-summary { max-width: 520px; min-height: 360px; padding-top: 0.4rem; }

.compare-page-body.is-loading { min-height: 70dvh; }
.csel-skeleton .csel-img { margin: 0; border: 0; }
.csel-skeleton .csel-text { width: 100%; }
.csel-skeleton .skeleton-line { margin-bottom: 0.35rem; }
.csel-skeleton-actions .skeleton-line { width: 100%; height: 42px; margin: 0; }

@media (max-width: 768px) {
  .detail-gallery-skeleton { aspect-ratio: 4 / 3; }
  .detail-skeleton-summary { min-height: 550px; }
}

@media (min-width: 769px) and (max-width: 1100px) {
  .detail-skeleton-summary { min-height: 440px; }
}

html[data-compare-count="1"] #compareSelectPanel:empty,
html[data-compare-count="2"] #compareSelectPanel:empty,
html[data-compare-count="3"] #compareSelectPanel:empty { min-height: 155px; }

@media (max-width: 640px) {
  html[data-compare-count="1"] #compareSelectPanel:empty { min-height: 302px; }
  html[data-compare-count="2"] #compareSelectPanel:empty { min-height: 397px; }
  html[data-compare-count="3"] #compareSelectPanel:empty { min-height: 395px; }
}

.skeleton-card .product-card-body {
  padding: 1rem;
}

/* ─── Grid meta tweaks ─────────────────────────────────────────── */
.grid-meta {
  font-weight: 500;
}

#resultCount {
  font-size: 0.95rem;
  color: var(--text);
}
#resultCount strong { font-weight: 700; }

/* The "of N" narrowing and the count-row "Clear all" are mobile-only affordances
   (styled in the ≤640px block); hidden on desktop so the desktop count/sort row
   stays exactly as it was. */
.rc-of { display: none; }
.grid-clear-all { display: none; }

/* Slight breadcrumb hierarchy tightening */
.page-breadcrumb {
  font-size: 0.82rem;
  margin-top: 1rem;
  color: var(--muted);
}

.page-breadcrumb a { color: var(--muted); font-weight: 500; }
.page-breadcrumb a:hover { color: var(--red); }
.page-breadcrumb span[aria-hidden] { margin: 0 0.4rem; opacity: 0.5; }
/* Mobile: drop the "Home ›" step so the trail reads "Products › <product>" —
   cleaner and easier to scan on a phone. Desktop keeps the full hierarchy. */
@media (max-width: 640px) {
  .page-breadcrumb .bc-home,
  .page-breadcrumb .bc-sep-home { display: none; }
}

/* Enquiry grid: collapse to one column, form drops below the product list,
   sticky positioning is meaningless once stacked so it's turned off. */
@media (max-width: 900px) {
  .enquiry-grid { grid-template-columns: 1fr; }
  .enquiry-form { position: static; }
  .enquiry-form-body .form-row { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
  .page-content { padding: 28px 1.25rem 48px; }
  .basket-item {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr) 44px;
    gap: 0.75rem;
  }
  .basket-item-thumb { width: 64px; height: 64px; }
  .basket-remove {
    width: 44px;
    height: 44px;
    min-height: 44px;
    padding: 0;
    justify-content: center;
  }
  .basket-remove span { display: none; }
}

@media (max-width: 480px) {
  .basket-item-thumb { width: 64px; height: 64px; }
  .enquiry-col-head { flex-wrap: wrap; gap: 8px; }
}

/* ─── Compare page polish ─────────────────────────────────────── */
.compare-page-top h1 {
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--text);
  margin: 0;
  line-height: 1.2;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ════════════════════════════════════════════════════════════════
   CONTACT PAGE ADDITIONS
   ════════════════════════════════════════════════════════════════ */


/* ─── 404 Page (standalone one-screen recovery) ─────────────────
   Focused recovery page: minimal branded top bar (no full site nav), warm
   hero with the back CTA + product search, and the "Helpful places to go"
   cards. No footer/copyright row and fluid vertical spacing, so the whole
   page fits within 100dvh at desktop sizes (1024×768 up) without a
   scrollbar. Phones/short viewports scroll naturally — nothing is clipped. */
.nf-body {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg); /* fill the viewport so the dark html fallback never shows */
}
/* main is a flex column: the hero band stays at the top with its image, and the
   helpful-places section grows to fill the space beneath it and centres its
   content — so the leftover space is shared above and below the cards instead of
   all collecting under them (the reported top-heavy distribution). */
.nf-body main { flex: 1; display: flex; flex-direction: column; }
.nf-hero { flex-shrink: 0; }

.nf-topbar {
  background: var(--dark);
  height: 56px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  padding: 0 2rem;
}
.nf-topbar a { display: inline-flex; align-items: center; }
.nf-topbar img { height: 34px; width: auto; display: block; }
.nf-topbar a:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

.nf-hero .hero-eyebrow { color: var(--red); }
.nf-hero h1 { max-width: 20ch; }
/* Fluid hero padding: compresses on shorter desktop viewports (768-800px
   tall) instead of pushing the page past one screen. */
.nf-hero .page-hero-inner {
  padding-top: clamp(1.4rem, 4vh, 2.4rem);
  padding-bottom: clamp(1.3rem, 3.8vh, 2.3rem);
}

.nf-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: clamp(0.9rem, 2.4vh, 1.5rem);
}
.nf-actions .btn { padding: 0.72rem 1.4rem; font-size: 0.92rem; }

.nf-search { margin-top: clamp(0.7rem, 1.8vh, 1rem); max-width: 560px; }

.nf-help {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;   /* centre heading + cards in the leftover space */
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;            /* horizontal centring only */
  padding: clamp(1.5rem, 5vh, 3.25rem) 2rem;
}

.nf-help h2 {
  font-size: 1.25rem;
  margin-bottom: clamp(0.7rem, 1.8vh, 1.1rem);
}

.nf-help-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}

.nf-help-card {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.15rem 1.1rem;
  text-decoration: none;
  color: inherit;
  transition: box-shadow 0.2s, border-color 0.2s;
}
.nf-help-card:hover { box-shadow: var(--shadow-md); border-color: var(--line-2); }
.nf-help-card:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

.nf-help-ic {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 9px;
  background: var(--red-tint);
  color: var(--red);
}

.nf-help-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.nf-help-text strong { font-size: 0.95rem; color: var(--text); }
.nf-help-text span { font-size: 0.82rem; color: var(--muted); line-height: 1.5; }
.nf-help-go { margin-left: auto; align-self: center; color: var(--muted); flex-shrink: 0; }
.nf-help-card:hover .nf-help-go { color: var(--red); }

@media (max-width: 900px) {
  .nf-help-grid { grid-template-columns: 1fr; }
  .nf-help { padding: 0 1.25rem; }
  .nf-actions .btn { flex: 1 1 100%; justify-content: center; min-height: 46px; }
}

/* Phones: compact hero, then the full destination cards (icon + title +
   description + chevron) stacked directly under it — the sparse two-tile
   version left an awkward centred void and read cheap. .nf-help no longer
   grows/centres, so the cards hug the hero with any slack sitting at the
   bottom; the page grows naturally rather than being forced to clip. */
@media (max-width: 640px) {
  .nf-topbar { height: 52px; padding: 0 1.25rem; }
  .nf-hero .page-hero-inner { padding-top: 1.4rem; padding-bottom: 1.1rem; }
  .nf-hero h1 { font-size: 1.55rem; line-height: 1.15; }
  .nf-hero .hero-lead { font-size: 0.9rem; margin-top: 0.5rem; }
  .nf-actions { margin-top: 1rem; }
  .nf-search { margin-top: 0.7rem; }

  .nf-help { flex: 0 0 auto; justify-content: flex-start; padding: 1.5rem 1.25rem 2rem; }
  .nf-help h2 { font-size: 1.1rem; margin-bottom: 0.85rem; }
  .nf-help-grid { grid-template-columns: 1fr; gap: 0.7rem; }
  .nf-help-card { padding: 1rem 1.05rem; }
}

/* ─── Contact Page (locked design + follow-up corrections) ─────
   White info card left (circular red icon chips, hairline rows, real data
   only), white form card right. Desktop: both cards share one stretched
   grid row so they end on the same baseline — the WhatsApp CTA anchors the
   bottom of the left card. Mobile stacks at natural heights. */

/* Softer hero-to-content transition on Contact only: the hero already fades
   into the page canvas, so the full-width rule under it is dropped and the
   cards sit closer to the hero. */
.page-hero.contact-hero { border-bottom: none; }

/* The "Send Us a Message" form is retired site-wide (Product Enquiry covers the
   same job), so this is no longer a two-column grid — one substantial contact
   card sits centred below the hero, its details laid out two-up on desktop so
   it fills the width and reads as a deliberate layout, not a lonely box. */
.contact-page {
  max-width: 880px;
  margin: 1.25rem auto 3.5rem;
  padding: 0 2rem;
}

.contact-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.75rem;
}

/* Left card stays content-sized; the WhatsApp action follows the factual rows
   directly instead of being pushed to the height of the longer form card. */
.contact-info-card {
  display: flex;
  flex-direction: column;
  padding: 2rem 2.25rem;
}
.contact-info-card .contact-whatsapp { margin-top: 1rem; }
.contact-info-card .contact-detail-list { margin-bottom: 0; }

/* Retired site-wide — Product Enquiry does the same job. Kept in the markup
   (harmless) but never shown. */
.contact-form-card { display: none; }

.contact-info-heading {
  font-size: 1.2rem;
  margin-bottom: 0.5rem;
}

.contact-card h2 {
  color: var(--dark);
  font-size: 1.35rem;
  line-height: 1.25;
  margin-bottom: 0.75rem;
}

.contact-detail-list {
  display: grid;
}

/* Desktop: two-up detail grid (Address spans the top; Email + Phone share the
   row below) so the wider card fills its width now the form column is gone.
   The WhatsApp CTA is capped so it doesn't stretch into a giant bar. */
@media (min-width: 720px) {
  .contact-detail-list { grid-template-columns: 1fr 1fr; column-gap: 2.5rem; }
  .contact-detail:first-child { grid-column: 1 / -1; }
  .contact-info-card .contact-whatsapp { max-width: 360px; }
}

.contact-detail {
  display: flex;
  align-items: flex-start;
  gap: 0.9rem;
  border-bottom: 1px solid var(--line);
  padding: 1.1rem 0.15rem;
}

.contact-detail > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

/* Circular red icon chip (locked design). */
.contact-detail-icon {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--red-tint);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--red);
}

.contact-detail strong {
  display: block;
  color: var(--text);
  font-size: 0.95rem;
  font-weight: 700;
  margin-bottom: 0.1rem;
}

.contact-detail span {
  color: var(--text);
  font-size: 0.92rem;
  line-height: 1.5;
}

.contact-detail-sub {
  color: var(--muted) !important;
  font-size: 0.82rem !important;
}

.contact-detail a {
  color: var(--text);
  text-decoration: none;
  font-weight: 500;
  overflow-wrap: anywhere;
}

.contact-detail a:hover { color: var(--red); text-decoration: underline; text-underline-offset: 2px; }

/* Outlined WhatsApp row (locked design: quiet functional control, not a
   full-green banner). */
.contact-whatsapp {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  margin-top: 0;
  padding: 0.85rem 1rem;
  background: #fff;
  border: 1px solid var(--border);
  color: var(--text);
  text-decoration: none;
  font-size: 0.92rem;
  font-weight: 600;
  border-radius: var(--radius);
  transition: border-color 0.18s, background 0.18s;
}

.contact-whatsapp:hover { border-color: #16a34a; background: #f2faf4; }
.contact-whatsapp:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.contact-whatsapp svg:first-child { flex-shrink: 0; color: #25D366; }
.contact-whatsapp-go { margin-left: auto; color: var(--muted); }

.contact-form {
  margin-top: 1rem;
  display: flex;
  flex-direction: column;
  flex: 1;
}

/* Standalone fields (Subject, Message) get the same group rhythm the two-up
   .form-row already carries, so no label ever crowds the control above it. */
.contact-form > .form-group { margin-bottom: 1.15rem; }

/* Message field fills remaining height (desktop stretched card); on the natural
   mobile stack there is no extra height, so it stays at min-height. */
.contact-message-group { flex: 1; display: flex; flex-direction: column; }
.contact-message-group textarea { flex: 1; }

.contact-form textarea {
  min-height: 140px;
}

/* Compact bottom composition (follow-up reference): the security note sits
   directly under the final textarea, with the primary Send action right
   after it — no floating note in an empty region, no isolated Clear Form. */
.contact-security-note {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.78rem;
  color: var(--muted);
  margin: 0 0 0.9rem;
}
.contact-security-note svg { flex-shrink: 0; opacity: 0.75; }

.contact-form-actions {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
}

.contact-submit-btn {
  padding: 0.8rem 1.5rem;
  font-size: 0.92rem;
  font-weight: 700;
}

/* Status line only takes space when it has something to say. Kept in the
   accessibility tree at all times (role="status") — an empty <p> is already
   zero-height, so only its margin needs collapsing. */
.contact-form-status {
  margin: 0 0 0.75rem;
  font-size: 0.9rem;
}
.contact-form-status:empty { margin: 0; }

.contact-form-status.success {
  color: #16803a;
}

.contact-form-status.error {
  color: #c0392b;
}

@media (max-width: 860px) {
  .contact-page {
    grid-template-columns: 1fr;
  }

  .contact-form-card .form-row {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .contact-page {
    margin: 1.5rem auto;
    padding: 0 1rem;
  }

  .contact-card {
    padding: 1.25rem;
  }

  .contact-card h2 {
    font-size: 1.3rem;
  }
}

@media (max-width: 640px) {
  /* Phones: the "Send Us a Message" form duplicates the Product Enquiry flow,
     so it's dropped here. The card keeps the real contact routes — address,
     email and the WhatsApp button — which cover the same job on a phone. */
  .contact-form-card { display: none; }
}

/* ─── Home Page (ReBond) ────────────────────────────────────────
   Assembled entirely from the shared system: the warm hero pattern, the
   four real brand ranges, featured catalogue cards (the same shared
   product card + actions as the catalogue), the shared advice band and
   the shared footer. Real data only. */
.home-hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.5rem;
}
.home-hero-cta .btn { padding: 0.75rem 1.4rem; font-size: 0.92rem; }

.home-brands {
  max-width: 1400px;
  margin: 2rem auto 0;
  padding: 0 2rem;
}
.home-brand-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1rem;
}
.home-brand-card {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.85rem 1rem;
  text-decoration: none;
  color: inherit;
  transition: box-shadow 0.2s, border-color 0.2s;
}
.home-brand-card:hover { box-shadow: var(--shadow-md); border-color: var(--line-2); }
.home-brand-card:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
/* Same fixed-window crop as the card brand marks: the official pictograms sit
   on large padded canvases; the window shows just the mark. */
.home-brand-ic {
  position: relative;
  width: 34px;
  height: 34px;
  overflow: hidden;
  flex-shrink: 0;
}
.home-brand-ic img {
  position: absolute;
  width: 240%;
  height: 240%;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  object-fit: contain;
}
.home-brand-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.home-brand-name {
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.home-brand-count { font-size: 0.74rem; color: var(--muted); }
.home-brand-go { margin-left: auto; flex-shrink: 0; color: var(--muted); transition: color 0.15s; }
.home-brand-card:hover .home-brand-go { color: var(--red); }

.home-featured {
  max-width: 1400px;
  margin: 2.75rem auto 3rem;
  padding: 0 2rem;
}
.home-sec-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.2rem;
}
.home-sec-eyebrow {
  display: block;
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--red);
  margin-bottom: 0.4rem;
}
.home-sec-head h2 {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--text);
  margin: 0;
}
.home-view-all {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--red);
  text-decoration: none;
  font-size: 0.88rem;
  font-weight: 700;
  white-space: nowrap;
  padding-bottom: 0.15rem;
}
.home-view-all:hover { text-decoration: underline; text-underline-offset: 3px; }
.home-view-all:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; border-radius: 2px; }

.home-featured-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.25rem;
}

.home-advice {
  max-width: 1400px;
  margin: 0 auto 3rem;
  padding: 0 2rem;
}

@media (max-width: 1023px) {
  .home-featured-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  .home-brand-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 768px) {
  .home-brands, .home-featured, .home-advice { padding: 0 1.25rem; }
}
@media (max-width: 640px) {
  .home-featured-grid { grid-template-columns: 1fr; gap: 0.9rem; }
  .home-sec-head { flex-direction: column; align-items: flex-start; gap: 0.35rem; }
  .home-hero-cta .btn { flex: 1 1 100%; justify-content: center; min-height: 46px; }
}
@media (max-width: 420px) {
  .home-brand-grid { grid-template-columns: 1fr; }
}

/* ════════════════════════════════════════════════════════════════
   MOBILE REDESIGN — phones ≤640px
   Desktop layout is untouched below this line.
   ════════════════════════════════════════════════════════════════ */

/* ─── Filter group bar — desktop appearance (button replaces h3) */
.filter-group-bar {
  width: 100%;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text);
  margin-bottom: 0.45rem;
  /* Match the rows' 0.5rem inset so labels + checkboxes align on a clean edge;
     a touch more space above than below groups the label with its items. */
  padding: 0.15rem 0.5rem 0.5rem;
  border-bottom: 1px solid var(--border);
  border-top: none;
  border-left: none;
  border-right: none;
  background: none;
  text-align: left;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.filter-group-bar:hover { color: var(--red); }
.filter-group-bar:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; border-radius: 3px; }
.filter-group-bar .r   { display: flex; align-items: center; gap: 0.55rem; }
/* Collapsible groups on every width: chevron rotates, panel hidden unless open. */
.fg-chev {
  display: block;
  color: var(--muted-2);
  transition: transform 0.2s ease;
  flex-shrink: 0;
}
.filter-group.open .fg-chev { transform: rotate(180deg); }
/* Smooth collapse via grid-template-rows (1fr↔0fr) — animates any content
   height cleanly instead of snapping. The single .fg-rows child clips. */
.filter-group-panel {
  display: grid;
  grid-template-rows: 1fr;
  opacity: 1;
  transition: grid-template-rows 0.18s ease, opacity 0.18s ease;
}
.filter-group:not(.open) .filter-group-panel {
  grid-template-rows: 0fr;
  opacity: 0;
}
.fg-rows { overflow: hidden; min-height: 0; }
@media (prefers-reduced-motion: reduce) {
  .filter-group-panel, .fg-chev { transition: none; }
}
.drawer-head           { display: none; } /* mobile only */
.drawer-foot           { display: none; } /* mobile only */
.mobile-filter-bar     { display: none; } /* mobile only */

/* ─── Phones ≤640px: single-column stacked cards (same structure as desktop,
   just full width), compact toolbar + count row. ────────────────── */
@media (max-width: 640px) {
  .product-grid { grid-template-columns: 1fr; gap: 0.9rem; }

  /* Press, not hover, on mobile */
  .product-card:active {
    box-shadow: 0 12px 28px -12px rgba(16,13,9,0.28);
    border-color: #c4bdac;
  }

  /* In-Enquiry confirmed press feedback */
  .product-card-actions .pcard-enq { transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.1s; }
  .product-card-actions .pcard-enq:active { transform: scale(0.97); }
  /* A quick, subtle check-in so adding to the enquiry feels deliberate. */
  .product-card-actions .pcard-enq.btn-added svg { animation: ylEnqCheck 0.18s ease-out both; }
  @keyframes ylEnqCheck {
    from { transform: scale(0.5); opacity: 0.3; }
    to   { transform: scale(1);   opacity: 1; }
  }
  @media (prefers-reduced-motion: reduce) {
    .product-card-actions .pcard-enq.btn-added svg { animation: none; }
  }

  /* Comfortable 44px touch targets on the card actions */
  .product-card-actions .btn { min-height: 44px; }
  .pcard-cmp { min-height: 44px; }

  /* Image and identity share the first band; technical attributes get the full
     card width below so this reads like a purpose-built mobile data card. */
  .product-card { box-shadow: 0 2px 8px rgba(32, 30, 24, 0.05); }
  .pcard-head { padding: 0.78rem 1rem 0.6rem; }
  .pcard-brand-ic { width: 26px; height: 26px; }
  .pcard-main {
    display: grid;
    grid-template-columns: minmax(148px, 48%) minmax(0, 1fr);
    gap: 0 0.9rem;
    align-items: start;
    padding: 0 1rem;
  }
  .product-card-image {
    aspect-ratio: 1 / 1;
    border: 0;
    border-radius: 6px;
    background: var(--panel-2);
  }
  .product-card-image img { padding: 0.35rem; }
  .product-card-body { padding: 0; min-width: 0; }
  .product-card-body h3 {
    font-size: 1.05rem;
    min-height: 0;            /* no desktop two-line reservation needed in the flow */
    margin-bottom: 0.28rem;
    line-height: 1.28;
  }
  .pcard-subtype { font-size: 0.82rem; margin-bottom: 0; line-height: 1.45; }
  .pcard-main > .pcard-rows {
    grid-column: 1 / -1;
    width: 100%;
    margin: 0.85rem 0 0;
  }
  .pcard-main .card-application {
    display: grid;
    grid-template-columns: 18px 72px minmax(0, 1fr);
    align-items: start;
    gap: 0.55rem;
    min-height: 48px;
    padding: 0.72rem 0;
    font-size: 0.8rem;
  }
  .pcard-main .card-application-val {
    margin-left: 0;
    text-align: right;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    line-height: 1.4;
    color: var(--muted);
  }
  .card-workson-spacer { display: none; }
  .product-card-actions {
    padding: 0.85rem 1rem 1rem;
    margin-top: 0;
    border-top: 0;
    flex-wrap: nowrap;
  }
  .product-card-actions .btn { min-height: 48px; }

  /* Catalogue layout padding */
  .catalogue-layout { padding: 0 0.75rem; margin-top: 0.75rem; }
  /* Count row (below the bar, still inside the sticky band so it stays in reach):
     mono uppercase label on the left, "Clear all" on the right while filtering. */
  .grid-meta {
    /* Hug the bar (was 11px) and align to its left edge so the count reads as the
       toolbar's own caption, not a stray line floating above the grid. */
    padding: 8px 4px 0;
    margin: 0;
    background: none;
    border: none;
    box-shadow: none;
    border-radius: 0;
    justify-content: space-between;
    align-items: baseline;
  }
  /* Quiet count caption ("31 products found"), sentence case per the locked
     mobile reference. No box, border, or fill. */
  #resultCount {
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    margin: 0;
  }
  .rc-of { display: inline; }   /* reveal the "of N" narrowing on phones */
  .grid-meta .grid-clear-all:not([hidden]) {
    display: none;
  }

  /* Active-filter summary strip: horizontal swipe row of compact chips with
     the "Active filters:" label and Clear all (locked design). */
  .active-filter-bar { padding: 10px 0.25rem 2px; }
  /* Wrap instead of a nowrap scroll strip: the old overflow-x + margin-left:auto
     shoved "Clear all" off the right edge (it read as "Clear..."). Wrapping keeps
     every chip and the clear control visible; the mono label is dropped on phones
     to save the row. */
  .active-filter-bar-inner { gap: 8px; flex-wrap: wrap; overflow: visible; align-items: center; }
  .active-filter-label { display: none; }
  .active-filter-clear { flex-shrink: 0; margin-left: 0; color: var(--red); min-height: 44px; padding: 0 0.35rem; }
  .filter-chip { flex-shrink: 0; white-space: nowrap; min-height: 44px; padding: 0.5rem 0.75rem; }
  /* No hover-to-red on touch: a :hover that lingers after a tap must not flash
     the chip solid red. Keep it calm; give a gentle pressed state instead. */
  .filter-chip:hover { background: #fff; color: var(--body); border-color: var(--line-2); }
  .filter-chip:active { background: #eae7de; }

  /* Hide the whole desktop sort control on mobile (mirrored in the mobile filter
     bar). Hiding the .grid-sort group covers the "Sort" label, the native
     .sort-select, AND the .custom-select-wrap trigger custom-select.js injects,
     so only #resultCount is left in .grid-meta. */
  .grid-meta .grid-sort { display: none; }

  /* Hide existing 768px filter toggle (replaced by mobile filter bar) */
  .filter-toggle { display: none; }

  /* ─── Unified warm toolbar (Filters + Sort as ONE bar) ────────────────
     A frosted cream band sticks under the nav; inside it Filters and Sort read
     as a single white rounded bar split by a hairline (no black button clashing
     with a white dropdown). The count row sits below, still in the band. */
  .mobile-toolbar {
    position: sticky;
    top: 60px;
    z-index: 40;                     /* above cards, below nav (100) + filter drawer */
    margin: 0 -0.75rem;
    /* A touch more room up top gives the cream bar breathing space under the dark
       nav; tighter elsewhere keeps the whole control area compact. */
    padding: 13px 16px 10px;
    /* Fully opaque cream (was 0.94 + blur): product cards must never ghost through
       as they scroll behind it. */
    background: #f6f4ef;
    /* Transparent at rest: the bar shares the page cream (--bg #f6f4ef), so with
       no border it blends seamlessly into the flow. A visible divider here read
       as a stray full-width line across the page. The separator (border + shadow)
       is added only once it sticks — see .is-stuck. */
    border-bottom: 1px solid transparent;
    transition: box-shadow 0.22s ease, border-color 0.22s ease;
  }
  /* Elevate ONLY once it genuinely sticks under the nav (JS toggles .is-stuck via
     an IntersectionObserver). At rest it sits flat in the page; when pinned it
     lifts into its own layer so cards pass cleanly beneath, not into, it. */
  .mobile-toolbar.is-stuck {
    box-shadow: 0 8px 18px -10px rgba(32, 30, 24, 0.34);
    border-bottom-color: #d8d3c5;
  }
  /* The one bar: white, warm border, rounded. NOTE: no `overflow:hidden` here —
     it would clip the sort dropdown's popup. Corners are instead rounded on each
     edge segment (below) so pressed/hover fills stay inside the radius. */
  .mobile-filter-bar {
    display: flex;
    align-items: stretch;
    gap: 0;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 12px;
    /* Faint lift so the white control reads as a distinct, crafted element on the
       cream band rather than a flat inset panel. */
    box-shadow: 0 1px 2px rgba(32, 30, 24, 0.05);
  }
  /* Filters segment (left): transparent, content-width, ink text + sliders. */
  .mfb-btn {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    height: 44px;
    padding: 0 15px;
    background: transparent;
    color: var(--ink);
    border: none;
    border-radius: 11px 0 0 11px;   /* left corners so the pressed fill stays inside the bar radius */
    font-size: 13.5px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
  }
  .mfb-btn svg { stroke: var(--ink); }
  .mfb-btn:active { background: #f2f0ea; }
  /* Red applied-count badge, inline after the "Filters" label. */
  .mfb-count {
    background: var(--red);
    color: #fff;
    font-family: var(--mono);
    font-size: 0.62rem;
    font-weight: 600;
    min-width: 17px;
    height: 17px;
    border-radius: 9px;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 0 4px;
  }

  /* Sort segment (right): fills the rest, with an inset hairline divider. */
  .mfb-sort-wrap {
    position: relative;
    flex: 1;
    min-width: 0;
    height: 44px;
  }
  .mfb-sort-wrap::before {
    content: "";
    position: absolute;
    left: 0;
    top: 9px;
    bottom: 9px;
    width: 1px;
    background: #e7e3d8;
  }
  /* Reuse the accessible custom dropdown (custom-select.js) but strip its box so
     it reads as a borderless segment inside the shared bar: transparent, full
     height, ink text, muted chevron. Never the raw OS <select> styling. */
  .mfb-sort-wrap .custom-select-wrap { display: block; width: 100%; height: 100%; }
  .mfb-sort-wrap .custom-select-trigger {
    width: 100%;
    height: 100%;
    min-width: 0;
    min-height: 44px;
    background: transparent;
    border: none;
    border-radius: 0 11px 11px 0;   /* right corners so the open/hover fill stays inside the bar radius */
    padding: 0 14px;
    color: var(--ink);
    font-size: 13.5px;
    font-weight: 600;
  }
  /* Open state stays clean white: the chevron flip + the panel dropping below
     already signal "open". A cream fill here (#f2f0ea) is the same family as the
     page bg, so "Default order" read as blending into the background. */
  .mfb-sort-wrap .custom-select-trigger[aria-expanded="true"] {
    background: transparent;
    box-shadow: none;
  }
  /* Warm press feedback only where a real pointer exists. On touch a :hover
     sticks after the tap and would leave the cream fill lingering (the blend). */
  @media (hover: hover) {
    .mfb-sort-wrap .custom-select-trigger:hover { background: #f2f0ea; box-shadow: none; }
  }
  .mfb-sort-wrap .custom-select-trigger:focus-visible {
    background: #f2f0ea;
    outline: 2px solid var(--muted);
    outline-offset: -2px;
    box-shadow: none;
  }
  .mfb-sort-wrap .custom-select-chevron { color: #8a847a; }
  /* Comfortable touch height for each option in the mobile dropdown. */
  .mfb-sort-wrap .custom-select-listbox { min-width: 180px; }
  .mfb-sort-wrap .custom-select-option { min-height: 44px; }

  .mfb-sort-sel {
    width: 100%;
    appearance: none;
    -webkit-appearance: none;
    border: none;
    background: transparent;
    padding: 0.7rem 2rem 0.7rem 0.7rem;
    font-size: 0.8rem;
    font-weight: 500;
    font-family: inherit;
    color: var(--text);
    outline: none;
    cursor: pointer;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23666666' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
    background-repeat: no-repeat;
    background-position: right 0.5rem center;
  }

  /* ─── Step 2: filters bottom sheet ───────────────────────── */
  /* Slide-up sheet anchored to the bottom (not a full-page takeover). z-index
     above the 60px nav so its header + close × are always visible/tappable. */
  .filter-sidebar.open {
    position: fixed !important;
    inset: auto 8px 8px 8px;
    width: auto !important;
    height: min(92dvh, calc(100dvh - 16px - env(safe-area-inset-bottom, 0px)));
    max-height: min(92dvh, calc(100dvh - 16px - env(safe-area-inset-bottom, 0px)));
    z-index: var(--z-filter-sheet);
    display: flex !important;
    flex-direction: column;
    padding: 0;
    background: #faf9f5;
    border: 1px solid var(--line-2);
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 18px 50px -14px rgba(0,0,0,0.48);
    animation: ylFilterSheetUp 0.26s var(--ease) both;
  }
  /* Grab handle — the premium bottom-sheet cue that reads as "drag / dismiss". */
  .filter-sidebar.open::before {
    content: "";
    position: absolute;
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    width: 40px;
    height: 4px;
    border-radius: 999px;
    background: var(--line-2);
    z-index: 3;
    pointer-events: none;
  }
  @keyframes ylFilterSheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
  @media (prefers-reduced-motion: reduce) { .filter-sidebar.open { animation: none; } }

  /* Dimmed backdrop behind the sheet (toggled with .show by products.js). */
  .filter-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(16,13,9,0.5);
    z-index: var(--z-filter-backdrop);
    animation: ylFilterFade 0.2s ease both;
  }
  .filter-backdrop.show { display: block; }
  @keyframes ylFilterFade { from { opacity: 0; } to { opacity: 1; } }
  @media (prefers-reduced-motion: reduce) { .filter-backdrop { animation: none; } }

  .drawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 64px;
    /* Extra top room clears the grab handle; the tight right padding pulls the
       close × so its glyph lines up with the group chevrons in the list below
       (a 44px tap target sat its centred glyph ~13px too far in). */
    padding: 0.95rem 0.3rem 0.55rem 1rem;
    border-bottom: 1px solid #e7e3d8;
    flex-shrink: 0;
    /* The header is the drag-to-dismiss surface (see ylSetupFilterDrag): claim
       the vertical gesture so the browser doesn't treat it as a scroll. */
    touch-action: none;
    cursor: grab;
  }
  .drawer-head h2 {
    font-family: 'Space Grotesk', 'Inter', sans-serif;
    font-size: 1.2rem;
    font-weight: 700;
    margin: 0;
  }
  /* ≥44px tap target with clear contrast against the white drawer. */
  .drawer-x {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 1px solid transparent;
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text);
    cursor: pointer;
    flex-shrink: 0;
  }
  .drawer-x:active { background: var(--panel-2); }

  .drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: 0 1rem 0.75rem;
    -webkit-overflow-scrolling: touch;
    -webkit-mask-image: none !important;
    mask-image: none !important;
  }

  .filter-heading { display: none; }
  .filter-clear   { display: none !important; }

  .sidebar-active {
    border: 0;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    background: transparent;
    padding: 0.75rem 0 0.9rem;
    margin: 0;
  }
  .sidebar-active-head { min-height: 44px; margin-bottom: 0.35rem; }
  .sidebar-active-clear { min-height: 44px; padding: 0 0.25rem; }
  .sidebar-active-chips { gap: 0.45rem; }
  .sidebar-active .filter-chip { min-height: 44px; }

  /* ─── Step 2: accordion filter groups ────────────────────── */
  .filter-group-bar {
    cursor: pointer !important;
    min-height: 52px;
    padding: 0.85rem 0 !important;
    border-bottom: 1px solid var(--border) !important;
    margin-bottom: 0 !important;
    /* Sentence case in the body font reads softer / more premium than shouting
       mono caps in the bottom sheet (matches the prototype). Desktop sidebar
       keeps its mono-caps label. */
    font-family: 'Space Grotesk', 'Inter', sans-serif;
    font-size: 0.98rem;
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0;
  }
  /* Touch latches :hover after a tap, which left group headers stuck red.
     Neutralise the hover colour on the sheet and use a real press state. */
  .filter-group-bar:hover { color: var(--text); }
  .filter-group-bar:active { color: var(--red); }

  .fg-chev {
    display: block;
    color: #888;
    transition: transform 0.2s ease;
    flex-shrink: 0;
  }
  .filter-group.open .fg-chev  { transform: rotate(180deg); }

  /* Collapse handled by the shared grid-rows animation; just add drawer spacing. */
  .filter-group.open .fg-rows { padding-bottom: 0.85rem; }

  .filter-group { margin-bottom: 0; }

  .filter-group label {
    min-height: 48px;
    padding: 0.7rem 0.55rem;
    margin: 0 0 2px;
    border-radius: 6px;
    font-size: 0.94rem;
  }
  .filter-group label:last-child { margin-bottom: 0; }
  .filter-group label:active { background: var(--panel); }  /* press, not hover, on mobile */
  /* Custom checkbox (mobile): native boxes look inconsistent + cheap. A rounded
     box that fills brand-red with a crisp white tick reads far more premium and
     makes the selected state unmistakable. */
  .filter-group input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 22px;
    height: 22px;
    margin: 0;
    border: 1.5px solid var(--line-2);
    border-radius: 6px;
    background: #fff;
    position: relative;
    flex-shrink: 0;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
  }
  .filter-group input[type="checkbox"]:checked {
    background: var(--red);
    border-color: var(--red);
  }
  .filter-group input[type="checkbox"]:checked::after {
    content: "";
    position: absolute;
    left: 7px;
    top: 3px;
    width: 6px;
    height: 11px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
  }
  /* The red tick is now the selected indicator, so the red-tint row wash is
     redundant and reads as too much red on a phone. Keep checked rows on the
     plain ground — just the tick + a bolder label. */
  .filter-group label:has(input:checked),
  .filter-group label:hover:has(input:checked) { background: transparent; }
  .filter-label-text { font-size: 0.92rem; }
  .fg-more-btn { min-height: 44px; padding: 0.65rem 0.55rem; }

  /* ─── Step 2: drawer footer ─────────────────────────────── */
  /* A sticky action bar that reads as PART of the cream sheet, not a white slab
     dropped on top: same cream ground, a soft warm hairline and a faint upward
     lift to separate it from the scrolling filter list above. */
  .drawer-foot {
    display: flex;
    gap: 0.6rem;
    padding: 0.8rem 1rem calc(0.8rem + env(safe-area-inset-bottom, 0px));
    background: #faf9f5;
    border-top: 1px solid #e7e3d8;
    box-shadow: 0 -10px 22px -18px rgba(26, 23, 18, 0.45);
    flex-shrink: 0;
  }
  .drawer-apply {
    flex: 1;
    width: 100%;
    min-height: 50px;
    background: var(--red);
    border: none;
    color: #fff;
    border-radius: 12px;
    padding: 0.7rem;
    font-size: 0.92rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    font-family: inherit;
    cursor: pointer;
    box-shadow: 0 6px 16px -8px rgba(204, 41, 41, 0.5);
    transition: background 0.15s var(--ease), transform 0.12s var(--ease);
  }
  .drawer-apply:active { background: var(--red-hover); transform: scale(0.99); }
}

/* ════════════════════════════════════════════════════════════════
   MOBILE — product detail sticky CTA, compare page scroll hint
   All hidden on desktop; revealed only at ≤640px.
   ════════════════════════════════════════════════════════════════ */
.sticky-cta { display: none; }

@media (max-width: 640px) {
  /* ─── Step 3: sticky bottom action bar ──────────────────────── */
  body.detail-has-cta { padding-bottom: 4.9rem; }
  /* Extra breathing room above the fixed bar at the very end of the page.
     Added INSIDE the dark footer (like body.compare-open above) so it can
     never expose a cream strip; the JS-measured body reservation stays an
     exact fit to the bar. Keeps footer links comfortably tappable. */
  body.detail-has-cta .site-footer { padding-bottom: 20px; }
  .sticky-cta {
    display: none;
    gap: 0.5rem;
    align-items: stretch;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: var(--z-sticky-cta);
    padding: 0.6rem 0.9rem calc(0.6rem + env(safe-area-inset-bottom, 0px));
    /* Solid (not alpha) so the cream body never shows through as a strip
       between the dark footer and this bar. The soft upward shadow gives the
       bar depth so it reads as a floating surface, not a flat strip. */
    background: #fff;
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-top: 1px solid var(--line);
    box-shadow: 0 -10px 26px -14px rgba(20, 16, 8, 0.30);
  }
  .sticky-cta.is-visible { display: flex; }
  .sticky-cta-cmp {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    width: 60px;
    min-height: 48px;
    flex-shrink: 0;
    background: #fff;
    border: 1px solid var(--line-2);
    border-radius: 12px;
    color: var(--muted);
    font-family: inherit;
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s, background 0.15s, transform 0.12s;
  }
  .sticky-cta-cmp:active { transform: scale(0.97); }
  .sticky-cta-cmp.on {
    color: var(--red);
    border-color: var(--red);
    background: var(--red-tint);
  }
  .sticky-cta-add {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    min-height: 48px;
    background: var(--red);
    color: #fff;
    border: none;
    border-radius: 12px;
    font-family: inherit;
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    cursor: pointer;
    box-shadow: 0 6px 16px -8px rgba(204, 41, 41, 0.55);
    transition: background 0.15s, transform 0.12s, box-shadow 0.15s;
  }
  .sticky-cta-add:active { transform: scale(0.985); }
  .sticky-cta-add.added {
    background: var(--green);
    box-shadow: 0 6px 16px -8px rgba(22, 128, 58, 0.5);
  }
  /* Green WhatsApp square (on-brand, bordered — matches the contact page) */
  .sticky-cta-wa {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    min-height: 48px;
    flex-shrink: 0;
    background: var(--green-tint);
    border: 1px solid var(--green-tint-bdr);
    border-radius: 12px;
    color: var(--green);
    transition: background 0.15s, transform 0.12s;
  }
  .sticky-cta-wa:active { transform: scale(0.97); background: #dcefe1; }


  /* ─── Compare page: mobile scroll hint ───────────────────────
     The table itself is unified across breakpoints (see .cx-scroll /
     .compare-row-label near the compare table styles); this hint just
     nudges the user to swipe when the columns overflow the viewport. */
  .cx-scrollhint {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin: 0 0 0.6rem;
    color: var(--red);
    font-size: 0.76rem;
    font-weight: 600;
    transition: opacity 0.2s;
  }
  .cx-scrollhint svg { flex-shrink: 0; }
  .cx-scrollhint[hidden] { display: none; }
}
