/**
 * Closo Wholesale Marketplace — public catalog chrome + cards (S1).
 * Tokens are the approved artboards' own (wsmk Main.dc / Home.dc /
 * MobileCatalog.dc): #452B90 accent · #1A202C ink · #556070 muted ·
 * #E4E2EE lines · #FAFAFC card bg · pill buttons · 14px card radius ·
 * kraft photo placeholder gradient. Fonts: Poppins (display), Inter (text),
 * JetBrains Mono (numbers) — linked from _chrome.php.
 *
 * Mobile per MobileCatalog.dc: single column under 640px, filter chips in
 * one horizontal-scroll row.
 */

/* Scrollbar appearance must never shift the layout between pages. */
html { scrollbar-gutter: stable; }

.wm {
  margin: 0 auto;
  /* ONE page container across every marketplace page (catalog, home, sold,
   * lot, auctions) — same max-width the lot/auctions documents center at,
   * so tab navigation never jumps in width. Widened 1280 -> 1720 (operator
   * 2026-08-19: Faire-width surface); wide viewports add grid columns below. */
  max-width: none;
  background: #fff;
  color: #1A202C;
  font-family: "Inter", Inter Fallback, system-ui, -apple-system, sans-serif;
  -webkit-text-size-adjust: 100%;
}
:where(.wm) a { color: inherit; text-decoration: none; }
:where(.wm) a:hover { color: #321F69; }

/* ── wm-* components are SELF-SUFFICIENT ─────────────────────────────────
 * The lot/auctions documents render this chrome after their OWN <body>; no
 * component may depend on a `.wm` ancestor for its text color or link
 * decoration — every base class below carries its own. */
.wm-wordmark, .wm-btn-ghost, .wm-btn-solid, .wm-btn-outline, .wm-tab,
.wm-chip, .wm-drop-panel a, .wm-footer a, .wm-card-cta, .wm-find-similar,
.wm-heart, .wm-teaser-cta, .wm-card-link, .wm-week-title {
  text-decoration: none;
}
.wm-btn-ghost, .wm-btn-solid, .wm-btn-outline, .wm-tab, .wm-chip,
.wm-card-cta, .wm-teaser-cta, .wm-footer a, .wm-drop-panel a,
.wm-find-similar, .wm-heart, .wm-wordmark {
  transition: background 0.15s ease, color 0.15s ease,
    border-color 0.15s ease, box-shadow 0.15s ease;
}
/* Keyboard focus — every interactive element on the surface. */
.wm a:focus-visible, .wm button:focus-visible, .wm summary:focus-visible,
.wm input:focus-visible,
a[class*="wm-"]:focus-visible, button[class*="wm-"]:focus-visible,
summary[class*="wm-"]:focus-visible {
  outline: 2px solid #452B90;
  outline-offset: 2px;
}

/* ── header ─────────────────────────────────────────────────────────── */
.wm-header {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 18px 48px;
  border-bottom: 1px solid #E4E2EE;
}
.wm-wordmark {
  /* The BRAND mark, not a display face: closo.co's own logo recipe
   * (.chd-logo — Inter 700 / 19px / -0.02em / ink) so «Closo» reads the
   * same on the marketplace, the marketing site and the cabinet
   * (operator 2026-08-21). Only the product word keeps the accent. */
  font-family: "Inter", Inter Fallback, system-ui, sans-serif;
  font-weight: 700;
  font-size: 19px;
  letter-spacing: -0.02em;
  color: #1A202C;
  white-space: nowrap;
}
.wm-wordmark span { color: #452B90; }
.wm-search {
  flex: 1;
  max-width: 480px;
  display: flex;
  align-items: center;
  gap: 9px;
  background: #FAFAFC;
  border: 1px solid #E4E2EE;
  border-radius: 999px;
  padding: 10px 18px;
  color: #556070;
  font-size: 13.5px;
}
.wm-search input {
  flex: 1;
  border: 0;
  background: transparent;
  font: inherit;
  color: #1A202C;
  outline: none;
  padding: 0;
  min-width: 0;
}
.wm-search input::placeholder { color: #556070; }
/* The pill IS the focus ring (operator 2026-09-05: «remove the rectangular border … inside the oval»): the global input focus outline would draw a rectangle
   inside the rounded field, so the input drops it and the field lights up. */
.wm-search input:focus, .wm-search input:focus-visible { outline: none; box-shadow: none; }
.wm-search:focus-within { border-color: #452B90; box-shadow: 0 0 0 3px rgba(69,43,144,.12); background: #fff; }
.wm-header-spacer { flex: 1; }
.wm-header-cta { display: flex; align-items: center; gap: 10px; }
.wm-btn-ghost {
  font-size: 13.5px;
  font-weight: 600;
  padding: 10px 16px;
  border-radius: 999px;
  color: #1A202C;
  white-space: nowrap;
}
.wm-btn-supply { color: #556070; }
.wm-btn-supply:hover { color: #1A202C; background: #F4F2FA; }
@media (max-width: 900px) { .wm-btn-supply { display: none; } }
.wm-btn-ghost:hover {
  background: #F4F2FA;
  color: #1A202C;
  box-shadow: inset 0 0 0 1px #E4E2EE;
}
/* Button chrome, Faire benchmark (operator 2026-08-20): a real 1px ink
 * border at rest; on hover the border DOUBLES via an inset ring — the
 * box-shadow trick keeps the geometry byte-identical, so nothing shifts.
 * The ground stays white on hover (the ring is the event); the tint is the
 * PRESS (:active), one step later, exactly Faire's order. */
.wm-btn-outline {
  border: 1px solid #1A202C;
  border-radius: 999px;
  padding: 10px 22px;
  color: #1A202C;
  background: #fff;
}
.wm-btn-outline:hover {
  background: #fff;
  color: #1A202C;
  box-shadow: inset 0 0 0 1px #1A202C;
}
.wm-btn-outline:active { background: #F4F2FA; }
.wm-btn-solid {
  font-size: 13.5px;
  font-weight: 600;
  padding: 10px 20px;
  background: #452B90;
  color: #fff;
  border-radius: 999px;
  white-space: nowrap;
  border: 0;
  cursor: pointer;
}
.wm-btn-solid:hover {
  background: #321F69;
  color: #fff;
  box-shadow: inset 0 0 0 1px #170D3E;
}
.wm-btn-solid:active { background: #2A1A58; }

/* Header CTAs — Stripe / Airbnb secondary-button benchmark (operator
 * 2026-08-20): a ghost button with NO border at rest reads as text, and the
 * three header doors (Setup guide / Apply to sell / Log in) were exactly
 * that — nothing said they were pressable until the pointer was already on
 * them. Each now carries a 1px hairline at rest. Hover takes the border to
 * ink while the ground stays white (Airbnb's move, and the same order
 * .wm-btn-outline already codifies above); the tint is the PRESS, one step
 * later. Geometry is byte-identical: the 1px border is subtracted from the
 * padding, and the solid gets a same-colour border so all four pills share
 * one height. Scoped to .wm-header-cta on purpose — the in-page ghost links
 * (auction guides, CTA bands) keep their flat look. */
.wm-header-cta .wm-btn-ghost {
  border: 1px solid #DDDBE7;
  background: #fff;
  padding: 9px 15px;
  box-shadow: 0 1px 1px rgba(16, 24, 40, .03);
  transition: border-color .15s ease, background-color .15s ease;
}
.wm-header-cta .wm-btn-ghost:hover {
  background: #fff;
  color: #1A202C;
  border-color: #1A202C;
  box-shadow: 0 1px 1px rgba(16, 24, 40, .03);
}
.wm-header-cta .wm-btn-ghost:active { background: #F4F2FA; }
.wm-header-cta .wm-btn-ghost:focus-visible { outline: 2px solid #452B90; outline-offset: 2px; }
.wm-header-cta .wm-btn-solid { border: 1px solid #452B90; padding: 9px 19px; }

/* …and a RANK inside that cluster (operator 2026-08-20: "they all look
 * the same now"). One border for four buttons is affordance without hierarchy —
 * the eye cannot tell the main door from a help link. Three tiers, the Stripe
 * / Airbnb / Faire split, every one of them still visibly pressable:
 *   solid   Sign up free           — the action the page wants
 *   outline Log in                 — the second door, for people who have one
 *   tonal   Setup guide / Apply to sell — utilities: a soft ground carries the
 *           click, no border competes with the doors.
 * A hairline divider separates the two utilities from the two doors, so the
 * cluster reads as two groups instead of a row of four. */
.wm-header-cta .wm-btn-guide,
.wm-header-cta .wm-btn-supply {
  border-color: transparent;
  background: #F4F2FA;
  color: #4A5262;
  box-shadow: none;
}
.wm-header-cta .wm-btn-guide:hover,
.wm-header-cta .wm-btn-supply:hover {
  background: #EBE7F7;
  color: #1A202C;
  border-color: transparent;
  box-shadow: none;
}
.wm-header-cta .wm-btn-guide:active,
.wm-header-cta .wm-btn-supply:active { background: #E2DCF3; }
.wm-cta-div {
  width: 1px;
  height: 22px;
  background: #E4E2EE;
  flex: 0 0 auto;
}
@media (max-width: 900px) { .wm-cta-div { display: none; } }

/* ── section nav ────────────────────────────────────────────────────── */
.wm-nav {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 48px;
  border-bottom: 1px solid #E4E2EE;
}
.wm-tab {
  font-size: 14px;
  font-weight: 500;
  color: #556070;
  padding: 15px 14px;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
/* Tab hover = underline only (operator 2026-08-31: «only the bottom
 * underline») — the active state's line in a lighter tint, no ground. */
.wm-tab:hover {
  color: #1A202C;
  border-bottom-color: #CBC4E4;
}
.wm-tab.is-active {
  font-weight: 600;
  color: #1A202C;
  border-bottom-color: #452B90;
}
.wm-nav-count {
  margin-left: auto;
  font-family: "JetBrains Mono", monospace;
  font-size: 12px;
  color: #556070;
  white-space: nowrap;
}

/* ── filters ────────────────────────────────────────────────────────── */
.wm-applied {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 9px;
  padding: 16px 48px 0;
}
.wm-applied-label { font-size: 12.5px; color: #556070; }
.wm-filters {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 18px 48px 4px;
}
.wm-chip {
  display: inline-block;
  font-size: 12.5px;
  font-weight: 500;
  border: 1px solid #E4E2EE;
  border-radius: 999px;
  padding: 8px 15px;
  cursor: pointer;
  list-style: none;
  white-space: nowrap;
  background: #fff;
  color: #1A202C;
}
.wm-chip span { color: #556070; }
.wm-chip b { font-weight: 700; margin-left: 2px; }
.wm-chip-x { display: inline-block; vertical-align: middle; margin-left: 4px; color: inherit; }
.wm-chip.is-on {
  font-weight: 600;
  color: #452B90;
  background: #EDE8F8;
  border-color: #452B90;
}
.wm-chip:hover { border-color: #452B90; color: #452B90; }
.wm-chip.is-on span { color: #452B90; }
/* «See all <theme>» next to an applied Theme chip (2026-10-23): the theme's own page, only while it is open */
.wm-chip-more { display: inline-flex; align-items: center; min-height: 32px; padding: 0 4px; font-size: 13px; font-weight: 600; color: #452B90; text-decoration: underline; text-underline-offset: 2px; }
.wm-chip-more:hover { color: #2f1d66; }
.wm-drop { position: relative; }
.wm-drop summary::-webkit-details-marker { display: none; }
.wm-drop summary { list-style: none; }
.wm-drop-panel {
  position: absolute;
  z-index: 30;
  top: calc(100% + 6px);
  left: 0;
  min-width: 170px;
  background: #fff;
  border: 1px solid #E4E2EE;
  border-radius: 12px;
  box-shadow: 0 12px 36px rgba(26, 32, 44, 0.14);
  padding: 6px;
  display: flex;
  flex-direction: column;
}
.wm-drop-panel a {
  font-size: 13px;
  padding: 8px 12px;
  border-radius: 8px;
  color: #1A202C;
}
.wm-drop-panel a:hover { background: #FAFAFC; color: #452B90; }
.wm-sort {
  margin-left: auto;
  font-size: 12.5px;
  color: #556070;
  white-space: nowrap;
}
.wm-sort b { color: #1A202C; font-weight: 600; }
/* Sort menu (2026-09-05): a <details> dropdown; the summary is the pill the
 * toolbar already styled, the menu a right-anchored card. */
.wm-sortdd { position: relative; }
.wm-sortdd > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.wm-sortdd > summary::-webkit-details-marker { display: none; }
.wm-sortdd > summary svg { color: #556070; transition: transform 160ms; }
.wm-sortdd[open] > summary svg { transform: rotate(180deg); }
.wm-sortdd-menu { position: absolute; right: 0; top: calc(100% + 6px); z-index: 30; min-width: 220px; padding: 6px; background: #fff; border: 1px solid #E4E2EE; border-radius: 12px; box-shadow: 0 12px 32px rgba(26, 32, 44, .12); }
.wm-sortdd-menu a { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 9px 10px; border-radius: 8px; font-size: 13.5px; color: #1A202C; text-decoration: none; white-space: nowrap; }
.wm-sortdd-menu a:hover { background: #FAFAFC; color: #452B90; }
.wm-sortdd-menu a.is-on { font-weight: 600; color: #452B90; }
.wm-sortdd-menu a.is-on::after { content: "\2713"; font-size: 13px; }
/* A sort that says what it does (Resale view): the label and its second line. */
.wm-sortdd-l { display: flex; flex-direction: column; gap: 2px; }
.wm-sortdd-l small { font-size: 12px; font-weight: 400; color: #6B6478; white-space: normal; max-width: 240px; }

/* ── The lot card's resale strip (Closo Resale Index, 2026-09-27) — ONE rule for the hub's
 * «Source it wholesale» strip and the grids' Resale view (moved from wholesale-resale-index.css). */
.wm-card-ri { position: relative; z-index: 2; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 4px 8px; margin: 10px 0 2px; padding: 10px 12px; border-radius: 12px; background: #F7F5F1; }
.wm-card-ri > div { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.wm-card-ri span { font: 500 10.5px/1.2 Inter, Inter Fallback, system-ui, sans-serif; letter-spacing: .06em; text-transform: uppercase; color: #6B6478; }
.wm-card-ri b { font: 600 18px/1.2 Poppins, Poppins Fallback, Inter, Inter Fallback, system-ui, sans-serif; color: #1A1530; }
.wm-card-ri b.g { color: #1F7A4D; }
.wm-card-ri small { font: 400 11px/1.3 Inter, Inter Fallback, system-ui, sans-serif; color: #6B6478; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wm-card-ri em { grid-column: 1 / -1; justify-self: start; font: 600 12px/1 Inter, Inter Fallback, system-ui, sans-serif; font-style: normal; color: #1F7A4D; background: #E6F3EC; padding: 5px 10px; border-radius: 999px; }

/* ── «Resale view» (Ivan 2026-09-28, artifact 4SYyS4ijwcgS4qpBnmnR8T) ─────────────
 * The switch beside Sort, the explainer under the toolbar, the strip / dashed empty
 * state on every card of the grid. Every block ships HIDDEN (the grid is shared-cached):
 * _resale_switch.php's pre-paint script puts .wsm-rv on <html> for a viewer who turned
 * it on, and .wsm-rv-js at all — no script, no switch. */
.wm-rv-switch { display: none; align-items: center; gap: 8px; margin-left: auto; height: 40px; box-sizing: border-box; padding: 0 12px 0 16px; border: 1px solid #D5D8DE; border-radius: 999px; background: #fff; font: 600 14px/1 Inter, Inter Fallback, system-ui, sans-serif; color: #1A1530; cursor: pointer; white-space: nowrap; -webkit-tap-highlight-color: transparent; }
html.wsm-rv-js .wm-rv-switch { display: inline-flex; }
.wm-rv-switch + .wm-sort { margin-left: 0; }
.wm-rv-switch:hover { border-color: #452B90; color: #452B90; }
.wm-rv-switch:focus-visible { outline: 2px solid #452B90; outline-offset: 2px; }
.wm-rv-track { position: relative; display: inline-block; flex: none; width: 32px; height: 18px; border-radius: 999px; background: #CFCBD8; transition: background .15s; }
.wm-rv-knob { position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 999px; background: #fff; transition: left .15s; }
html.wsm-rv .wm-rv-switch { border-color: #452B90; background: #F4F1FA; color: #452B90; }
html.wsm-rv .wm-rv-track { background: #452B90; }
html.wsm-rv .wm-rv-knob { left: 16px; }
.wm-rv-bar { display: flex; align-items: center; justify-content: flex-end; gap: 12px; padding-top: 0; margin-bottom: 4px; }
.wm-rv-note { display: none; align-items: center; gap: 10px; margin: 16px 0 0; padding: 12px 16px; border-radius: 12px; background: #F4F1FA; font: 400 13px/1.45 Inter, Inter Fallback, system-ui, sans-serif; color: #4A4458; }
.wm-rv-note svg { flex: none; color: #452B90; }
.wm-rv-note b { color: #1A1530; font-weight: 600; }
html.wsm-rv .wm-rv-note { display: flex; }
.wm-card-rv { display: none; }
html.wsm-rv .wm-card-rv { display: block; margin-top: 8px; }
.wm-card-rv .wm-card-ri { position: static; z-index: auto; gap: 8px; margin: 0; padding: 12px; background: #F6F4EF; }
.wm-card-rv .wm-card-ri small { white-space: normal; }
.wm-card-ri-foot { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 8px; margin: 0; min-width: 0; }
.wm-card-ri-foot em { flex: none; }
.wm-card-ri-foot i { font: 400 11px/1.3 Inter, Inter Fallback, system-ui, sans-serif; font-style: normal; color: #6B6478; white-space: nowrap; }
/* a bale sold by weight (2026-09-28): the estimated piece count, its own line under the foot */
.wm-card-ri-est { margin-top: 6px; }
.wm-card-ri-est i { white-space: normal; }
.wm-rv-sorted { display: none; margin: 10px 0 0; font: 400 12px/1.4 Inter, Inter Fallback, system-ui, sans-serif; color: #6B6478; }
.wm-rv-sorted b { color: #1A1530; font-weight: 600; }
.wm-card-rv-empty { display: flex; align-items: flex-start; gap: 8px; margin: 0; padding: 12px; border: 1px dashed #D9D4E3; border-radius: 12px; font: 400 12px/1.45 Inter, Inter Fallback, system-ui, sans-serif; color: #6B6478; }
.wm-card-rv-empty svg { flex: none; margin-top: 1px; }
.wm-card-rv-empty b { display: block; color: #4A4458; font-weight: 600; }
@media (max-width: 640px) {
  .wm-rv-switch { margin-left: 0; padding: 0 10px 0 14px; }
  .wm-rv-ic, .wm-rv-lx { display: none; }
  .wm-rv-switch + .wm-sort { margin-left: auto; }
  .wm-rv-bar { justify-content: flex-start; }
  /* Filters · Resale · Sort in one row at 390 (Phone artboard): the Sort pill says «Sort ⌄» and the
     order is named on its own line under the row — «Sort: Recommended» beside the switch overflowed. */
  html.wsm-rv-js .wm-rv-switch + .wm-sort > summary { font-size: 0; gap: 4px; }
  html.wsm-rv-js .wm-rv-switch + .wm-sort > summary::before { content: "Sort"; font-size: 13px; color: #1A1530; }
  html.wsm-rv-js .wm-rv-sorted { display: block; }
}

/* ── grid + cards ───────────────────────────────────────────────────── */
/* SF-4 wave 3 (2026-09-11): a 48-card grid. Cards past the second row are
   laid out only as they approach the viewport — Lighthouse mobile lost two
   points to the extra DOM at 48; this gives them back without changing what
   is in the tree (the crawler still reads every card). `auto 430px`: the
   phone card's height as the first guess, the card's own remembered height
   after its first paint — the estimate only matters on the first scroll. */
/* Screen-reader-only text (the photo count's «6 photos» behind the icon). */
.wm-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.wm-grid--dense .wm-card:nth-child(n+7) { content-visibility: auto; contain-intrinsic-size: auto 430px; }
.wm-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px;
  padding: 20px 48px 28px;
}
/* The search note («Also matching …», «No results for …», market/index.php) sits on the GRID's own
   left edge and in the grid's rhythm — measured 2026-09-22 on /wholesale/lots?q=…: it hung 24 px
   left of the cards (its wrapper has no gutter) and 8 px under the assistant bar, with an inline
   style on each of the five variants. One rule, no inline styles: the card edge is the grid's
   padding (24 px beside the filters column, 16 px on phones), 16 px above; below, its 4 px + the grid's own 20 px top padding = the 24 px block gap (phone 10 + 14). */
.wm-search-note { margin: 16px 0 4px; padding: 0 48px 0 24px; font-size: 13px; line-height: 1.5; color: #556070; }
/* W7-b «Suppliers matching “q”» (2026-09-11; cards 2026-09-27, Ivan: Faire's
   «Brands» section above «Products»). A titled section of the storefront's
   supplier cards (.wsf-sup, wholesale-market-faire.css) inside the live grid
   region. Gutter: the column's shared rule (wholesale-market-filters.css, beside
   .wm-recent — 24 / 48, 24 / 24 ≤ 980, 16 / 16 ≤ 640) so the heading and the
   first card sit on the product cards' left edge. Rhythm: 24 px under the
   assistant bar (was 0), 16 px heading → cards, and 8 px + the grid's own
   16 px top = 24 px to the results (phone 16 above, 10 + 14 = 24 below).
   Columns: the grid's own count, joined into its rules below, so every
   supplier card is exactly one product card wide. It sits HERE, before the
   per-width rules below, so they win the cascade at equal specificity. */
.wm-search-sup { margin: 24px 0 8px; }
.wm-search-sup .wsf-row-head { margin-bottom: 16px; }
.wm-search-sup .wsf-sups { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px; }
.wm-card {
  position: relative;
  border: 1px solid #E4E2EE;
  border-radius: 14px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: #fff;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.wm-card:hover,
.wm-card:focus-within {
  transform: translateY(-2px);
  box-shadow: 0 10px 28px rgba(26, 32, 44, 0.12);
}
.wm-card:hover .wm-card-cta { color: #321F69; }
/* ⛔ THE CARD HAD HOVER AND NO PRESS. Every button on this sheet follows the
   order stated above — hover is the event, the tint is the PRESS one step
   later — and the card, the most-clicked target on the marketplace, was the
   one control that skipped it. So a click produced NOTHING until the next
   document painted: locally that is 140-220ms, and over a real network it is
   long enough to read as «it did not react» and to be clicked twice.
   The press settles the hover lift and tightens the shadow — the card goes
   DOWN under the finger, which is the whole point of a press state. */
.wm-card:active {
  transform: translateY(0);
  box-shadow: 0 3px 10px rgba(26, 32, 44, 0.14);
}
.wm-card:active .wm-card-cta { color: #2A1A58; }
@media (prefers-reduced-motion: reduce) {
  .wm-card { transition: box-shadow 0.15s ease; }
  .wm-card:hover, .wm-card:focus-within, .wm-card:active { transform: none; }
}
.wm-card-link { position: absolute; inset: 0; z-index: 1; }
.wm-card-photo {
  aspect-ratio: 4 / 3;
  position: relative;
  background: linear-gradient(135deg, #E9E5DC, #D6D0C2); /* kraft placeholder */
  overflow: hidden;
}
/* Composed cover (COVER wave). The drawn SVG is set inline by _card.php as a
   background-image LAYERED OVER the kraft gradient, so a cover that fails to
   fetch degrades to exactly the placeholder this file already painted. The
   cover is authored 4:3 — the same ratio as the frame — so `cover` sizing
   crops nothing. Only ever present on a card with no printable photo. */
.wm-card-photo.has-cover {
  background-size: cover, auto;
  background-position: center, 0 0;
  background-repeat: no-repeat, no-repeat;
}
.wm-card-photo img {
  width: 100%;
  height: 100%;
  max-width: 100%;
  object-fit: cover;
  display: block;
}
.wm-photo-count {
  position: absolute;
  top: 10px;
  left: 10px;
  font-size: 11px;
  font-weight: 700;
  background: rgba(26, 32, 44, 0.82);
  color: #fff;
  border-radius: 5px;
  padding: 2px 8px;
}
/* Off the cover's text zone: the drawn cover prints the shelf and the unit count bottom-LEFT,
 * and the pill sat on the digits (Ivan, phone, 2026-10-08). Text pill (legacy, lean flag off):
 * bottom-right beside the 34px heart. Icon pill (lean, the fleet): TOP-right corner, the bag
 * moves left of it — Ivan's placement, «next to add-to-bag» (see .wm-find-similar--icon). */
.wm-find-similar {
  position: absolute;
  z-index: 2;
  bottom: 10px;
  right: 52px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 600;
  background: rgba(255, 255, 255, 0.94);
  color: #1A202C;
  border-radius: 999px;
  padding: 6px 11px;
  box-shadow: 0 1px 4px rgba(26, 32, 44, 0.15);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, color 0.15s ease;
}
.wm-find-similar:hover { color: #452B90; }
.wm-card:hover .wm-find-similar,
.wm-card:focus-within .wm-find-similar {
  opacity: 1;
  pointer-events: auto;
}
.wm-heart {
  position: absolute;
  z-index: 2;
  right: 10px;
  bottom: 10px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.94);
  box-shadow: 0 1px 4px rgba(26, 32, 44, 0.18);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #556070;
}
.wm-heart:hover { color: #B02E68; }
.wm-card-body {
  padding: 13px 15px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex-grow: 1;
}
/* Lot archive listing (ТЗ 2026-09-23): an archive card is a link as a whole, its
   badge is the status and date («Off market · Sep 12, 2026» / «Sold · …»). */
a.wm-card--offmkt { color: inherit; text-decoration: none; }
.wm-badge.wm-badge--offmkt { color: #8A5A00; background: #FDF3E0; }
.wm-badge {
  align-self: flex-start;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: 99px;
  padding: 2px 8px;
}
.wm-badge-manifested { color: #186A3B; background: #E8F5EC; }
.wm-badge-assortment { color: #1D5FBF; background: #DCEAFB; }
.wm-badge-unmanifested { color: #8A5A00; background: #FDF3E0; }
.wm-card-title {
  font-size: 15px;
  line-height: 1.3;
  /* Faire benchmark (operator 2026-09-08): a title takes two lines at most, then an
     ellipsis — cards keep one rhythm whether the supplier wrote 4 words or 40. The
     full title stays in the title= attribute and on the lot page. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
}
.wm-card-meta { font-size: 12.5px; color: #556070; }
.wm-card-price {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 6px;
}
.wm-price {
  font-family: "JetBrains Mono", monospace;
  font-size: 18px;
  font-weight: 700;
}
.wm-msrp {
  font-size: 12.5px;
  color: #556070;
  text-decoration: line-through;
}
.wm-msrp-plain { text-decoration: none; }
.wm-off {
  margin-left: auto;
  font-size: 11px;
  font-weight: 700;
  color: #B02E68;
  background: #FBE3EE;
  border-radius: 99px;
  padding: 2px 8px;
  /* ONE line, always (operator 2026-09-05: the badge broke into two rows in a
     narrow card): the pill never wraps or shrinks — the struck retail beside
     it gives way instead. */
  white-space: nowrap;
  flex: none;
}
.wm-card-price .wm-msrp { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* «39 % of retail» (display wave 2026-09-17): the measured green the card
   already uses for a manifested lot — a real number, not a promotion. One
   line, never wraps; sits at the row's end like .wm-off. */
.wm-retail {
  margin-left: auto;
  font-size: 11px;
  font-weight: 700;
  color: #186A3B;
  background: #E8F5EC;
  border-radius: 99px;
  padding: 2px 8px;
  white-space: nowrap;
  flex: none;
}
.wm-card-price .wm-off + .wm-retail { margin-left: 0; }
/* «N sizes» (lot sizes W3-SEO, 2026-09-25): a lot in several sizes is ONE card, the head's —
   «From $X» + this chip, the neutral grey of the meta line (a fact, not a promotion). One line,
   never wraps; sits at the row's end like .wm-off. */
.wm-card-sizes {
  margin-left: auto;
  font-size: 11px;
  font-weight: 700;
  color: #3A4452;
  background: #EEF0F3;
  border-radius: 99px;
  padding: 2px 8px;
  white-space: nowrap;
  flex: none;
}
/* The foreign guest's price row (2026-09-25, Faire «Unlock wholesale pricing»): the lock of the
   «Buying for resale?» plaque + the words, in the card's link colour. ABOVE the stretched overlay
   link (.wm-card-link, z-index 1) like .wm-supplier-link, or the click would open the lot. */
.wm-card-unlock {
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-size: 14px;
  font-weight: 600;
  color: #452B90;
  text-decoration: none;
  width: fit-content;
}
.wm-card-unlock svg { width: 14px; height: 14px; flex: none; }
.wm-card-unlock:hover { text-decoration: underline; }
.wm-card-cta {
  display: block;
  text-align: center;
  padding: 10px 0 12px;
  font-size: 13.5px;
  font-weight: 600;
  color: #452B90;
  border-top: 1px solid #E4E2EE;
}
.wm-card-cta:hover { color: #321F69; }

/* ── empty state · pager · teaser ───────────────────────────────────── */
.wm-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 72px 48px;
  text-align: center;
}
.wm-empty b { font-size: 16px; }
.wm-empty span { font-size: 13.5px; color: #556070; }
.wm-empty .wm-btn-outline { margin-top: 10px; }
/* two doors side by side (rung 2 at 0 lots: the shelf's archive + the live catalogue) */
.wm-empty-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 0 12px; }
.wm-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 0 48px 28px;
}
.wm-pager-count {
  font-family: "JetBrains Mono", monospace;
  font-size: 12px;
  color: #556070;
}
/* ── The signed-out teaser: a closing band, not a hairline strip (operator
   2026-09-09) ────────────────────────────────────────────────────────────
   ⛔ THE MARGIN IS NOT SET HERE. `.wm-layout .wm-teaser` in
   wholesale-market-filters.css (0,2,0) and `.wcf .wm-teaser` in
   wholesale-catalog-faire.css both outrank a bare `.wm-teaser` whatever the
   order, and BOTH sheets load after this one — measured, not assumed: a
   margin written here computed to 0px on the live page. Geometry lives in the
   sheet that already owns it; only the LOOK lives here. */
/* Signed-out-only blocks (sign-up teasers): on the proxied host (closo.co/tools/…) PHP cannot see the buyer
   cookie and always prints them; wholesale-market.js marks <html class="wsm-viewer"> once the viewer chip
   answers «signed in» (and the stored hint does so before first paint). One rule for every such block. */
html.wsm-viewer [data-wsm-anon] { display: none !important; }
/* …and the mirror (edge-cache W3, 2026-09-29): a signed-in-only block the SHARED page prints hidden
   (the supplier's message button, the catalogue's Follow chip) shows once the chip says «signed in». */
html:not(.wsm-viewer) [data-wsm-viewer] { display: none !important; }
.wm-teaser {
  display: flex;
  gap: 18px;
  align-items: center;
  padding: 20px 24px;
  background: linear-gradient(160deg, #F8F5FD 0%, #EFEAF8 100%);
  border: 1px solid #E4DDF3;
  border-radius: 18px;
  box-shadow: 0 18px 40px -38px rgba(69, 43, 144, .5);
}
.wm-teaser-ic {
  flex: 0 0 42px; width: 42px; height: 42px; box-sizing: border-box; border-radius: 50%;
  background: #fff; border: 1px solid #EDE7F8; box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
  display: flex; align-items: center; justify-content: center;
}
.wm-teaser-ic svg { display: block; width: 20px; height: 20px; stroke: #452B90; }
.wm-teaser-tx { flex: 1; min-width: 0; }
.wm-teaser-tx b { display: block; font-family: "Poppins", Poppins Fallback, "Inter", Inter Fallback, system-ui, sans-serif; font-weight: 600; font-size: 15.5px; line-height: 1.3; color: #1A202C; }
.wm-teaser-tx > span { display: block; margin-top: 3px; font-size: 13.5px; line-height: 1.55; color: #5C6472; }
.wm-teaser-cta {
  flex: 0 0 auto;
  font: 600 13.5px/1 Inter, Inter Fallback, sans-serif;
  color: #FFFFFF; background: #452B90;
  border-radius: 999px; padding: 13px 24px; white-space: nowrap;
}
.wm-teaser-cta:hover { background: #321F69; color: #FFFFFF; }
/* The same plaque where the foreign guest's price was (lot page, 2026-09-25) and over the registry's
   «Elsewhere» reviews: in a column of its own, so the margin is its own too. */
.wm-teaser--guest { margin: 14px 0 12px; padding: 16px 20px; }
.wm-teaser--guest .wm-teaser-cta { text-decoration: none; }
/* «Unlock wholesale price →» in the lot's «What's inside» Price row. */
.wsl-unlock { color: #452B90; font-weight: 600; text-decoration: none; }
.wsl-unlock:hover { text-decoration: underline; }

/* ── footer ─────────────────────────────────────────────────────────── */
.wm-footer {
  display: flex;
  gap: 26px;
  align-items: center;
  padding: 18px 48px;
  border-top: 1px solid #E4E2EE;
  font-size: 12px;
  color: #556070;
}
.wm-footer a { color: #556070; }
.wm-footer a:hover { color: #321F69; }
.wm-footer .wm-wordmark { font-size: 12px; font-weight: 600; color: #1A202C; }
.wm-footer .wm-wordmark:hover { color: #321F69; }
.wm-footer-right { margin-left: auto; }

/* ── responsive ─────────────────────────────────────────────────────── */
@media (max-width: 980px) {
  .wm-header,
  .wm-nav,
  .wm-applied,
  .wm-filters,
  .wm-grid,
  .wm-pager,
  .wm-footer { padding-left: 24px; padding-right: 24px; }
  .wm-teaser { margin-left: 24px; margin-right: 24px; }
  .wm-grid, .wm-search-sup .wsf-sups { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
}

/* ⛔ THE HEADER STOPPED FITTING 170px BEFORE IT WAS ALLOWED TO REFLOW.
   Measured 2026-08-22: wordmark 150 + search 257 + CTA 321 plus gaps and
   padding is an intrinsic minimum of 811px, but the wrap rule below only
   starts at 640 — so every viewport from ~641 to ~810 pushed the document
   past the window and the whole page scrolled sideways. On the catalogue AND
   the lot page, since this is the shared chrome.

   Reflowing the header early is the fix, not shrinking the search: at 760 it
   is already at its content minimum, and squeezing it further buys pixels by
   making the field unusable. 860 rather than 820 leaves margin for a
   signed-in CTA, which is wider than the anonymous one this was measured on. */
@media (max-width: 860px) and (min-width: 641px) {
  .wm-header { flex-wrap: wrap; gap: 10px; }
  .wm-search { order: 3; flex-basis: 100%; max-width: none; }
  .wm-header-spacer { display: none; }
}

/* ── Touch doors: the burger IN THE HEADER (operator 2026-08-31) ──────────
   The benchmark pattern: on a phone or tablet the header keeps the wordmark,
   the search and one hamburger; the doors live behind it. Painted ONLY under
   the touch query, so a desktop never shows it even before the script runs. */
.wmfab { display: none; position: relative; }
.wmfab-btn { display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; color: #1A202C; background: transparent;
  border: 1px solid #E4E2EE; border-radius: 12px; cursor: pointer; padding: 0; }
.wmfab-btn:active { background: #F4F2FA; }
.wmfab-btn[aria-expanded="true"] { background: #EEEBF7; border-color: #452B90; color: #452B90; }
.wmfab-btn:focus-visible { outline: 2px solid #452B90; outline-offset: 2px; }
.wmfab-sheet { position: absolute; right: 0; top: calc(100% + 10px); z-index: 60;
  display: flex; flex-direction: column; gap: 4px; min-width: 216px;
  background: #FFFFFF; border: 1px solid #E4E2EE; border-radius: 16px; padding: 10px;
  box-shadow: 0 14px 38px rgba(26, 32, 44, .18); }
.wmfab-item { display: block; font-family: "Inter", Inter Fallback, sans-serif; font-weight: 500;
  font-size: 15px; color: #1A202C; text-decoration: none; padding: 11px 14px;
  border-radius: 10px; white-space: nowrap; }
/* ⛔ HOVER COLOURS ARE NOT OPTIONAL AND MUST NOT SIT BEHIND A MEDIA GATE.
   The sheet inherits the realm's global `:where(.wm) a:hover { color:#321F69 }`,
   and on the SOLID row that paints dark purple text on a purple button — the
   label disappears (operator 2026-08-31: «on My account hover I cannot see the text»). Gated behind (pointer: fine) the fix simply never reached a touch
   device, which is where the burger lives. So: every state of the solid row
   pins its own white, unconditionally, and the ghost rows pin theirs.
   Sticky hover on a touch screen is the lesser evil, and the sheet closes on
   the tap anyway. */
.wmfab-item:hover,
.wmfab-item:focus { background: #F4F2FA; color: #452B90; }
.wmfab-item-solid,
.wmfab-item-solid:link,
.wmfab-item-solid:visited,
.wmfab-item-solid:hover,
.wmfab-item-solid:focus,
.wmfab-item-solid:active { color: #FFFFFF; }
.wmfab-item-solid:hover { background: #3A2478; }
.wmfab-btn:hover { background: #F4F2FA; border-color: #D8D0F0; }
.wmfab-item { transition: background .12s ease, color .12s ease; }
.wmfab-item:focus-visible { outline: 2px solid #452B90; outline-offset: -2px; }
.wmfab-item:active { background: #F4F2FA; }
/* ⛔ The `hidden` ATTRIBUTE loses to a class that sets display. Without this
   rule the sheet is open on every page load and the button only closes it
   (operator 2026-08-31: «the burger must not show the menu until it is tapped»). Any class that sets display on an element the markup hides must
   carry its own [hidden] escape. */
.wmfab-sheet[hidden] { display: none; }
.wmfab-item-solid { background: #452B90; color: #FFFFFF; font-weight: 600; text-align: center; }
.wmfab-item-solid:active { background: #3A2478; }

@media (max-width: 1024px) { .wmfab { display: inline-flex; margin-left: auto; } }

/* The doors moved into the burger on phone AND tablet (operator 2026-08-31);
   a signed-in buyer keeps bag and saved, the two things a touch user actually
   reaches for mid-session. This query MUST match the one the burger script
   listens on, or a tablet shows both sets or neither. */
@media (max-width: 1024px) {
  .wm-header-cta .wm-btn-ghost,
  .wm-header-cta .wm-btn-solid { display: none; }
  /* The lot grid and its pager follow the storefront's one gutter (2026-09-07).
     Their COLUMN COUNT still changes at 640; only the horizontal padding moved
     here, where the chrome narrows. The catalogue's rail layout keeps its own
     `.wm-layout .wm-grid` rule — it is a different geometry, not a gutter. */
  .wm-grid, .wm-pager { padding-left: 16px; padding-right: 16px; }
  .wm-teaser { margin-left: 16px; margin-right: 16px; }
}

@media (max-width: 640px) {
  .wm-header {
    flex-wrap: wrap;
    gap: 10px;
    padding: 14px 16px;
  }
  .wm-search { order: 3; flex-basis: 100%; max-width: none; }
  .wm-header-spacer { display: none; }
  .wm-btn-ghost { padding: 10px 8px; }
  .wm-header-cta .wm-btn-ghost { padding: 9px 7px; }
  .wm-nav { padding: 0 16px; overflow-x: auto; }
  .wm-nav-count { display: none; }
  .wm-applied { padding: 12px 16px 0; }
  .wm-filters {
    padding: 12px 16px 2px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .wm-filters::-webkit-scrollbar { display: none; }
  .wm-sort { display: none; }
  .wm-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
    padding: 14px 16px 24px;
  }
  .wm-search-note { margin: 12px 0 10px; padding: 0 16px; }
  .wm-search-sup { margin: 16px 0 10px; }
  .wm-find-similar { opacity: 1; pointer-events: auto; right: 62px; } /* heart is 44px here */
  .wm-heart { width: 44px; height: 44px; }
  .wm-pager { padding: 0 16px 24px; }
  .wm-teaser { flex-wrap: wrap; }
  .wm-teaser-cta { width: 100%; text-align: center; box-sizing: border-box; }
  .wm-footer {
    padding: 16px;
    gap: 14px;
    flex-wrap: wrap;
  }
}

/* ── S1 polish: catnav · computed badges · quick add · saved heart ──────
 * Appended as a self-contained section (base rules first, own mobile
 * overrides last) — nothing above is reflowed. */

/* Category row — a slim strip of the top-6 categories under the nav. */
.wm-catnav {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px var(--wm-pad) 0; /* THE COLUMN's side (2026-09-27): the row scrolls edge to edge, its first pill on the gutter */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.wm-catnav::-webkit-scrollbar { display: none; }
.wm-catnav-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 600;
  color: #1A202C;
  background: #FAFAFC;
  border: 1px solid #E4E2EE;
  border-radius: 999px;
  padding: 7px 14px;
  white-space: nowrap;
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.wm-catnav-item span { font-weight: 500; color: #556070; }
.wm-catnav-item:hover { border-color: #452B90; color: #452B90; }
.wm-catnav-item.is-active {
  color: #452B90;
  background: #EDE8F8;
  border-color: #452B90;
}
.wm-catnav-item.is-active span { color: #452B90; }

/* Badge row — the manifest badge plus the computed New / Selling fast. */
.wm-badges {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 5px;
}
.wm-badge-new { color: #452B90; background: #EDE8F8; }
.wm-badge-fast { color: #B02E68; background: #FBE3EE; }
/* RECO behavioural badges — only ONE of the four ever prints on a card
 * (PalletMarketFeedService::signalBadge). Bestseller is the accent itself,
 * Trending sits one step down the same family. */
.wm-badge-bestseller { color: #FFFFFF; background: #452B90; }
.wm-badge-trending { color: #452B90; background: #FFFFFF; box-shadow: inset 0 0 0 1px #452B90; }
/* T2 (2026-10-20, D5): «Price cut N%» — leads the soft signals (signalBadge), the mockup's red pair. */
.wm-badge.wm-cut{color:#B4232C;background:#FDE7E9}

/* Quick add pill — top-right of the photo box; hover-revealed on desktop
 * (mirrors .wm-find-similar), persistent on mobile below. */
.wm-bag-add {
  position: absolute;
  z-index: 2;
  top: 10px;
  right: 10px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 600;
  background: rgba(255, 255, 255, 0.94);
  color: #1A202C;
  border-radius: 999px;
  padding: 6px 11px;
  box-shadow: 0 1px 4px rgba(26, 32, 44, 0.15);
  text-decoration: none;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}
/* SF-4 (2026-09-11, wsm_lean_cards): icon-only pills — same box, no words. */
.wm-bag-add--icon, .wm-find-similar--icon { padding: 7px; }
/* Lean icons share the top-right row: magnifier in the corner (13px glyph + 2×7 = 27px),
 * bag 8px left of it. Doubled class so the phone block's text-pill padding (5px 9px, below)
 * does not reshape the icon bag: both icons stay 27-28px squares on every width. */
.wm-find-similar--icon { top: 10px; bottom: auto; right: 10px; }
.wm-bag-add.wm-bag-add--icon { right: 45px; padding: 7px; }
.wm-photo-count svg { vertical-align: -1px; margin-right: 4px; }
.wm-bag-add:hover {
  color: #452B90;
  box-shadow: 0 1px 4px rgba(26, 32, 44, 0.15), inset 0 0 0 1px #452B90;
}
.wm-card:hover .wm-bag-add,
.wm-card:focus-within .wm-bag-add {
  opacity: 1;
  pointer-events: auto;
}
.wm-bag-add.is-on {
  background: #452B90;
  color: #fff;
}
.wm-bag-add.is-on:hover { background: #321F69; color: #fff; }

/* Saved heart — active state is the filled /w/ storefront red. */
.wm-heart.is-on { color: #B3261E; }
.wm-heart.is-on svg path { fill: #B3261E; stroke: #B3261E; }

/* Load-more counter label inside the anchor. */
.wm-lm-n {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  font-weight: 500;
  color: #556070;
  margin-left: 8px;
}

@media (max-width: 640px) {
  .wm-catnav { padding-top: 10px; }
  /* No hover on touch — the pill is a persistent small control. */
  .wm-bag-add {
    opacity: 1;
    pointer-events: auto;
    padding: 5px 9px;
  }
}

/* ── W1 mobile audit (360-430px pass) ────────────────────────────────────
 * Appended, self-contained: touch tap targets ≥44px on the shared chrome
 * controls, iOS-zoom-proof inputs, and a header cluster that holds one row
 * at 360px. Nothing above is reflowed on desktop. */
@media (max-width: 640px) {
  /* Tap targets: chips / category pills / door buttons reach ≥44px tall. */
  .wm-chip { padding: 11px 15px; }
  .wm-catnav-item { padding: 11px 14px; }
  .wm-btn-ghost { padding-top: 12px; padding-bottom: 12px; }
  .wm-btn-solid { padding: 12px 16px; }
  .wm-header-cta .wm-btn-ghost { padding-top: 11px; padding-bottom: 11px; }
  .wm-header-cta .wm-btn-solid { padding: 11px 15px; }
  .wm-btn-outline { padding-top: 12px; padding-bottom: 12px; }
  .wm-tab { padding-top: 14px; padding-bottom: 14px; }
  /* Header cluster: tighter gaps so wordmark + Log in + Sign up hold one
   * row at 360px (the search box already wraps to its own full row).
   * `margin-left:auto` re-does the spacer's job on mobile (operator
   * 2026-08-21: «nudge it a bit to the right — it sits dead centre now»):
   * the wrap pass hides .wm-header-spacer, which left the cluster sitting
   * beside the wordmark mid-row; auto-margin pins it to the right edge,
   * matching the desktop layout. Covers BOTH clusters — the signed-out
   * door buttons and the signed-in guide/saved/bag/account icons. */
  .wm-header { gap: 8px; }
  .wm-header-cta { gap: 6px; margin-left: auto; }
  /* 16px input font — iOS Safari must not zoom the page on focus. */
  .wm-search { padding: 11px 16px; }
  .wm-search input { font-size: 16px; }
}

/* ── Faire-width viewports (operator 2026-08-19): the 1720px shell adds grid
 * columns instead of stretching three cards. ── */
@media (min-width: 1200px) {
  .wm-grid, .wm-search-sup .wsf-sups { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* Rail hidden -> the freed width is a fifth card, not fatter cards. */
  .wm-layout.filters-off .wm-grid, .wm-layout.filters-off .wm-search-sup .wsf-sups { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
@media (min-width: 1600px) {
  .wm-grid, .wm-search-sup .wsf-sups { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 24px; }
}

/* ── Rich category header (operator 2026-08-19, Faire frame; rev 4 —
 * «expensive-looking»: label BELOW the photo, no scrim, cohesive studio photo set,
 * generous whitespace. DOM unchanged: .wm-cattile-ph, <b>, <span>. ── */
/* horizontal padding from the shared centring rule (2026-09-07): it used
   to hold 48px down to 640 while the page around it narrowed at 1024. */
.wm-cathead { padding: 28px 0 0; }
/* Brand page header (grouping spec wave 4, mockup D): mono initial 56px / 12px radius,
   16px gap, title 22px, line 12.5px — the mockup's own values, on the page's padding. */
.wm-brandhead { display: flex; align-items: center; gap: 16px; padding-top: 28px; margin-bottom: 14px; }
.wm-brandhead-mono { width: 56px; height: 56px; border-radius: 12px; background: #1A202C; color: #fff; display: grid; place-items: center; font-weight: 800; font-size: 20px; flex: none; }
.wm-brandhead-title { margin: 0; font-family: "Poppins", Poppins Fallback, "Inter", Inter Fallback, sans-serif; font-size: 22px; font-weight: 700; color: #1A202C; }
.wm-brandhead-sub { margin: 2px 0 0; color: #556070; font-size: 12.5px; }
/* «<Brand> inside: N pcs · models» on a card (mockup D). */
.wm-card-inside { font-size: 11.5px; color: #452B90; background: #F6F3FC; border-radius: 6px; padding: 4px 7px; margin: 2px 0 4px; }
.wm-card-inside b { font-weight: 700; }
/* A page without the rail (brand page): no filter buttons, the grid keeps the page gutter. */
.wm-main--norail .wm-filters-open, .wm-main--norail .wm-rail-toggle { display: none; }
/* The Faire catalog sheet re-shows the phone «Filters» button at 0,3,0 — outrank it. */
.wcf .wm-main--norail .wm-toolbar .wm-filters-open { display: none; }
/* The rail-less column's gutter lives in wholesale-market-filters.css («NO RAIL,
   ONE LEFT EDGE»): a rule here lost to that sheet's `.wm-layout …` rules on
   source order and left the brand pages with two left edges (2026-09-23). */
.wm-cathead-title {
  margin: 0;
  font-family: "Poppins", Poppins Fallback, "Inter", Inter Fallback, sans-serif;
  font-weight: 600;
  font-size: 27px;
  letter-spacing: -0.01em;
  color: #1A202C;
}
.wm-cathead-sub { margin: 6px 0 0; font-size: 14px; color: #556070; max-width: 72ch; }
/* Faire's category carousel (operator 2026-09-11): ONE row, tiles of a fixed width,
   the row scrolls sideways when they do not fit — never wraps into a second row.
   Scrollbar hidden, snap to a tile; the arrows (.wm-catnav-arrow) sit over the
   edges of the row and are revealed by the script only when there is overflow. */
.wm-catnav-wrap { position: relative; }
.wm-catnav.is-rich {
  display: flex;
  /* Tiles hang from the top (2026-09-23). The pill row's `align-items: center`
     (.wm-catnav) centred a one-line tile beside a two-line one («General
     Merchandise») ~9px lower on a phone, so heading → tiles read 14 or 22.8
     depending on which tiles were in view. */
  align-items: flex-start;
  gap: 20px;
  padding: 20px var(--wm-pad) 6px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  scroll-behavior: smooth;
  scroll-padding-left: var(--wm-pad);
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.wm-catnav.is-rich::-webkit-scrollbar { display: none; }
.wm-catnav.is-rich > .wm-cattile { flex: 0 0 176px; scroll-snap-align: start; }
.wm-catnav-arrow {
  position: absolute;
  top: 67px;                  /* 20px row padding + half of the 132px photo (176 wide, 4:3) − 19px: centred on the photo */
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid #E4E2EE;
  border-radius: 999px;
  background: #fff;
  color: #1A202C;
  box-shadow: 0 6px 18px rgba(26, 32, 44, 0.14);
  cursor: pointer;
  z-index: 2;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.wm-catnav-arrow > svg { width: 17px; height: 17px; display: block; }
/* on the column's edges, not in the gutter (THE COLUMN, 2026-09-27): the row bleeds, its controls do not */
.wm-catnav-arrow.is-prev { left: var(--wm-pad); }
.wm-catnav-arrow.is-next { right: var(--wm-pad); }
.wm-catnav-arrow:hover:not(:disabled) { border-color: #452B90; color: #452B90; background: #F7F5FC; }
.wm-catnav-arrow:disabled { opacity: 0; pointer-events: none; }
.wm-catnav-arrow[hidden] { display: none !important; }
@media (prefers-reduced-motion: reduce) { .wm-catnav.is-rich { scroll-behavior: auto; } }
.wm-cattile {
  display: block;
  text-decoration: none;
  color: #1A202C;
}
.wm-cattile-ph {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: 14px;
  border: 1px solid #ECEAF2;
  background: linear-gradient(135deg, #F1EFE9, #E7E3D9);
  background-size: cover;
  background-position: center;
  transition: box-shadow 0.18s ease, transform 0.18s ease;
}
.wm-cattile:hover .wm-cattile-ph {
  transform: translateY(-2px);
  box-shadow: 0 12px 28px rgba(26, 32, 44, 0.13);
}
.wm-cattile b {
  display: block;
  margin-top: 10px;
  font-family: "Poppins", Poppins Fallback, "Inter", Inter Fallback, sans-serif;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.3;
  color: #1A202C;
}
/* Two lines, always reserved, in the rich row (2026-09-23, review P2-1): a
   two-line label («Hoodies & Sweatshirts», «Women's Clothing Pallets») set the
   whole row's height even when that tile was scrolled out of view, so the gap
   from the tiles to the format tabs changed from shelf to shelf with whichever
   labels happened to wrap. Every label now takes exactly two lines of height —
   one-line names keep the second line empty, longer ones wrap (a third line is
   clamped) — so the row is one height on every shelf and no name is cut short
   (the coordinator ruled out a one-line ellipsis on a primary navigation row). */
.wm-catnav.is-rich .wm-cattile b { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; min-height: 2.6em; max-height: 2.6em; }
/* …and the tile keeps its width: a flex item's min-width is its content, so a
   long unbroken name widened its tile (182 instead of 176) and scaled its photo up. */
.wm-catnav.is-rich > .wm-cattile { min-width: 0; }
.wm-cattile:hover b { color: #452B90; }
.wm-cattile.is-active .wm-cattile-ph { box-shadow: 0 0 0 2.5px #452B90; }
.wm-cattile.is-active b { color: #452B90; }
@media (max-width: 640px) {
  .wm-cathead { padding-top: 18px; }
  .wm-brandhead { padding-top: 18px; }
  .wm-brandhead-title { font-size: 21px; }
  .wm-cathead-title { font-size: 21px; }
  .wm-catnav.is-rich { padding-top: 14px; padding-bottom: 4px; gap: 14px; }
  .wm-catnav.is-rich > .wm-cattile { flex-basis: 150px; }
  .wm-catnav-arrow { display: none !important; }   /* a thumb scrolls the row on a phone */
}


/* ═══ PROMO STRIP — SHARED (moved out of wholesale-market-home.css,
 * 2026-08-20). The operator asked for the same band on the catalogue, and
 * the catalogue does not load the home sheet, so the component lives in the
 * one sheet BOTH surfaces load. WIDTH IS DELIBERATELY NOT SET HERE: the home
 * sheet caps it at 1200px alongside its siblings, while the catalogue is
 * full-bleed and the 48px padding below already matches .wm-grid's gutter. */
/* ── promo rail (operator 2026-08-19 rev 2: marketplace promo panels, NOT
 * SaaS chips — a tinted panel each, oversized display type, a watermark
 * glyph, an underlined CTA. Still by default; arrows move it. ── */
.wsm-promo { padding: 30px var(--wm-pad) 6px; }
.wsm-promo-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}
.wsm-promo-nav { display: flex; gap: 8px; }
.wsm-promo-nav[hidden] { display: none !important; }
.wsm-promo-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: 1px solid #E4E2EE;
  border-radius: 999px;
  background: #fff;
  color: #1A202C;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.wsm-promo-arrow:hover:not(:disabled) { border-color: #452B90; color: #452B90; background: #F7F5FC; }
.wsm-promo-arrow:disabled { opacity: 0.35; cursor: default; }
.wsm-promo-rail {
  /* A SHELF the reader moves with the arrows (operator 2026-08-20: "like before, with the arrows"). The band is the same 48px gutter every other home
     section uses — verified against the DOM, not assumed — and the card width
     below is derived FROM this container so a whole number of cards fills it
     exactly. That is what keeps the row flush with the page: nothing is ever
     half-visible at the right edge, which is what made earlier revisions read
     as wider than the page. */
  display: flex;
  gap: 16px;
  max-width: 100%;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding-bottom: 4px;
}
.wsm-promo-rail::-webkit-scrollbar { display: none; }
.wsm-promo-card {
  /* Four cards plus their three 16px gaps equal the band exactly, at any
     viewport. A FIXED pixel width cannot do that -- five fixed cards overflow a
     narrower band and the fifth is sliced at the gutter. min-width:0 is the
     other half: a flex item defaults to min-width:auto, so long copy could
     still push a card past its basis. */
  /* ⛔ BORDER-BOX, AND THE calc ABOVE IS WHY. Without it the card's own 20px
     side padding is ADDED to the computed basis — 288 becomes 328 — so four
     cards need 1360 of a 1200 band and the fourth is sliced at the edge.
     Measured on a headless render: cards 328px wide, gaps 16px, band 1200px. */
  box-sizing: border-box;
  flex: 0 0 calc((100% - 48px) / 4);
  min-width: 0;
  max-width: 100%;
  scroll-snap-align: start;
  position: relative;
  overflow: hidden;
  min-height: 136px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 8px;
  padding: 18px 20px;
  border-radius: 16px;
  text-decoration: none;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.wsm-promo-card:hover {
  transform: translateY(-2px);
  box-shadow: inset 0 0 0 1px rgba(26, 32, 44, 0.10), 0 14px 30px -16px rgba(26, 32, 44, 0.30);
}
/* The watermark: oversized, low-contrast, bleeding off the corner — the
   panel carries the art so the type can stay quiet. */
.wsm-promo-mark {
  position: absolute;
  top: -14px;
  right: -12px;
  width: 96px;
  height: 96px;
  opacity: 0.15;
  pointer-events: none;
}
.wsm-promo-mark svg { width: 100%; height: 100%; }
.wsm-promo-title {
  position: relative;
  font-family: "Poppins", Poppins Fallback, "Inter", Inter Fallback, sans-serif;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.28;
  letter-spacing: -0.01em;
  max-width: 18ch;
}
.wsm-promo-cta {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 600;
  padding-bottom: 1px;
  border-bottom: 1.5px solid currentColor;
  align-self: flex-start;
}
.wsm-promo-cta svg { width: 13px; height: 13px; }
/* Five tints, cycled by position — adjacent panels never repeat. */
.wsm-promo-a { background: linear-gradient(150deg, #EDE8F8 0%, #DCD3F2 100%); color: #2B1A5E; }
.wsm-promo-a .wsm-promo-mark { color: #452B90; }
.wsm-promo-b { background: linear-gradient(150deg, #E4F3EC 0%, #CDE9DC 100%); color: #14432F; }
.wsm-promo-b .wsm-promo-mark { color: #186A3B; }
.wsm-promo-c { background: linear-gradient(150deg, #E6EEFA 0%, #D2E1F6 100%); color: #163458; }
.wsm-promo-c .wsm-promo-mark { color: #1D5FBF; }
.wsm-promo-d { background: linear-gradient(150deg, #F6EFE4 0%, #EBDCC6 100%); color: #4A3720; }
.wsm-promo-d .wsm-promo-mark { color: #8A5A2B; }
.wsm-promo-e { background: linear-gradient(150deg, #FBE9F1 0%, #F4D3E2 100%); color: #5C1F3B; }
.wsm-promo-e .wsm-promo-mark { color: #B02E68; }
@media (max-width: 760px) {
  /* Phones: one card at a time, snapped, still fixed-scale. */
  .wsm-promo-card { flex-basis: calc((100% - 16px) / 2); }
}
@media (max-width: 640px) {
  .wsm-promo { padding: 22px var(--wm-pad) 2px; }
  .wsm-promo-card { flex-basis: 86%; }
  .wsm-promo-card { min-height: 128px; padding: 16px 18px; }
  .wsm-promo-title { font-size: 15px; }
}

/* ── Card tag row (operator 2026-08-20): free-shipping eligibility, the
 * supplier's own sale, and the supplier's rating. Each element renders only
 * when the service stamped the field behind it, so an empty row never draws. */
.wm-card-tags {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 9px;
  padding-top: 9px;
  border-top: 1px solid #F0EEF6;
}
.wm-tag {
  font-size: 11px;
  font-weight: 600;
  line-height: 1.35;
  padding: 3px 8px;
  border-radius: 999px;
  white-space: nowrap;
}
.wm-tag-ship { background: #EAF6EE; color: #1B6B3A; }
.wm-tag-sale { background: #FDECEC; color: #B42318; }
/* The rating moved up to the supplier line (2026-08-20): it describes the
 * SUPPLIER, and sitting among the lot's own tags made it read as a fact about
 * the lot. */
.wm-card-rating {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 11.5px;
  color: #556070;
  white-space: nowrap;
}
.wm-card-rating svg { color: #E8A33D; flex: none; }
.wm-card-rating b { color: #1A202C; font-weight: 600; }
@media (max-width: 640px) {
  .wm-tag { font-size: 10.5px; padding: 3px 7px; }
}

/* ── Supplier line (operator 2026-08-20): who is selling, above the price. */
.wm-card-supplier {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 2px;
  min-width: 0;
}
.wm-supplier-link, .wm-supplier-name {
  font-size: 12.5px;
  font-weight: 600;
  color: #556070;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
/* ⛔ ABOVE THE CARD'S STRETCHED OVERLAY LINK, or the click never lands here.
 *    .wm-card-link is position:absolute; inset:0; z-index:1. */
.wm-supplier-link {
  position: relative;
  z-index: 2;
  text-decoration: none;
}
.wm-supplier-link:hover { color: #452B90; text-decoration: underline; }
.wm-card-supplier .wm-card-rating { margin-left: auto; }

/* ── Card strips on the lot page (2026-08-20). They render `_card`, the same
 * partial the catalogue renders, so they need only a track count — every other
 * rule the card carries itself. Four across, because a lot page is narrower
 * than the catalogue once its own column is accounted for. */
.wsp-reco-grid, .wsl-similar-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  padding: 0;
  gap: 18px;
}
@media (max-width: 1100px) {
  .wsp-reco-grid, .wsl-similar-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .wsp-reco-grid, .wsl-similar-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 480px) {
  .wsp-reco-grid, .wsl-similar-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ── Header that comes back when you scroll up (operator 2026-08-20) ───────
   The top-tier marketplace pattern, Faire's included: scrolling DOWN gets out
   of the way, scrolling UP brings the bar straight back, so search and the
   bag are one gesture away from anywhere on a long catalogue.

   ⛔ `transform` HERE MAKES THIS ELEMENT THE CONTAINING BLOCK FOR ANY
      `position: fixed` DESCENDANT. The confirmation panel is one, so it is
      moved to <body> when it opens — otherwise it would ride the header out
      of view mid-scroll. If anything else fixed is ever added inside the
      header, it needs the same treatment.

   A background is mandatory: the header declared none, which is invisible
   while it sits in the flow and shows the page through it once it sticks. */
.wm-header {
  position: sticky;
  top: 0;
  z-index: 45;
  background: #fff;
  transition: transform 0.24s ease;
}
.wm-header.is-tucked { transform: translateY(-100%); }

@media (prefers-reduced-motion: reduce) {
  .wm-header { transition: none; }
}

/* ── Quiet button system (operator 2026-09-04, direction A of artifact f306bcd2): one height, one
   radius, one weight, one accent; secondaries white with one thin rule; icon buttons are circles
   of the same rule; hover = rule to the accent + a lilac ground. No rings, no shadows. ── */
.wm-header-cta .wm-btn-ghost,.wm-header-cta .wm-btn-solid,.wm-header-cta .wmb-icon{height:36px;border-radius:999px;font-size:13.5px;font-weight:600;display:inline-flex;align-items:center;justify-content:center;transition:background .15s,border-color .15s,color .15s}
.wm-header-cta .wm-btn-ghost{background:#fff;border:1px solid #D9D6E6;color:#1A202C;padding:0 14px}
.wm-header-cta .wm-btn-ghost:hover{border-color:#452B90;background:#F7F4FD;color:#1A202C}
.wm-header-cta .wm-btn-solid{background:#452B90;border:1px solid #452B90;color:#fff;padding:0 16px}
.wm-header-cta .wm-btn-solid:hover{background:#321F69;border-color:#321F69}
.wm-header-cta .wmb-icon{width:36px;background:#fff;border:1px solid #D9D6E6;color:#1A202C}
.wm-header-cta .wmb-icon:hover{border-color:#452B90;background:#F7F4FD}
.wsm-hero-ctas a{height:46px;display:inline-flex;align-items:center;justify-content:center;padding:0 24px;border-radius:999px;font-weight:600;font-size:15px}
.wsm-hero-ctas .wsm-cta-primary{background:#452B90;border:1px solid #452B90;color:#fff}
.wsm-hero-ctas .wsm-cta-primary:hover{background:#321F69;border-color:#321F69}
.wsm-hero-ctas .wsm-cta-secondary{background:#fff;border:1px solid #D9D6E6;color:#1A202C;transition:background .15s,border-color .15s}
.wsm-hero-ctas .wsm-cta-secondary:hover{border-color:#452B90;background:#F7F4FD;color:#1A202C}

/* ── Shelf pages /wholesale/c/<slug> (shop-SEO S-2, 2026-09-04): the intro
 * paragraph under the category header and the FAQ under the grid. Same
 * tokens as .wm-cathead-sub / .wm-teaser; script-free <details>. ── */
.wm-catintro { padding: 10px var(--wm-pad) 0; }
.wm-catintro p { margin: 0; max-width: 84ch; font-size: 14px; line-height: 1.6; color: #556070; }
/* ── The shelf's closing band: «About …» + FAQ (2026-09-09, operator
   «elegant, rich and expensive-looking» by the Faire benchmark) ───────────────────────
   TWO blocks that had been the marketplace's last private designs — the
   About paragraph was a bare <details> under a 20px heading, and the FAQ a
   grey box with «+» characters while every other page on the storefront
   already shared the accordion below. Both now read as one editorial band:
   a hairline, an eyebrow, a 30px head, and a card of what the shelf
   guarantees beside the copy.

   GUTTER: neither block brings its own — `.wm-about` and `.wsf-faq` are both
   in the shared centring rule (wholesale-market-faire.css), so they sit on
   the same edge as the grid at every width. */
.wm-about {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: 56px;
  align-items: start;
  margin-top: 44px;
  padding-top: 38px;
  border-top: 1px solid #ECEAF2;
}
.wm-about-l { min-width: 0; }
.wm-about-h {
  margin: 10px 0 14px;
  font-family: "Poppins", Poppins Fallback, "Inter", Inter Fallback, system-ui, sans-serif;
  font-weight: 600; font-size: 30px; line-height: 1.14; letter-spacing: -.024em;
  color: #1A202C; max-width: 20ch;
}
.wm-about-lead { margin: 0; font-size: 16.5px; line-height: 1.7; color: #3F4756; max-width: 60ch; }
.wm-about-more > p { margin: 16px 0 0; font-size: 15.5px; line-height: 1.72; color: #556070; max-width: 58ch; }
.wm-about-more > summary {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 9px;
  margin-top: 18px; padding: 10px 20px;
  border: 1.5px solid #DED6F1; border-radius: 999px; background: #fff;
  font: 600 13.5px/1 Inter, Inter Fallback, sans-serif; color: #452B90;
  transition: border-color .14s, background-color .14s;
}
.wm-about-more > summary::-webkit-details-marker { display: none; }
.wm-about-more > summary::marker { content: ""; }
.wm-about-more > summary::after {
  content: ""; width: 13px; height: 13px; flex: 0 0 auto;
  background: center/13px 13px no-repeat url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23452B90' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");
  transition: transform .18s;
}
.wm-about-more > summary:hover { border-color: #452B90; background: #F7F5FC; }
.wm-about-more > summary:focus-visible { outline: 2px solid #452B90; outline-offset: 2px; }
/* Open, the button belongs UNDER the text it revealed, not above it. */
.wm-about-more[open] { display: flex; flex-direction: column; align-items: flex-start; }
.wm-about-more[open] > summary { order: 2; margin-top: 20px; }
.wm-about-more[open] > summary::after { transform: rotate(180deg); }
.wm-about-more > summary .a-close { display: none; }
.wm-about-more[open] > summary .a-open { display: none; }
.wm-about-more[open] > summary .a-close { display: inline; }

/* What every lot on this shelf carries — the promo strip's glyphs
   (WholesalePromoGlyphs), so the art is the same wherever a claim appears. */
.wm-about-r {
  background: linear-gradient(180deg, #FCFBFE 0%, #F5F2FC 100%);
  border: 1px solid #EAE4F7; border-radius: 20px;
  padding: 22px 24px 8px;
  box-shadow: 0 18px 40px -30px rgba(69, 43, 144, .45);
}
.wm-about-r-h {
  display: block; margin: 0 0 10px; padding-bottom: 12px; border-bottom: 1px solid #EDE7F8;
  font: 700 11.5px/1.2 Inter, Inter Fallback, sans-serif; letter-spacing: .085em; text-transform: uppercase; color: #6B5AA6;
}
.wm-about-facts { list-style: none; margin: 0; padding: 0; }
.wm-about-facts li { display: flex; gap: 14px; align-items: flex-start; padding: 15px 0; border-top: 1px solid #EDE7F8; }
.wm-about-facts li:first-child { border-top: 0; padding-top: 2px; }
/* box-sizing is content-box here, so the border has to be inside the 40px or
   the circle is 42 and the row's baseline shifts with it. */
.wm-about-ic {
  flex: 0 0 40px; width: 40px; height: 40px; box-sizing: border-box; border-radius: 50%;
  background: #fff; border: 1px solid #EDE7F8; box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
  display: flex; align-items: center; justify-content: center;
}
.wm-about-ic svg { display: block; width: 20px; height: 20px; stroke: #452B90; stroke-width: 1.5; }
.wm-about-facts li > div { min-width: 0; }
/* ⛔ SCOPED TO THE TEXT COLUMN ON PURPOSE. A bare `.wm-about-facts span` also
   matches the icon's own <span> — and it outranks `.wm-about-ic` on
   specificity, whatever the order — so the glyph inherited `display: block`
   and sat in the top-left corner of its circle instead of the middle of it. */
.wm-about-facts li > div > b { display: block; font: 600 14.5px/1.35 Inter, Inter Fallback, sans-serif; color: #1A202C; }
.wm-about-facts li > div > span { display: block; margin-top: 3px; font: 400 13px/1.55 Inter, Inter Fallback, sans-serif; color: #5C6472; }

/* The shelf FAQ is the storefront's standard two-column section head over the
   one accordion below (.pgq). Only the band's rhythm lives here. */
.wm-catfaq { padding-top: 40px; padding-bottom: 8px; margin-top: 40px; border-top: 1px solid #ECEAF2; }
.wm-guides { padding-top: 40px; margin-top: 40px; border-top: 1px solid #ECEAF2; }
.wm-catfaq-h {
  margin: 0 0 10px;
  font-family: "Poppins", Poppins Fallback, "Inter", Inter Fallback, system-ui, sans-serif;
  font-weight: 600; font-size: 30px; line-height: 1.14; letter-spacing: -.024em; color: #1A202C;
}
.wm-catfaq .wsf-faq-l p { margin: 0; font-size: 14.5px; line-height: 1.6; color: #556070; max-width: 38ch; }

@media (max-width: 1024px) {
  .wm-about { grid-template-columns: 1fr; gap: 26px; margin-top: 34px; padding-top: 28px; }
  .wm-about-h { font-size: 22px; max-width: none; margin-top: 8px; }
  .wm-about-lead { font-size: 15.5px; }
  .wm-about-more > p { font-size: 15px; }
  .wm-about-r { padding: 20px 18px 4px; border-radius: 16px; }
  /* the shelf band stacks at 1024 (where the storefront gutter changes) — the
     catalogue's main column is already narrowed by the filter rail */
  /* TWO classes on purpose: the shared `.wsf-faq` grid is defined further
     down this file at the same (0,1,0) weight, so a single class here
     loses on source order and the FAQ stayed two-column at 761–1024. */
  .wsf-faq.wm-catfaq { grid-template-columns: 1fr; gap: 14px; }
  .wm-catfaq { padding-top: 30px; margin-top: 32px; }
  .wm-catfaq-h { font-size: 22px; }
  .wm-catfaq .wsf-faq-l p { max-width: none; margin-bottom: 4px; }
}
/* On a phone the lead is clamped until the fold opens, so the card is not
   pushed below nine lines of prose. @supports-guarded on purpose: a browser
   without :has() shows the WHOLE lead rather than a truncation it has no way
   to open. */
@supports selector(:has(*)) {
  @media (max-width: 1024px) {
    /* ⛔ CLAMP ONLY WHERE THERE IS A CONTROL THAT OPENS IT. The view emits no
       <details> when the copy is a single sentence ($rest === ''), and a bare
       `.wm-about-lead` clamp then hid the tail of that sentence on every phone
       with nothing on the page able to reveal it. */
    .wm-about-l:has(.wm-about-more) .wm-about-lead { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; overflow: hidden; }
    .wm-about-l:has(.wm-about-more[open]) .wm-about-lead { display: block; overflow: visible; }
  }
}
@media (max-width: 640px) {
  .wm-catintro { padding: 8px var(--wm-pad) 0; }
}

/* ── Ranking surface (W2, 2026-09-06) ─────────────────────────────────────
   «In demand» is the ranking's own badge: the lot's contents are in the top
   15 % of their category by what they actually do on the resale market. It
   is filled, not outlined, because it outranks every storefront signal in
   PalletMarketFeedService::SIGNAL_BADGES and the card should read that way
   at a glance. The resale line under the price carries the one sentence the
   ranking will say publicly — the return itself is not on a shared-cached
   card at all. */
.wm-badge-demand { color: #FFFFFF; background: #0F7B4F; }
.wm-card-resale {
  display: flex; align-items: center; gap: 5px;
  margin-top: 4px; font-size: 12px; line-height: 1.35; color: #4B5563;
}
.wm-card-resale svg { flex: 0 0 auto; opacity: .7; }
.wm-card-resale > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Format tabs (grouping spec wave 1, 2026-09-06): the «size of the deal»
   axis above the rail + grid. Chips, not tabs, so they match the filter
   vocabulary; horizontal scroll on the phone like the category strip. ── */
.wm-fmt-tabs { display: flex; gap: 8px; padding: 6px var(--wm-pad) 0; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.wm-fmt-tabs::-webkit-scrollbar { display: none; }
/* «Shop <brand> by category» on the wholesale brand page (hub-linking wave B): a chip row
   above the format tabs — 12px between the two rows, the chip rhythm of the shelves. */
.wm-brand-kids { padding-top: 12px; margin-bottom: 4px; }
.wm-fmt-tabs .wm-chip { flex: none; }
/* ── The shelf bar (operator 2026-09-12: «three different chip types that look the same»). Three rows of identical chips had meant three different
   things — a filter of THIS page, two neighbour pages, the resale bridge.
   Now ONE row: the format tabs as a segmented control on the left, the
   shelf's list pages as quiet text links on the right; the bridge went to
   the foot rails as a «Related searches»-family section. GUTTER: `.wm-shelf-bar`
   is in the shared centring rule (wholesale-market-faire.css) — the tabs'
   own 48px is zeroed inside it. ── */
.wm-shelf-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px 24px; flex-wrap: wrap; padding-top: 10px; }
.wm-shelf-bar .wm-fmt-tabs { padding: 0; }
/* The segmented control: a wash track, the active segment lifted white. The
   chips keep .wm-chip / .is-on for the live swap; the look is the track's. */
.wm-seg { display: inline-flex; gap: 2px; padding: 3px; border-radius: 999px; background: #F1EFF6; max-width: 100%; box-sizing: border-box; }
.wm-seg .wm-chip { border: 0; background: transparent; color: #556070; font-weight: 600; font-size: 13.5px; line-height: 1; padding: 9px 16px; border-radius: 999px; box-shadow: none; transition: background .15s, color .15s; }
.wm-seg .wm-chip:hover { color: #1A202C; background: rgba(255, 255, 255, .55); border: 0; }
.wm-seg .wm-chip.is-on { background: #fff; color: #1A202C; box-shadow: 0 1px 2px rgba(15, 23, 42, .10), 0 0 0 1px rgba(69, 43, 144, .06); }
/* The list pages: an axis label + glyph links (_shelf_views.php). */
.wm-views { display: flex; align-items: center; gap: 6px 20px; flex-wrap: wrap; min-width: 0; }
.wm-views-lead { font: 600 11.5px/1 Inter, Inter Fallback, sans-serif; letter-spacing: .07em; text-transform: uppercase; color: #6B6880; white-space: nowrap; }
.wm-view { display: inline-flex; align-items: center; gap: 7px; font: 600 13.5px/1 Inter, Inter Fallback, sans-serif; color: #452B90; padding: 8px 0; text-decoration: none; white-space: nowrap; }
.wm-view svg { width: 16px; height: 16px; stroke: currentColor; stroke-width: 1.8; fill: none; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.wm-view:hover { text-decoration: underline; text-underline-offset: 4px; color: #452B90; }
@media (max-width: 640px) {
  .wm-shelf-bar { align-items: flex-start; gap: 8px; }
  .wm-seg { overflow-x: auto; scrollbar-width: none; }
  /* the chip's phone size (36px, ≤960 below) applies to the segments as well */
  .wm-views { gap: 4px 16px; }
  .wm-views-lead { display: none; }
}
.wm-fmt-tabs .wm-chip b { color: #556070; font-weight: 700; margin-left: 4px; font-variant-numeric: tabular-nums; }
.wm-fmt-tabs .wm-chip.is-on b { color: #452B90; }
/* Phone pills 36px tall like Faire's filter row — min-height on a content-box
   chip added its 11px paddings on top and stood 64px (operator 2026-09-07). */
@media (max-width: 960px) { .wm-fmt-tabs { padding-left: var(--wm-pad); padding-right: var(--wm-pad); } .wm-fmt-tabs .wm-chip { box-sizing: border-box; min-height: 36px; padding: 0 14px; font-size: 13px; display: inline-flex; align-items: center; } }

/* ── Form controls — ONE look for every native <select>, text-like <input>
   and <textarea> on the marketplace (operator 2026-09-08: the OS-default
   select in the Lot Drop band «looks like Windows 95», and every dropdown and
   input must match the benchmark). Element-scoped on purpose, specificity
   (0,2,1) so it beats the per-surface `.x select {}` rules that each page grew
   on its own; a surface that needs the raw control adds `.wsm-native`. The
   header search, the filter-rail range inputs and the assistant keep their
   own composed designs. The OPEN list of a native select is painted by the OS
   and cannot be styled — a composed listbox is a separate wave. */
body select:not(.wsm-native):not([multiple]):not(.wm-header *):not(.wm-search *):not(.rgc-search *):not(.wm-rail-range *):not(.wsa *):not(.ca *),
body input:not(.wsm-native):is([type="text"],[type="email"],[type="number"],[type="search"],[type="tel"],[type="url"],[type="password"],[type="date"]):not(.wm-header *):not(.wm-search *):not(.rgc-search *):not(.wm-rail-range *):not(.wsa *):not(.ca *):not(.ld-hp),
body textarea:not(.wsm-native):not(.wm-header *):not(.wsa *):not(.ca *) {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  margin: 0;
  font: 400 14px/1.4 Inter, Inter Fallback, -apple-system, "Segoe UI", sans-serif;
  color: #0F1729;
  background: #fff;
  border: 1px solid #E2E8F0;
  border-radius: 10px;
  padding: 11px 14px;
  min-height: 44px;
  outline: none;
  box-shadow: none;
  transition: border-color .15s, box-shadow .15s;
  -webkit-appearance: none;
  appearance: none;
}
body textarea:not(.wsm-native):not(.wm-header *):not(.wsa *):not(.ca *) { min-height: 96px; resize: vertical; }
body select:not(.wsm-native):not([multiple]):not(.wm-header *):not(.wm-search *):not(.rgc-search *):not(.wm-rail-range *):not(.wsa *):not(.ca *) {
  padding-right: 40px;
  cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23556070' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 16px 16px;
}
body select:not(.wsm-native) option { color: #0F1729; background: #fff; }
body :is(select, input, textarea):not(.wsm-native):not(.wm-header *):not(.wm-search *):not(.rgc-search *):not(.wm-rail-range *):not(.wsa *):not(.ca *)::placeholder { color: #8A94A6; opacity: 1; }
body :is(select, input, textarea):not(.wsm-native):not(.wm-header *):not(.wm-search *):not(.rgc-search *):not(.wm-rail-range *):not(.wsa *):not(.ca *):hover { border-color: #CBD2DC; }
body :is(select, input, textarea):not(.wsm-native):not(.wm-header *):not(.wm-search *):not(.rgc-search *):not(.wm-rail-range *):not(.wsa *):not(.ca *):focus,
body :is(select, input, textarea):not(.wsm-native):not(.wm-header *):not(.wm-search *):not(.rgc-search *):not(.wm-rail-range *):not(.wsa *):not(.ca *):focus-visible {
  border-color: #452B90;
  box-shadow: 0 0 0 3px rgba(69, 43, 144, .14);
}
body :is(select, input, textarea):not(.wsm-native)[aria-invalid="true"],
body :is(select, input, textarea):not(.wsm-native).is-invalid { border-color: #C0392B; box-shadow: 0 0 0 3px rgba(192, 57, 43, .12); }
body :is(select, input, textarea):not(.wsm-native):disabled { color: #8A94A6; background: #F7F8FA; cursor: not-allowed; }
@media (max-width: 640px) {
  /* 16px stops iOS from zooming the page into the field on focus. */
  body :is(select, input, textarea):not(.wsm-native):not(.wm-header *):not(.wm-search *):not(.rgc-search *):not(.wm-rail-range *):not(.wsa *):not(.ca *) { font-size: 16px; }
}

/* ── Destination country (lot page shipping row, wholesale international).
   The ONE control this file did not already cover. It takes the house look
   above — same border, radius, focus ring and chevron as every other select on
   the marketplace — at the shipping row's own compact scale, and sizes to its
   CONTENT instead of the full-width default, which in that flex row would push
   the postal field and the Estimate button onto lines of their own. It lives
   HERE, beside the other control rules, because the controls are identical on
   every page from one file and never from a per-page copy (operator
   2026-09-08). Specificity matches the block above plus the class, so it wins
   without !important. */
body select.wsl-country:not(.wsm-native):not(.wm-header *):not(.wm-search *):not(.rgc-search *):not(.wm-rail-range *):not(.wsa *):not(.ca *) {
  width: auto;
  max-width: 100%;
  min-height: 0;
  padding: 9px 32px 9px 12px;
  background-position: right 11px center;
  border-color: #E4E2EE;
}
@media (min-width: 641px) {
  /* Under 641px the shared 16px stands — anything smaller and iOS Safari
     zooms the page into the field on focus. */
  body select.wsl-country:not(.wsm-native):not(.wm-header *):not(.wm-search *):not(.rgc-search *):not(.wm-rail-range *):not(.wsa *):not(.ca *) { font-size: 13px; }
}
@media (max-width: 430px) {
  /* Tap target >= 44px, exactly what .wsl-zip and .wsl-zipgo take here. */
  body select.wsl-country:not(.wsm-native):not(.wm-header *):not(.wm-search *):not(.rgc-search *):not(.wm-rail-range *):not(.wsa *):not(.ca *) { min-height: 44px; }
}

/* ── The section head shared by every «Questions» / editorial band on the
   storefront (hubs, tools, compare, price guide, liquidation index, the
   shelf pages). Moved here from wholesale-programmatic.css on 2026-09-09
   because the catalogue's shelf band needs it and that sheet is not loaded
   on /wholesale/c/<slug> — one definition, every page. ── */
.wsf-eyebrow { display: block; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; font-weight: 700; color: #452B90; margin-bottom: 6px; }
/* «Related pages» / «Related searches» / «More to explore» — ONE chip section for the
   programmatic pages (where it was born), the shelves, the hubs and the lot page
   (hub-linking wave D, 2026-09-11). Horizontal gutter from the shared centring rule
   (wholesale-market-faire.css); the lot page's .relchip is the same pill. */
.wsf-related { padding: 26px 48px 0; border-top: 1px solid #F0EEF6; margin-top: 24px; }
.wsf-related .wsm-h2, .wsf-related-h, .wm-search-sup-h { margin: 0; font-family: "Poppins", Poppins Fallback, "Inter", Inter Fallback, system-ui, sans-serif; font-weight: 600; font-size: 20px; }
.wsf-related-chips { display: flex; flex-wrap: wrap; gap: 10px; padding-top: 12px; }
/* THE link chip (Ivan 2026-09-27, Faire «Related searches»): a white pill, a thin light-grey
   hairline, dark-grey regular text after a 16px magnifier (LinkRails::CHIP_ICON), 40px tall,
   16px sides, 8px icon gap; hover / keyboard focus darken the border. ONE rule for every chip
   row that carries .relchip — the shelves' and programmatic foot rails (.wsf-related-chips,
   _link_rail.php + registry/_chips.php), the lot page's «Related searches», the Resale Index
   brands, a noun page's «Looking for something else?» and the empty page's «Explore nearby».
   Filter chips (.wm-chip ×) and the format tabs are other components and stay as they are.
   Listed rows, not a bare .relchip: the pill must outrank a page's `.x a { color }` (0,2,0,
   the specificity the old per-row rule had). */
:is(.wsf-related-chips, .wsl-relsearch-chips, .rv-chips, .wsc-chips, .pg-none-chips, .rpb-chips) .relchip {
  display: inline-flex; align-items: center; gap: 8px; min-width: 0; max-width: 100%; min-height: 40px; box-sizing: border-box;
  padding: 8px 16px; border: 1px solid #D5D8DE; border-radius: 999px; background: #fff;
  font: 400 14px/1.25 Inter, Inter Fallback, system-ui, sans-serif; color: #333A45; text-align: left; text-decoration: none;
  transition: border-color .15s ease, color .15s ease, box-shadow .15s ease;
}
:is(.wsf-related-chips, .wsl-relsearch-chips, .rv-chips, .wsc-chips, .pg-none-chips, .rpb-chips) .relchip:hover { border-color: #1A202C; color: #1A202C; background: #fff; }
:is(.wsf-related-chips, .wsl-relsearch-chips, .rv-chips, .wsc-chips, .pg-none-chips, .rpb-chips) .relchip:focus-visible { outline: 2px solid #1A202C; outline-offset: 2px; border-color: #1A202C; color: #1A202C; }
.relchip-ico { flex: none; width: 16px; height: 16px; display: block; color: currentColor; }
:is(.wsf-related-chips, .wsl-relsearch-chips, .rv-chips, .wsc-chips, .pg-none-chips, .rpb-chips) .relchip > .relchip-v { margin-left: 0; }
/* THE store-type card (moved here from wholesale-market-home.css, 2026-09-27, rules
   unchanged): _store_cards.php — the /wholesale home's «Buying for a store?» and every
   shelf's / store-type page's rail of store types (Ivan: «те же фото-плитки, что на
   главной»). 3 a row on a desktop; one sideways swipe row under 960px (the row scrolls,
   never the page). Fixed image box: no layout shift when the photo lands. */
.wsf-st-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px 20px; }
.wsf-st-card { display: flex; flex-direction: column; min-width: 0; background: #F7F4EF; border-radius: 18px; overflow: hidden; color: #1A202C; text-decoration: none; transition: transform .15s ease, box-shadow .15s ease; }
.wsf-st-card:hover { transform: translateY(-2px); box-shadow: 0 12px 32px rgba(26,32,44,.12); }
.wsf-st-img { display: block; width: 100%; height: 250px; object-fit: cover; background: #EDE8DF; }
.wsf-st-body { display: flex; flex-direction: column; gap: 6px; padding: 18px 20px 20px; }
.wsf-st-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.wsf-st-name { font-family: "Poppins", Poppins Fallback, "Inter", Inter Fallback, system-ui, sans-serif; font-weight: 600; font-size: 18px; line-height: 1.25; }
.wsf-st-go { flex: none; font-size: 14px; font-weight: 600; color: #452B90; }
.wsf-st-line { font-size: 14px; line-height: 1.5; color: #556070; }
@media (max-width: 960px) {
  .wsf-st-grid { display: flex; overflow-x: auto; gap: 12px; scroll-snap-type: x mandatory; padding-bottom: 6px; scrollbar-width: none; }
  .wsf-st-grid::-webkit-scrollbar { display: none; }
  .wsf-st-card { flex: 0 0 280px; scroll-snap-align: start; }
  .wsf-st-card:hover { transform: none; box-shadow: none; }
  .wsf-st-img { height: 190px; }
  .wsf-st-body { gap: 4px; padding: 16px 18px 18px; }
  .wsf-st-name { font-size: 17px; }
  .wsf-st-go { display: none; }
  .wsf-st-line { font-size: 13.5px; line-height: 1.45; }
}
@media (prefers-reduced-motion: reduce) { .wsf-st-card { transition: none; } .wsf-st-card:hover { transform: none; } }
/* …inside a foot rail (.wsf-related, _link_rail.php `stores`): the heading's gap, as the chips'. */
.wsf-related > .wsf-st-grid { margin-top: 12px; }
/* «Buying from suppliers direct?» as the storefront's supplier cards (2026-09-27): the .wsf-sup
   card (wholesale-market-faire.css) inside a foot rail — the heading's 12px gap; under 960px
   one sideways swipe row, the same idiom as search's «Suppliers matching» (the row scrolls,
   never the page); the registry page stays as one quiet «See all … →» link under the cards. */
.wsf-related > .wsf-sups { margin-top: 12px; }
@media (max-width: 960px) {
  .wsf-related > .wsf-sups { display: flex; overflow-x: auto; gap: 12px; scroll-snap-type: x mandatory; padding-bottom: 6px; scrollbar-width: none; }
  .wsf-related > .wsf-sups::-webkit-scrollbar { display: none; }
  .wsf-related > .wsf-sups > * { flex: 0 0 76%; scroll-snap-align: start; min-width: 0; }
}
.wsf-related-more { margin: 14px 0 0; font-size: 14px; }
.wsf-related-more a { color: #452B90; font-weight: 600; text-decoration: none; }
.wsf-related-more a:hover { text-decoration: underline; text-underline-offset: 2px; }
.wsf-related-more a:focus-visible { outline: 2px solid #1A202C; outline-offset: 2px; border-radius: 4px; }
/* A chip section's footnote (_chips.php `note`, 04.10): inside the section, so it takes the section's
   gutter and the next section's seam sits under it — one line, muted, one chip-row gap down. */
.wsf-related-note { margin: 14px 0 0; font: 400 13.5px/1.55 Inter, Inter Fallback, sans-serif; color: #3A4450; max-width: 72ch; }
/* «Shop by product» as photo tiles (2026-09-27): the storefront's one tile row
   (_cattiles.php, .wm-catnav.is-rich — rules above) inside a foot rail. The section
   already carries the gutter, so the row drops its own; the arrows re-centre on the
   132px photo (176 × 4:3) under the row's 12px top: 12 + 66 − 19 = 59. */
.wsf-related .wm-catnav.is-rich { padding: 12px 0 6px; scroll-padding-left: 0; }
.wsf-related .wm-catnav-arrow { top: 59px; }
/* …and the arrows sit on the rail's own column edge (the header row puts them at --wm-pad,
   its own padding; here the section already stands in the column, so the edge is 0). */
.wsf-related .wm-catnav-arrow.is-prev { left: 0; }
.wsf-related .wm-catnav-arrow.is-next { right: 0; }
.wsf-related .wm-catnav-wrap + .wsf-related-chips { padding-top: 10px; }
.wsf-faq { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 48px; }
.wsf-faq-l, .wsf-faq-r { min-width: 0; }
@media (max-width: 760px) { .wsf-faq { grid-template-columns: 1fr; gap: 12px; } }

/* ── FAQ accordion — ONE style for every «Questions» block on the marketplace
   (operator 2026-09-08: «every FAQ section on every page in one style» —
   the brand-hub shape, with room between the questions and WITHOUT border
   lines: «they make everything worse»). Families that used to carry their own look —
   .pgq (hubs, tools, compare, programmatic, price guide, liquidation index,
   about), .wml-faq (landing pages: protection, net terms, insider, referral,
   guides), .wm-hub2-faq (supplier hub), .wsl-faq-list (lot page) — share these
   rules; their local variants were deleted, not overridden. Anatomy: each
   question a soft tinted row, 10px apart, the question in 16px semibold, a
   plus disc that turns into a minus, the open row lifts to white. */
:is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) { display: flex; flex-direction: column; gap: 10px; }
:is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) > details { border: 0; border-radius: 14px; background: #F7F5FC; box-shadow: none; margin: 0; padding: 0; transition: background-color .15s, box-shadow .15s; }
:is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) > details:first-of-type { border-top: 0; }
:is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) > details[open] { background: #FDFCFF; box-shadow: 0 8px 24px rgba(69, 43, 144, .08); }
:is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) > details > summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 18px 20px 18px 22px; font: 600 16px/1.35 Inter, Inter Fallback, sans-serif; color: #1A202C; position: static; border-radius: 14px; transition: color .12s; }
:is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) > details > summary::-webkit-details-marker { display: none; }
:is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) > details > summary::marker { content: ""; }
:is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) > details > summary::after { content: ""; float: none; position: static; flex: 0 0 auto; width: 30px; height: 30px; margin: 0; border: 0; border-radius: 50%; background: #fff center/14px 14px no-repeat url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23452B90' stroke-width='2.4' stroke-linecap='round'><path d='M12 5v14M5 12h14'/></svg>"); box-shadow: 0 1px 2px rgba(15, 23, 42, .06); transition: transform .18s, background-color .12s; }
:is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) > details > summary:hover { color: #452B90; }
:is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) > details > summary:focus-visible { outline: 2px solid #452B90; outline-offset: 2px; }
:is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) > details[open] > summary::after { transform: rotate(45deg); background-color: #EDE8F8; }
:is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) > details > :is(p, div) { margin: 0; padding: 0 72px 20px 22px; font: 400 14.5px/1.65 Inter, Inter Fallback, sans-serif; color: #3F4756; max-width: 76ch; }
/* .wsf-door — the measured-FAQ door (HubMeasuredFaq::answerHtml, 2026-10-21): the one link an answer may carry,
   «Shop Tops lots →» to the nearest shelf when the brand has no lot of its own; a link reads as a link. */
.wsf-door { font-weight: 600; color: var(--wm-ink, #452B90); text-decoration: underline; text-underline-offset: 2px; }
@media (max-width: 640px) {
  :is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) > details > summary { font-size: 15px; padding: 15px 14px 15px 16px; }
  :is(.pgq, .wml-faq, .wm-hub2-faq, .wsl-faq-list) > details > :is(p, div) { padding: 0 48px 16px 16px; }
}

/* ── THE COLUMN — one side gutter for every block of EVERY storefront page (Ivan 2026-09-27,
   Faire benchmark: «у всех блоков отступы по бокам по бэнчмарку Faire … проверь все страницы»).
   A storefront page is ONE centred column: --wm-col of content between two --wm-gutter sides —
   48px, 16px from 1024 down (the header's own boundary, wholesale-market-faire.css). Wider than
   col + 2 gutters, the column centres: the side is (width − col) / 2.
   --wm-pad IS that side, measured against the page (body.wm is an inline-size container, so
   100cqw is the page's width wherever the token is read — a block nested in a narrower box
   still gets the PAGE's gutter, which is what «one column» means). Every block reads it:
     · the shared container list (wholesale-market-faire.css «THE GUTTER») pads each top-level
       section with it — backgrounds and hairlines stay full-bleed, the content sits on the column;
     · the frames (.hub-wrap, .pgx) centre col + 2 gutters — the same edge by construction;
     · the chrome strips below (header, category bar, «Why buy» promo, footer) pad their content;
     · the catalogue shell (.wm-layout, wholesale-market-filters.css) is one padded section with
       the rail and the column inside it.
   Measured before (2026-09-27, 34 pages × 390/1000/1440): catalogue-family pages ran their chrome
   on 48 at 1440 while the hubs sat on 83; the shelf's sections under the grid (sourcing, link
   rails, About, FAQ) ran to the screen edge (x = 0 with the rail hidden, the reported cosmetics
   page). A new block brings NO gutter of its own — it joins the list or sits in a shell.
   Guards: tests/standalone/js/storefront-gutters.mjs (rendered), tests/architecture/
   storefront_one_column.php (the list, the tokens, no new literal gutter). */
/* TWO NAMED WIDTHS, ONE MECHANISM (Ivan 2026-09-28, after the column shipped: «product pages feel too
   narrow»). A page whose main content is a LOT GRID — the catalogue shell (.wm-layout: /lots, category,
   category/sub, collections, from/<state>[/<shelf>], brand, search, the supplier storefront), the /c/ hubs
   (main[class="hub-wrap"]) and the bag — takes the WIDE column: 1680, so a 1440 screen is full width with
   48px sides again and a 1920+ monitor gets more cards per row instead of wide empty margins. Every other
   page (lot page, registry profile, landing, tools, FAQ/text pages) keeps the READING column, 1260. The
   choice is made ONCE, on body, by what the page holds — no page sets a width of its own; the header,
   category bar, promo and footer read the same --wm-pad and stay on the grid's edges.
   --wm-pad is declared on body (not :root) so it resolves against the body's --wm-col. */
:root { --wm-gutter: 48px; --wm-col-read: 1260px; --wm-col-wide: 1680px; --wm-col: var(--wm-col-read); }
@media (max-width: 1024px) { :root { --wm-gutter: 16px; } }
body.wm { container-type: inline-size; --wm-pad: max(var(--wm-gutter), calc((100cqw - var(--wm-col)) / 2)); }
body.wm:has(.wm-layout, main[class="hub-wrap"], .wbf) { --wm-col: var(--wm-col-wide); }
/* …and the wide column fills with cards, not with fatter cards: a fifth / sixth column where it fits. */
@media (min-width: 1600px) {
  .wm-layout.filters-off .wm-grid, .wm-layout.filters-off .wm-search-sup .wsf-sups { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  body.wm:has(main[class="hub-wrap"]) .pg-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  body.wm:has(main[class="hub-wrap"]) .hubgrid .grid { grid-template-columns: repeat(8, minmax(0, 1fr)); }
}
body.wm :is(.wm-header--f, .wm-catbar, .wsm-promo, .wsmf-in) {
  max-width: none; margin-left: 0; margin-right: 0; box-sizing: border-box;
  padding-left: var(--wm-pad);
  padding-right: var(--wm-pad);
}

/* ── Breadcrumbs — ONE rhythm on every page that has them (operator
   2026-09-08: «above-the-fold spacing in one style»). Catbar → crumb text 22px,
   crumbs → the next thing 24px, 13px muted. Page sheets used to carry their
   own copy of this (compare, index, about, price guide, programmatic, hub,
   lot) with five different numbers; those were deleted, not overridden. The
   lot page keeps only its own SIDE padding (its 1144px frame). */
.pg-crumbs, .wsl-breadcrumb, .rgc-hero > .rgc-crumbs { padding-top: 22px; padding-bottom: 0; margin-bottom: 24px; font: 400 13px/1.5 Inter, Inter Fallback, sans-serif; color: #556070; }
.pg-crumbs a, .wsl-breadcrumb a, .rgc-hero > .rgc-crumbs a { color: #556070; text-decoration: none; }
.pg-crumbs a:hover, .wsl-breadcrumb a:hover, .rgc-hero > .rgc-crumbs a:hover { color: #1A202C; }
.pg-crumbs a.here, .wsl-breadcrumb .here { color: #1A202C; font-weight: 600; }
@media (max-width: 760px) { .pg-crumbs, .wsl-breadcrumb, .rgc-hero > .rgc-crumbs { padding-top: 16px; margin-bottom: 18px; } }
/* The crumbs carry the 24px gap; a page head that follows them adds nothing of its own (programmatic pages had 28px on .wm-cathead on top of it). */
.pg-crumbs + .wm-cathead, .wsl-breadcrumb + .wm-cathead, .pg-crumbs + .wm-brandhead { padding-top: 0; margin-top: 0; }

/* ── Section rhythm — ONE rule for every section boundary below the fold (Ivan
   2026-09-08 invariant; «all four sides» rule 2026-09-23). --wm-sec is the gap a
   person sees between the last ink of one section and the first ink of the next
   (a hairline counts as ink): 64 on a desktop, 44 on a phone — the Faire numbers,
   inside the invariant's 64–72 / 40–44. The footer takes the same value
   (_footer.php), and the last band of EVERY page brings no bottom space of its
   own into that gap (the rule at the end of this block). Measured before this rule (2026-09-23): 24–48 desktop and
   24–38 phone between sections on shelves, brand pages, /pallets pages and hubs,
   82/72 or 48/48 above the footer — the numbers came from a dozen per-block
   margins in five sheets and two partials, each right on its own.

   A SECTION is a new titled band. On a shelf / umbrella / sub-shelf / /lots /
   brand page (.wm-main): «What X resells for» (.wm-brand-resale), Sourcing
   request (.wsr-block), every link rail (.wsf-related — each has its own
   heading), About (.wm-about), FAQ (.wsf-faq), Guides (.wm-guides), Lot Drop
   (.ld-block), the sign-up teaser (.wm-teaser). On a programmatic page (the
   …/pallets and /from/<state> family, programmatic.php — top-level children
   of a body that carries its grid region; the registry and supplier pages put
   the same blocks at the top level too and are not this family): «What X
   sells for» (.hub-sf), Suppliers (.wsf.wsf-row), How it works (.wsf-steps),
   FAQ, Guides (.wsf-guides), Related (.wsf-related), the sign-up band
   (.wsf-cta). On a /c/ hub (main.hub-wrap): every .hub-sec, the rails pair
   (.hub-rails), the link rails and the FAQ.

   NOT a section (keeps its own spacing): the head (crumbs 22/24, H1 block,
   tiles, shelf bar, format tabs, stats strip — the invariant's own numbers);
   the grid region (toolbar, chips, assistant bar, card rows, the pager 28/24
   under the last card, «Show more lots» 18); the head → first section on a hub
   (32/24, the «H1 block → next» of that family); the nearby-lots rail that
   hangs under «sells for» (.hub-sf + .pg-none-rail); the «Ver en español»
   door under a FAQ; the inside of any band.

   HOW: every section takes the gap as its top margin; the bottoms that would
   add to it are zeroed — the panels' own bottom margins (the last one sits in
   .wm-main, a flex item, so its margin never collapsed into the footer's), the
   transparent sections' bottom padding, and the grid's bottom padding, which
   becomes a margin so it collapses into the next section's instead of
   stacking on it. The selectors are qualified (body.wm …, 0,3,1+) so they
   outrank the per-block rules they replace in wholesale-market-filters.css,
   wholesale-hub.css, wholesale-programmatic.css, wholesale-catalog-faire.css
   and the partials' own <style> (_stock_request, _lot_drop_form).
   The /c/ hub is addressed as main[class="hub-wrap"] ON PURPOSE: tools,
   compare, about, es and the hub indexes share the .hub-wrap frame with their
   own layouts and were not measured with this change. */
:root { --wm-sec: 64px; }
@media (max-width: 760px) { :root { --wm-sec: 44px; } }
body.wm .wm-main > :is(.wm-brand-resale, .wsr-block, .wm-about, .wsf-faq, .wm-guides, .ld-block, .wm-teaser),
body.wm .wm-main > [data-wsm-live] > .wsf-related,
body.wm:has(> [data-wsm-page="programmatic"], > .pg-sold) > :is(.hub-sf.wpf, .wsf.wsf-row, .wsf-steps, .wsf-faq, .wsf-guides, .wsf-related, .wsf-cta),
body.wm:has(> [data-wsm-page="programmatic"], > .pg-sold) > [data-wsm-live] > .wsf-related,
body.wm main[class="hub-wrap"] > :is(.hub-sec, .hub-rails, .wsf-related, .wsf-faq),
body.wm > .rpb.wm-sec,
body.wm:has(> .wm-sup-identity) > .wm-layout + :is(.wm-hub2, .wm-sup-section) { margin-top: var(--wm-sec); margin-bottom: 0; }
/* The supplier page (Ivan 2026-09-27): its grid region (.wm-layout — All lots, or
   the Sold tab's #ended) is a TOP-LEVEL band, not a .wm-main child, so the band
   under it never got the section gap: measured pager ink → next ink 0px on
   ?tab=sold (Newer / Older sat on the rails' hairline) and 6px on All lots
   («Load more» → «Sold lots»), against 64 / 44 under the catalogue's pager.
   Same token, same rule: the band after the grid region (the .wm-hub2 frame or
   the rails' .wm-sup-section — the only two the view prints there) is in the
   ONE rule above; its 6px .wm-hub2 top padding is dropped so the gap is the token. */
body.wm:has(> .wm-sup-identity) > .wm-layout + .wm-hub2 { padding-top: 0; }
/* the hub's first band under its head keeps the head rhythm */
body.wm main[class="hub-wrap"] > .wm-cathead + :is(.hub-sec, .hub-rails) { margin-top: 32px; }
@media (max-width: 760px) { body.wm main[class="hub-wrap"] > .wm-cathead + :is(.hub-sec, .hub-rails) { margin-top: 24px; } }
/* transparent sections: no bottom padding under their last line */
body.wm .wm-main > :is(.wsf-faq, .wm-guides, .wm-about),
body.wm:has(> [data-wsm-page="programmatic"], > .pg-sold) > :is(.wsf.wsf-row, .wsf-steps, .wsf-faq, .wsf-guides),
body.wm main[class="hub-wrap"] > .wsf-faq { padding-bottom: 0; }
/* the Suppliers row carried its gap as top padding (40/32) */
body.wm:has(> [data-wsm-page="programmatic"], > .pg-sold) > .wsf.wsf-row { padding-top: 0; }
/* the grid region: the card rows' bottom padding becomes a margin, the pager
   under them keeps it (grid → pager 28 / 24) and adds none below itself */
body.wm .wm-layout .wm-main .wm-grid { padding-bottom: 0; margin-bottom: 28px; }
body.wm .wm-layout .wm-main .wm-pager { padding-bottom: 0; }
@media (max-width: 980px) { body.wm .wm-layout .wm-main .wm-grid { margin-bottom: 24px; } }
/* THE LAST BAND BRINGS NO BOTTOM SPACE INTO THE FOOTER'S GAP — every page (reviews
   P1-1 and P1-2, 2026-09-23). With the footer on --wm-sec, whatever bottom margin
   or padding the page's last band carries stacks on it: 94–142 on the registry,
   supplier, compare, hub-index and tool pages, 92/96 on the lot archive.
   THE TAIL is found by structure, not by page: T0 is the last top-level block
   before footer.wsmf; T1 is T0's last child, T2 that one's last child — descending
   only through TRANSPARENT wrappers (a frame, a live region, the lazy slot, a
   hairline band, a link rail, a FAQ, a card grid, a pager), because a filled panel
   is a box whose inner spacing is its own. «Last» means: no later sibling that
   takes part in the layout — scripts, styles, [hidden], <dialog> and anything
   with role dialog / alertdialog / status are looked past by what they ARE, not by
   name (the consent banner, the soft wall, the first-order popup, the share sheet
   and the toast all declare a role; a new overlay that declares one is covered).
   Every tail block loses its bottom margin (outside its box); a transparent one
   loses its bottom padding too. A filled panel at the end (a CTA band, the
   registry's door card) keeps its inner padding. */
body.wm > :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]):has(~ footer.wsmf):not(:has(~ :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]) ~ footer.wsmf)),
body.wm > :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]):has(~ footer.wsmf):not(:has(~ :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]) ~ footer.wsmf)):is(main, .rg2, .rgd, .wcf, .wm-layout, .wm-main, [data-wsm-live], [data-wsl-lazy-slot], .wm-sup-section, .hub-sec, .wsf-faq, .wsf-related, .wsl-relsearch, .wsl-guides, .wsl-similar, .wm-grid, .wm-pager) > :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]):not(:has(~ :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]))),
body.wm > :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]):has(~ footer.wsmf):not(:has(~ :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]) ~ footer.wsmf)):is(main, .rg2, .rgd, .wcf, .wm-layout, .wm-main, [data-wsm-live], [data-wsl-lazy-slot], .wm-sup-section, .hub-sec, .wsf-faq, .wsf-related, .wsl-relsearch, .wsl-guides, .wsl-similar, .wm-grid, .wm-pager) > :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]):not(:has(~ :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]))):is(main, .rg2, .rgd, .wcf, .wm-layout, .wm-main, [data-wsm-live], [data-wsl-lazy-slot], .wm-sup-section, .hub-sec, .wsf-faq, .wsf-related, .wsl-relsearch, .wsl-guides, .wsl-similar, .wm-grid, .wm-pager) > :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]):not(:has(~ :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]))) { margin-bottom: 0; }
body.wm > :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]):has(~ footer.wsmf):not(:has(~ :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]) ~ footer.wsmf)):is(main, .rg2, .rgd, .wcf, .wm-layout, .wm-main, [data-wsm-live], [data-wsl-lazy-slot], .wm-sup-section, .hub-sec, .wsf-faq, .wsf-related, .wsl-relsearch, .wsl-guides, .wsl-similar, .wm-grid, .wm-pager),
body.wm > :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]):has(~ footer.wsmf):not(:has(~ :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]) ~ footer.wsmf)):is(main, .rg2, .rgd, .wcf, .wm-layout, .wm-main, [data-wsm-live], [data-wsl-lazy-slot], .wm-sup-section, .hub-sec, .wsf-faq, .wsf-related, .wsl-relsearch, .wsl-guides, .wsl-similar, .wm-grid, .wm-pager) > :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]):not(:has(~ :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]))):is(main, .rg2, .rgd, .wcf, .wm-layout, .wm-main, [data-wsm-live], [data-wsl-lazy-slot], .wm-sup-section, .hub-sec, .wsf-faq, .wsf-related, .wsl-relsearch, .wsl-guides, .wsl-similar, .wm-grid, .wm-pager),
body.wm > :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]):has(~ footer.wsmf):not(:has(~ :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]) ~ footer.wsmf)):is(main, .rg2, .rgd, .wcf, .wm-layout, .wm-main, [data-wsm-live], [data-wsl-lazy-slot], .wm-sup-section, .hub-sec, .wsf-faq, .wsf-related, .wsl-relsearch, .wsl-guides, .wsl-similar, .wm-grid, .wm-pager) > :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]):not(:has(~ :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]))):is(main, .rg2, .rgd, .wcf, .wm-layout, .wm-main, [data-wsm-live], [data-wsl-lazy-slot], .wm-sup-section, .hub-sec, .wsf-faq, .wsf-related, .wsl-relsearch, .wsl-guides, .wsl-similar, .wm-grid, .wm-pager) > :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]):not(:has(~ :not(script, style, link, template, noscript, dialog, [hidden], [role="dialog"], [role="alertdialog"], [role="status"]))):is(main, .rg2, .rgd, .wcf, .wm-layout, .wm-main, [data-wsm-live], [data-wsl-lazy-slot], .wm-sup-section, .hub-sec, .wsf-faq, .wsf-related, .wsl-relsearch, .wsl-guides, .wsl-similar, .wm-grid, .wm-pager) { padding-bottom: 0; }

/* ── Search suggest panel (Faire benchmark, operator 2026-09-08) ──────────
   Sections under the field — Categories (open category hubs), Brands (open
   brand hubs), Lots (56px tile, one-line title with the matched fragment in
   bold, meta line, mono price) — then «See all lots for “q”» and, when a
   price-guide product type matches, a quiet «Resale price guide» row. The
   panel is a role=listbox the input drives (aria-activedescendant); the
   ↑/↓ selection and the mouse hover share ONE tint. Scoped under .wm-search
   so no sheet loaded later can restyle it by class alone; the [hidden] rule
   sits INSIDE the block so the explicit display never beats the attribute
   (this surface's display-beats-hidden defect class). The mockup-E rules
   this replaces were deleted from wholesale-market-buyer.css, not overridden. */
.wm-search .wmb-sug { position: absolute; top: calc(100% + 8px); left: 0; width: 540px; max-width: calc(100vw - 32px); z-index: 60; display: block; padding: 6px 0 4px; background: #fff; border: 1px solid #E4E2EE; border-radius: 16px; box-shadow: 0 18px 44px rgba(26, 32, 44, .14); max-height: min(72vh, 620px); overflow-y: auto; overflow-x: hidden; text-align: left; font-family: Inter, Inter Fallback, sans-serif; }
.wm-search .wmb-sug[hidden] { display: none; }
.wm-search .wmb-sug h6 { margin: 8px 16px 2px; font: 700 11.5px/1.4 Inter, Inter Fallback, sans-serif; letter-spacing: .06em; text-transform: uppercase; color: #556070; }
.wm-search .wmb-sug h6 + h6 { margin-top: 0; }
.wm-search .wmb-sug-row { display: flex; align-items: center; gap: 12px; padding: 12px 16px; min-width: 0; color: #1A202C; font-size: 13.5px; line-height: 1.35; text-decoration: none; }
.wm-search .wmb-sug-row .tile { flex: 0 0 56px; width: 56px; height: 56px; border-radius: 8px; background: linear-gradient(135deg, #EEEBF6, #E4E2EE) center / cover no-repeat; }
.wm-search .wmb-sug-row .t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wm-search .wmb-sug-row .t b { font-weight: 700; color: #1A202C; }
.wm-search .wmb-sug-row .t small { display: block; margin-top: 2px; font-size: 12px; color: #556070; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wm-search .wmb-sug-row .r { margin-left: auto; flex: none; white-space: nowrap; font: 500 12.5px/1.2 "JetBrains Mono", ui-monospace, monospace; color: #556070; }
.wm-search .wmb-sug-row .r.price { color: #1A202C; font-size: 13px; }
.wm-search .wmb-sug-row .r .arrow { color: #452B90; font-family: Inter, Inter Fallback, sans-serif; }
.wm-search .wmb-sug-row:hover, .wm-search .wmb-sug-row.sel, .wm-search .wmb-sug-row[aria-selected="true"] { background: #F7F5FC; color: #1A202C; }
.wm-search .wmb-sug-foot { display: flex; align-items: center; gap: 10px; margin-top: 4px; padding: 12px 16px; border-top: 1px solid #E4E2EE; color: #452B90; font-size: 13px; font-weight: 600; text-decoration: none; }
.wm-search .wmb-sug-foot + .wmb-sug-foot { margin-top: 0; padding-top: 10px; border-top: 0; }
.wm-search .wmb-sug-foot .n { margin-left: auto; font: 500 12px/1.2 "JetBrains Mono", ui-monospace, monospace; color: #556070; }
.wm-search .wmb-sug-foot.quiet { color: #556070; font-weight: 500; }
.wm-search .wmb-sug-foot.quiet b { color: #1A202C; font-weight: 600; }
.wm-search .wmb-sug-foot:hover, .wm-search .wmb-sug-foot.sel, .wm-search .wmb-sug-foot[aria-selected="true"] { background: #F7F5FC; }
.wm-search .wmb-sug-empty { padding: 14px 16px 6px; font-size: 13.5px; color: #1A202C; }
.wm-search .wmb-sug-empty small { display: block; margin-top: 3px; font-size: 12.5px; color: #556070; }
@media (max-width: 700px) {
  .wm-search .wmb-sug { left: 0; right: 0; width: auto; max-width: none; border-radius: 14px; max-height: min(64vh, 560px); }
  .wm-search .wmb-sug-row { padding: 14px 16px; gap: 12px; }
  .wm-search .wmb-sug-row.lot { flex-wrap: wrap; }
  .wm-search .wmb-sug-row.lot .t { flex-basis: calc(100% - 68px); }
  .wm-search .wmb-sug-row.lot .r.price { flex-basis: 100%; margin-left: 68px; margin-top: -6px; }
  .wm-search .wmb-sug-foot { padding: 14px 16px; }
}

/* ── «Pick up where you left off» (catalogue home; design signed off by the
   operator 2026-09-08, artifact 217961b5) ──
   A section in the page's own components, not a box: Poppins 18 heading, the
   rail's arrows, a quiet Clear; categories/brands as 46px pills with the home
   strip's photo in a 38px circle; lots as a Faire «Recently viewed» rail —
   104px cards (operator 2026-09-08: «half the size»), snap per card, arrows on desktop, thumb on
   the phone. 24px under the toolbar and 24px above what follows (16 ≤640). */
.wm-recent { margin: 24px 0; padding: 0 24px; }
.wm-recent-head { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; }
.wm-recent-title { margin: 0; flex: 1 1 auto; font-family: "Poppins", Poppins Fallback, "Inter", Inter Fallback, sans-serif; font-size: 18px; font-weight: 600; line-height: 1.2; letter-spacing: -.01em; color: #1A202C; }
.wm-recent-arrows { display: flex; gap: 6px; }
.wm-recent-arrows[hidden] { display: none; }
.wm-recent-arrow { width: 32px; height: 32px; border: 1px solid #E4E2EE; border-radius: 50%; background: #fff; color: #1A202C; font: 400 18px/1 "Inter", Inter Fallback, sans-serif; display: grid; place-items: center; cursor: pointer; padding: 0 0 2px; }
.wm-recent-arrow:hover:not(:disabled) { border-color: #452B90; color: #452B90; }
.wm-recent-arrow:disabled { color: #A0A6B4; cursor: default; }
.wm-recent-clear { font: 600 13px/1 inherit; color: #452B90; background: none; border: 0; padding: 4px 0; cursor: pointer; }
.wm-recent-clear:hover { color: #321F69; text-decoration: underline; }
.wm-recent-pills { display: flex; gap: 8px; flex-wrap: wrap; }
.wm-recent-pill { display: inline-flex; align-items: center; gap: 10px; height: 46px; box-sizing: border-box; padding: 4px 14px 4px 4px; border: 1px solid #E4E2EE; border-radius: 999px; background: #fff; text-decoration: none; color: #1A202C; max-width: 100%; }
.wm-recent-pill:hover { border-color: #452B90; }
.wm-recent-pill-ph { width: 38px; height: 38px; border-radius: 50%; flex: none; background: #F4F2FA center / cover; display: grid; place-items: center; }
.wm-recent-pill-ph i { font: 600 16px/1 "Poppins", Poppins Fallback, "Inter", Inter Fallback, sans-serif; font-style: normal; color: #452B90; }
.wm-recent-pill-t { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.wm-recent-pill-t b { font-size: 13.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wm-recent-pill-t i { font: 600 10px/1 "Inter", Inter Fallback, sans-serif; font-style: normal; letter-spacing: .06em; text-transform: uppercase; color: #6D5BB5; margin-top: 3px; }
.wm-recent-rail { display: flex; gap: 10px; margin-top: 12px; overflow-x: auto; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; scrollbar-width: none; padding-bottom: 2px; }
.wm-recent-rail::-webkit-scrollbar { display: none; }
.wm-recent-pills:empty + .wm-recent-rail { margin-top: 0; }
.wm-recent-card { flex: 0 0 104px; scroll-snap-align: start; display: flex; flex-direction: column; min-width: 0; border: 1px solid #E4E2EE; border-radius: 14px; overflow: hidden; background: #fff; text-decoration: none; color: #1A202C; transition: transform .15s ease, box-shadow .15s ease; }
.wm-recent-card:hover { transform: translateY(-2px); box-shadow: 0 10px 28px rgba(26, 32, 44, .12); }
.wm-recent-ph { display: block; position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: linear-gradient(135deg, #F1EFE9, #E7E3D9); }
.wm-recent-ph img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.wm-recent-body { display: flex; flex-direction: column; gap: 2px; padding: 7px 8px 9px; min-width: 0; }
.wm-recent-t { font-size: 12px; font-weight: 600; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wm-recent-meta { display: none; }
.wm-recent-price { font-family: "JetBrains Mono", monospace; font-size: 12px; font-weight: 700; margin-top: 1px; }
@media (max-width: 640px) {
  .wm-recent { margin: 16px 0; padding: 0 16px; }
  .wm-recent-arrows { display: none; }
  .wm-recent-pills { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
  .wm-recent-pills::-webkit-scrollbar { display: none; }
  .wm-recent-pill { flex: none; }
  .wm-recent-rail { gap: 8px; }
}
@media (prefers-reduced-motion: reduce) { .wm-recent-card { transition: none; } }
/* ── Live selection (wholesale-live.js, operator 2026-09-08) ──
   While the next page is on its way the grid dims instead of vanishing;
   the rail stays usable so a second facet can be picked before the first lands.
   The applied chips dim too (2026-09-28): the tapped tab is selected at once, and until
   the answer lands the chips still name the old state — dimmed, they read as «updating». */
.wsm-live-busy [data-wsm-live="pager"], .wsm-live-busy [data-wsm-live="applied"] { opacity: .55; }
/* Skeleton cards (Faire benchmark, operator 2026-09-08): the card's own frame
   — radius 14, hairline, 4:3 photo — with a shimmer over the photo and four
   text bars where title, meta, supplier and price will land. */
.wm-skel { border: 1px solid #E4E2EE; border-radius: 14px; overflow: hidden; background: #fff; display: flex; flex-direction: column; min-height: 380px; }
.wm-skel-ph { display: block; aspect-ratio: 4 / 3; background: #EFEDF5; position: relative; overflow: hidden; }
.wm-skel-ph::after, .wm-skel-l::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.75) 50%, rgba(255,255,255,0) 100%); transform: translateX(-100%); animation: wm-skel-shimmer 1.3s ease-in-out infinite; }
.wm-skel-b { display: flex; flex-direction: column; gap: 10px; padding: 16px 15px; }
.wm-skel-l { display: block; position: relative; overflow: hidden; height: 12px; border-radius: 6px; background: #EFEDF5; }
.wm-skel-l.w1 { width: 40%; height: 16px; border-radius: 99px; }
.wm-skel-l.w2 { width: 92%; height: 14px; }
.wm-skel-l.w3 { width: 64%; }
.wm-skel-l.w4 { width: 34%; height: 18px; margin-top: 6px; }
@keyframes wm-skel-shimmer { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .wm-skel-ph::after, .wm-skel-l::after { animation: none; } }

/* H11 «Guides» rail (2026-09-10, operator: «by the Faire benchmark — rich and elegant»; shared 2026-09-11 with the phrase
   hubs and supplier pages): editorial cards — cover 3:2 radius 14, no border, eyebrow (blog · read time), two-line
   title, one line of the article's description, cover lifts on hover. The section's OUTER rhythm belongs to the page
   (.hub-sec on hubs, .wsf-guides on programmatic pages, .wm-hub2-sec on supplier pages); the header inside is ours. */
.hub-guides-h{margin-bottom:18px}
.hub-guides-h h2{font-family:Poppins, Poppins Fallback,Inter, Inter Fallback,sans-serif;font-weight:600;font-size:24px;letter-spacing:-.01em;margin:0;color:#1A202C}
.hub-guides-h p{margin:4px 0 0;color:#556070;font:400 14.5px/1.5 Inter, Inter Fallback,sans-serif;max-width:70ch}
@media(max-width:640px){.hub-guides-h h2{font-size:20px}.hub-guides-h p{font-size:13.5px;line-height:1.45}}
.hub-guides-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:22px 18px}
.hub-guide{display:block;color:#1A202C;text-decoration:none;min-width:0}
.hub-guide-ph{position:relative;aspect-ratio:3/2;border-radius:14px;overflow:hidden;background:#F4F3F7}
.hub-guide-ph img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .25s ease}
.hub-guide:hover .hub-guide-ph img{transform:scale(1.03)}
.hub-guide-ph.is-text{display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#F4F1FB,#E9E3F7)}
.hub-guide-ph.is-text span{font:600 44px/1 Poppins, Poppins Fallback,Inter, Inter Fallback,sans-serif;color:#452B90;opacity:.55}
.hub-guide-b{padding:12px 2px 0}
.hub-guide-eb{display:block;font:500 11.5px/1.3 Inter, Inter Fallback,sans-serif;letter-spacing:.06em;text-transform:uppercase;color:#7A7290;margin-bottom:6px}
.hub-guide h3{margin:0;font:600 16px/1.35 Inter, Inter Fallback,sans-serif;color:#1A202C;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;transition:color .15s}
.hub-guide:hover h3{color:#452B90}
.hub-guide p{margin:6px 0 0;font:400 13.5px/1.5 Inter, Inter Fallback,sans-serif;color:#556070;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
@media(max-width:1024px){.hub-guides-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:20px 14px}}
@media(max-width:560px){.hub-guides-grid{grid-template-columns:1fr}.hub-guide-ph{aspect-ratio:16/9}}
@media(prefers-reduced-motion:reduce){.hub-guide-ph img,.hub-guide h3{transition:none}.hub-guide:hover .hub-guide-ph img{transform:none}}

/* «Ver esta página en español» — the ONE geo notice (M-B §7.2, 2026-09-18).
   Its own rule and not a new sheet: one line on an English page does not earn a
   stylesheet request. It sits UNDER the header and the category bar, in normal
   flow, so nothing moves when it prints; when the visitor dismisses it the node
   is removed, and a shift within 500 ms of a click is not a layout shift Google
   counts. Side gutter 16 px on a phone, as the rest of the storefront. */
.wm-esmx {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 9px var(--wm-pad);
  background: #F1ECFA;
  color: #321F69;
  font-size: 13px;
  line-height: 1.4;
}
.wm-esmx-link {
  color: #452B90;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.wm-esmx-link:hover { color: #321F69; }
.wm-esmx-x {
  border: 0;
  background: none;
  padding: 0 2px;
  font-size: 17px;
  line-height: 1;
  color: #6B5AA0;
  cursor: pointer;
}
.wm-esmx-x:hover { color: #321F69; }
.wm-esmx-x-svg { display: block; }
@media (max-width: 1024px) {
  .wm-esmx { padding: 9px var(--wm-pad); font-size: 12.5px; gap: 8px; }
  .wm-esmx-link { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* ── ФИЧА 2/3 (2026-09-24, ТЗ «маржа/калькулятор/доверие»): the lot page's
   #profit block (board LotMargin.dc), the pallet-roi redesign (CalcTool.dc /
   CalcToolPhone.dc) and the registry trust section (RegistryTrust.dc).
   Tokens are the boards' own — ink #1A202C · muted #556070 · accent #452B90 ·
   tint #F4F2FA · hairline #E8EAEE · panel divider #DDD8EC · numbers in
   JetBrains Mono. Every selector below is NEW: while the two flags are dark
   nothing on any page matches these rules. */

/* — lot #profit (wsl-profit / wslp-*) — the section frame (max-width 1240,
   padding 44/48 → 32/16 phone, hairline below) comes from the lot family's own
   `.wm .wsl-sec` rule (wholesale-market-lot.css) so #profit sits in the page's
   rhythm like every neighbour; only the INNER layout is declared here, at
   .wm .wsl-sec.wsl-profit so the family's display:block does not undo it. */
.wm .wsl-sec.wsl-profit { display: flex; flex-direction: column; gap: 24px; font-family: "Inter", Inter Fallback, system-ui, sans-serif; color: #1A202C; }
.wslp-head { display: flex; flex-direction: column; gap: 8px; max-width: 880px; }
.wslp-h { margin: 0; font-size: 20px; font-weight: 700; line-height: 1.35; }
.wslp-h .mono, .wslp-hsub .mono, .wslp-in, .wslp-big, .wslp-r .mono { font-family: "JetBrains Mono", "SFMono-Regular", monospace; }
.wslp-arr { color: #556070; }
.wslp-hsub { font-size: 13px; color: #556070; }
.wslp-hsub a { color: #452B90; text-decoration: none; }
.wslp-hsub a:hover { text-decoration: underline; }
.wslp-cols { display: flex; gap: 56px; align-items: flex-start; }
.wslp-form { flex: 1 1 0; display: flex; flex-direction: column; gap: 20px; max-width: 480px; }
.wslp-f { display: flex; flex-direction: column; gap: 6px; flex: 1 1 0; }
.wslp-l { font-size: 13px; font-weight: 600; color: #556070; }
.wslp-in { box-sizing: border-box; width: 100%; min-height: 48px; padding: 0 16px; border: 1px solid #C9CED8; border-radius: 8px; font-size: 16px; color: #1A202C; background: #fff; }
.wslp-note { font-size: 12px; color: #556070; }
.wslp-row { display: flex; gap: 16px; }
.wslp-help { font-size: 13px; color: #556070; line-height: 1.5; }
.wslp-panel { flex: 1 1 0; background: #F4F2FA; border-radius: 16px; padding: 28px 32px; display: flex; flex-direction: column; gap: 14px; max-width: 480px; }
.wslp-eyebrow { font-size: 13px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: #452B90; }
.wslp-big { font-size: 48px; font-weight: 700; line-height: 1; }
.wslp-sub { font-size: 14px; color: #556070; line-height: 1.5; }
.wslp-r { display: flex; justify-content: space-between; gap: 18px; border-top: 1px solid #DDD8EC; padding-top: 14px; font-size: 14px; }
.wslp-r > span:first-child { color: #556070; }
.wslp-r .mono { font-weight: 700; text-align: right; }
.wslp-method { font-size: 12px; color: #556070; line-height: 1.5; }
.wslp-calc { color: #452B90; font-weight: 600; text-decoration: none; white-space: nowrap; }
.wslp-calc:hover { text-decoration: underline; }
@media (max-width: 760px) {
  .wm .wsl-sec.wsl-profit { gap: 18px; }
  .wslp-cols { flex-direction: column; gap: 18px; }
  .wslp-form, .wslp-panel { max-width: none; width: 100%; box-sizing: border-box; }
  .wslp-panel { padding: 22px 20px; gap: 10px; }
  .wslp-big { font-size: 40px; }
  .wslp-h { font-size: 18px; }
}

/* — pallet-roi redesign (roi2-*) — */
.roi2-head { display: flex; flex-direction: column; gap: 12px; max-width: 760px; margin: 8px 0 36px; }
.roi2-eyebrow { font-size: 12px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: #452B90; }
.roi2-h1 { margin: 0; font-size: 34px; font-weight: 800; letter-spacing: -0.01em; line-height: 1.2; }
.roi2-sub { margin: 0; font-size: 16px; color: #556070; line-height: 1.55; }
.roi2 { display: flex; gap: 48px; align-items: flex-start; margin-bottom: 64px; }
.roi2-form { flex: 1.1 1 0; border: 1px solid #E8EAEE; border-radius: 16px; padding: 32px 36px; display: flex; flex-direction: column; gap: 22px; }
.roi2-f { display: flex; flex-direction: column; gap: 6px; flex: 1 1 0; }
.roi2-l { font-size: 13px; font-weight: 600; color: #556070; }
.roi2-in, .roi2-sel { box-sizing: border-box; width: 100%; min-height: 48px; padding: 0 16px; border: 1px solid #C9CED8; border-radius: 8px; font-size: 16px; color: #1A202C; background: #fff; }
.roi2-in { font-family: "JetBrains Mono", "SFMono-Regular", monospace; }
.roi2-sel { padding: 0 14px; font-family: "Inter", Inter Fallback, system-ui, sans-serif; font-size: 15px; font-weight: 600; }
.roi2-row { display: flex; gap: 16px; }
.roi2-note { font-size: 12px; color: #556070; }
.roi2-side { flex: 1 1 0; display: flex; flex-direction: column; gap: 24px; }
.roi2-panel { background: #F4F2FA; border-radius: 16px; padding: 32px 36px; display: flex; flex-direction: column; gap: 16px; }
.roi2-plabel { font-size: 13px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: #452B90; }
.roi2-big { font-size: 56px; font-weight: 700; line-height: 1; }
.roi2-big, .roi2-r .mono { font-family: "JetBrains Mono", "SFMono-Regular", monospace; }
.roi2-rows { display: flex; flex-direction: column; }
.roi2-r { display: flex; justify-content: space-between; gap: 18px; padding: 12px 0; border-top: 1px solid #DDD8EC; font-size: 14px; }
.roi2-r > span:first-child { color: #556070; }
.roi2-r .mono { font-weight: 700; text-align: right; }
.roi2-est { font-size: 12px; color: #556070; }
.roi2-cta { display: flex; justify-content: center; align-items: center; min-height: 52px; border-radius: 999px; background: #1A202C; color: #fff; font-size: 15px; font-weight: 600; text-decoration: none; }
.roi2-cta:hover { background: #452B90; color: #fff; }
.roi2-note2 { margin: 0; font-size: 13px; color: #556070; line-height: 1.5; }
@media (max-width: 860px) {
  .roi2-head { margin-bottom: 18px; gap: 8px; }
  .roi2-h1 { font-size: 24px; }
  .roi2-sub { font-size: 14px; }
  .roi2 { flex-direction: column; gap: 18px; margin-bottom: 44px; }
  .roi2-form { border: 0; border-radius: 0; padding: 0; gap: 18px; }
  .roi2-row { gap: 12px; }
  .roi2-side { width: 100%; gap: 18px; }
  .roi2-panel { padding: 22px 20px; gap: 10px; }
  .roi2-big { font-size: 40px; }
  .roi2-r { padding: 10px 0; font-size: 13px; }
  .roi2-cta { min-height: 48px; }
  .roi2-note2 { font-size: 11px; }
}

/* — registry trust (rg-trust-*) — */
.rg-trust { margin: var(--wm-sec) 0; padding: 0 var(--wm-pad); display: flex; flex-direction: column; gap: 26px; font-family: "Inter", Inter Fallback, system-ui, sans-serif; color: #1A202C; }
.rg2 .rg-trust { padding: 0; }
.rg-trust-head { display: flex; flex-direction: column; gap: 10px; }
.rg-trust-eyebrow { font-size: 12px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: #452B90; }
.rg-trust-h { margin: 0; font-size: 28px; font-weight: 800; }
.rg-trust-cols { display: flex; gap: 56px; align-items: flex-start; }
.rg-trust-left { flex: 0 0 auto; display: flex; flex-direction: column; gap: 8px; max-width: 340px; }
.rg-trust-big { display: flex; align-items: baseline; gap: 12px; }
.rg-trust-n { font-family: "JetBrains Mono", "SFMono-Regular", monospace; font-size: 64px; font-weight: 700; line-height: 1; }
.rg-trust-nl { font-size: 16px; font-weight: 600; }
.rg-trust-sent, .rg-trust-pct { margin: 0; font-size: 15px; color: #556070; line-height: 1.5; }
.rg-trust-rows { flex: 1 1 0; display: flex; flex-direction: column; min-width: 0; }
.rg-trust-r { display: flex; justify-content: space-between; gap: 32px; padding: 16px 0; border-top: 1px solid #E8EAEE; }
.rg-trust-how { border-bottom: 1px solid #E8EAEE; }
.rg-trust-rl { font-size: 15px; color: #556070; flex-shrink: 0; }
.rg-trust-rv { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; text-align: right; }
.rg-trust-rv b { font-size: 15px; font-weight: 600; }
.rg-trust-rv i { font-style: normal; font-size: 13px; color: #556070; }
.rg-trust-rv a { color: #1A202C; text-decoration: none; }
.rg-trust-rv a:hover b { color: #452B90; }
.rg-trust-foot { display: flex; align-items: center; justify-content: space-between; gap: 40px; border-top: 1px solid #E8EAEE; padding-top: 22px; }
.rg-trust-note { font-size: 13px; color: #556070; max-width: 720px; }
.rg-trust-cta { flex-shrink: 0; display: inline-flex; align-items: center; padding: 12px 22px; border-radius: 999px; background: #1A202C; color: #fff; font-size: 15px; font-weight: 600; text-decoration: none; }
.rg-trust-cta:hover { background: #452B90; color: #fff; }
@media (max-width: 1024px) { .rg-trust { padding: 0 var(--wm-pad); } .rg2 .rg-trust { padding: 0; } }
@media (max-width: 760px) {
  .rg-trust { gap: 18px; }
  .rg-trust-h { font-size: 22px; }
  .rg-trust-cols { flex-direction: column; gap: 18px; }
  .rg-trust-left { max-width: none; }
  .rg-trust-n { font-size: 44px; }
  .rg-trust-r { gap: 18px; padding: 12px 0; }
  .rg-trust-foot { flex-direction: column; align-items: flex-start; gap: 16px; padding-top: 16px; }
}
/* ── W2 sourcing/margin blocks (boards 2026-09-24: Main / PlacesCityPhone /
   HubSellsFor / ShelfNational). One vocabulary for the Places city/state
   block, the hub/shelf «Typical sourcing cost» section and the resale tiles:
   number + band, tint card, chips, number tiles. Skin = the storefront's own
   (Inter, #1A202C/#556070/#452B90/#F4F2FA, 999px pills, JetBrains Mono for
   numbers); spacing joins each host page's section system — no seams here. */
.wsrc-cols { display: flex; gap: 56px; align-items: flex-start; margin-top: 6px; }
.wsrc-main { flex: 1.2 1 0; min-width: 0; }
.wsrc-side { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 16px; }
.wsrc-cap { margin: 0 0 2px; font-size: 13px; font-weight: 600; color: #556070; }
.wsrc-band { position: relative; height: 8px; border-radius: 999px; background: #EDEBF5; margin-top: 14px; }
.wsrc-band i { position: absolute; top: 0; height: 8px; border-radius: 999px; background: #452B90; }
.wsrc-band u { position: absolute; top: -4px; width: 16px; height: 16px; border-radius: 999px; background: #452B90; border: 3px solid #fff; box-sizing: border-box; box-shadow: 0 1px 3px rgba(20,22,40,.25); text-decoration: none; }
.wsrc-scale { display: flex; justify-content: space-between; gap: 8px; margin-top: 8px; font: 500 13px/1.3 "JetBrains Mono", ui-monospace, monospace; color: #556070; }
.wsrc-scale b { color: #1A202C; font-weight: 600; }
.wsrc-nat { margin-top: 12px; padding-top: 10px; border-top: 1px dashed #E8EAEE; }
.wsrc-lede { margin: 14px 0 0; font-size: 17px; line-height: 1.55; color: #1A202C; max-width: 66ch; }
.wsrc-lede b { font-family: "JetBrains Mono", ui-monospace, monospace; font-weight: 700; }
.wsrc-tint { background: #F4F2FA; border-radius: 12px; padding: 20px 24px; display: flex; flex-direction: column; gap: 6px; }
.wsrc-tint .t { margin: 0; font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #452B90; }
.wsrc-tint .n { margin: 0; font: 700 26px/1.2 "JetBrains Mono", ui-monospace, monospace; color: #1A202C; }
.wsrc-tint .c { margin: 0; font-size: 13px; line-height: 1.5; color: #556070; }
.wsrc-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.wsrc-chip { display: inline-flex; align-items: center; padding: 8px 14px; border: 1px solid #E8EAEE; border-radius: 999px; font-size: 13.5px; line-height: 1.3; color: #3B3A4A; background: #fff; }
.wsrc-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-top: 16px; }
.wsrc-tiles.n2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } /* the section's parts share ONE width, the column's (Ivan 2026-09-27: card 960, tiles 960, footnote full — three widths) */
.wsrc-side .wsrc-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 0; }
.wsrc-tile { border: 1px solid #E8EAEE; border-radius: 12px; padding: 16px 18px; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.wsrc-tile .l { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #556070; }
.wsrc-tile .l.is-lead { color: #452B90; }
.wsrc-tile .n { font: 700 24px/1.1 "JetBrains Mono", ui-monospace, monospace; color: #1A202C; }
.wsrc-tile .s { font-size: 12.5px; line-height: 1.45; color: #556070; }
.wsrc-tile .bar { height: 10px; border-radius: 999px; background: #EDEBF5; margin-top: 6px; }
.wsrc-tile .bar i { display: block; height: 10px; border-radius: 999px; background: #452B90; }
.wsrc-tile .bar i.alt { background: #9A8FC4; }
.wsrc-foot { margin-top: 24px; padding-top: 20px; border-top: 1px solid #E8EAEE; display: flex; align-items: center; justify-content: space-between; gap: 40px; }
.wsrc-foot p { margin: 0; font-size: 13px; line-height: 1.55; color: #556070; max-width: 76ch; }
.wsrc-cta { flex-shrink: 0; display: inline-flex; align-items: center; padding: 12px 22px; border-radius: 999px; background: #1A202C; color: #fff; font-size: 15px; font-weight: 600; text-decoration: none; }
.wsrc-cta:hover { background: #2F1D66; color: #fff; }
.wsrc-cta.o { background: #fff; color: #1A202C; border: 1px solid #1A202C; }
.wsrc-cta.o:hover { background: #F4F2FA; color: #1A202C; }
/* the hub/shelf card: title+caption left, number+margin right (board HubSellsFor) */
.wsrc-hcard { flex-direction: row; justify-content: space-between; align-items: center; gap: 32px; }
.wsrc-hcard .wsrc-hl { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.wsrc-hcard .wsrc-hl b { font-size: 15px; font-weight: 600; color: #1A202C; }
.wsrc-hcard .wsrc-hl .c { font-size: 13px; color: #556070; }
.wsrc-hcard .wsrc-hr { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; text-align: right; }
.wsrc-hcard .wsrc-hr .n { font: 700 20px/1.2 "JetBrains Mono", ui-monospace, monospace; color: #1A202C; }
.wsrc-hcard .wsrc-hr .g { font-size: 13px; font-weight: 600; color: #452B90; }
.wsrc-hcard .wsrc-hr .g a { color: #452B90; }
/* Inside the block: the Faire step — card → 24 → «Market comparison»;
 * eyebrow → H2 12 (the storefront rule, Ivan 08.09); H2 → tiles 16. */
.wsrc-geo { margin-top: 24px; }
.wsrc-eyebrow { margin: 0 0 12px; font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: #452B90; }
.wsrc-h { margin: 0; font-size: 24px; font-weight: 800; letter-spacing: -.01em; color: #1A202C; }
.wm-src { margin-top: var(--wm-sec, 64px); }
main[class="hub-wrap"] > .wm-src.hub-sec { margin-top: var(--wm-sec, 64px); }
/* Spliced into the sells-for block (hub.php, Ivan 2026-09-24: above «Related
 * by sales»): the family's .hub-sec 8/34 must not apply — the section keeps
 * the storefront's section gap above (64 / 44) and NO bottom margin, because
 * the next .wpf-section carries the gap as its own padding-top. Measured
 * before: credit line → block 8 px, block → «Related by sales» H2 98 px. */
.hub-sf .wm-src.hub-sec { margin: var(--wm-sec, 64px) 0 0; }
/* Place board (the store's tag vs the pallet median): the tiles fill the
 * section; the day ladder reads as small mono chips under the number. */
.wsrc-place { margin-top: 16px; max-width: none; }
.wsrc-days { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.wsrc-days span { font: 500 12px/1 "JetBrains Mono", ui-monospace, monospace; color: #556070; background: #F4F2FA; border-radius: 999px; padding: 5px 8px; }
.wsrc-days b { color: #1A202C; font-weight: 700; }
@media (max-width: 560px) {
  .wsrc-tiles.n2.wsrc-place { grid-template-columns: minmax(0, 1fr); }
  /* The board's door is a compact pill on a phone, not a full-width 74 px
     slab (Ivan 2026-09-24: «кнопки большие»): content width, 44 px tap. */
  .wsrc-foot .wsrc-cta { align-self: flex-start; min-height: 44px; height: 44px; padding: 0 20px; box-sizing: border-box; }
}
@media (max-width: 900px) {
  .wsrc-cols { flex-direction: column; gap: 18px; }
  .wsrc-tiles, .wsrc-tiles.n2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .wsrc-foot { flex-direction: column; align-items: stretch; gap: 12px; margin-top: 18px; }
  .wsrc-cta { justify-content: center; min-height: 48px; }
  .wsrc-tint { padding: 16px; }
  .wsrc-tint .n { font-size: 22px; }
  .wsrc-hcard { flex-direction: column; align-items: stretch; gap: 10px; }
  .wsrc-hcard .wsrc-hr { align-items: flex-start; text-align: left; }
  .wsrc-h { font-size: 20px; }
}

/* Product-noun / store-type / seasonal pages (WholesaleNounPages, 2026-09-24):
   the answer paragraph under the heading and the market figures. The sections
   themselves are the shared .wsf-faq band (one design, the shared gutter). */
.wsn-answer { max-width: 860px; margin: 12px 0 0; padding: 0 var(--wm-pad); font-size: 15px; line-height: 1.55; color: #374151; }
.wsn-answer .wsn-asof { display: block; margin-top: 6px; font-size: 12.5px; color: #6B7280; }
.wsn-figs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin: 0; }
.wsn-figs div { border: 1px solid #E4E2EE; border-radius: 12px; padding: 14px 16px; }
.wsn-figs dt { font-size: 12.5px; color: #6B7280; }
.wsn-figs dd { margin: 4px 0 0; font-family: "Poppins", Poppins Fallback, "Inter", Inter Fallback, system-ui, sans-serif; font-weight: 600; font-size: 20px; color: #1A202C; }
.wsn-tool { margin: 16px 0 0; font-weight: 600; }
.wsn-guide-k { margin: 18px 0 4px; font-size: 16px; font-weight: 600; }
.wsn-guide-k:first-child { margin-top: 0; }
@media (max-width: 1023px) { .wsn-answer { padding: 0 var(--wm-pad); } }
@media (max-width: 640px) { .wsn-figs { grid-template-columns: 1fr; } }

/* ─── Copy guard (operator ТЗ 2026-09-26, wholesale_copy_guard_enabled;
   fresh-review correction 2026-09-26 P0) ───────────────────────────────────
   Stops a casual buyer copying a lot's title/description or dragging/saving
   its photos, so the title cannot be pasted into Google to find the same
   supplier cheaper. TWO gates, both server-printed (WholesaleCopyGuard):
     1. body.wsm-copyguard — the page is not one of the buyer's OWN
        purchased-item pages (the order list/detail).
     2. .wsm-cg — the ELEMENT is an actual lot surface: the lot card
        (market/_card.php's root, plus the hand-rolled cards in
        _rails_ssr/off_market/programmatic/saved/bag), the lot page's title,
        description, manifest/facts table and gallery, and the checkout
        order-summary line. The registry's OWN store/chain cards
        (_place_card.php, _place_chain_cards.php, places_chains.php,
        catalog.php) reuse .wm-card/.wm-card-title for a SUPPLIER name and
        never carry .wsm-cg, so a directory page stays copyable WITHOUT a
        page-level allowlist — the guard follows the marker, not the route,
        so a lot rail on any current or future page (places_city.php,
        places_chain_city.php, places_country.php, places_intl.php, …) is
        caught automatically.
   CSS-only guard; the JS in wholesale-market.js only backs up the
   keyboard/menu paths CSS user-select:none does not reach on every browser.
   Never touches HTML text or JSON-LD — Google reads the page exactly as
   before. Both classes are server-printed ⇒ a flag flip needs the
   storefront cache purged (see the deploy recipe / operator brief). */
/* Ivan 26.09 (second pass): the WHOLE page is guarded — lot surfaces AND the registry / Places
   directory (supplier and store names were the leak), header and footer included. Only form
   fields stay selectable; the buyer's purchased-item pages never get the body class at all
   (WholesaleCopyGuard::excluded). .wsm-cg markers stay in the HTML, harmless. */
body.wsm-copyguard {
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
body.wsm-copyguard img {
  -webkit-user-drag: none;
}
/* A LINK stays a link (Ivan 27.09): the guard must not cost a lot card its right-click «Open
   link in new tab» or the phone's long-press link menu. iOS draws that menu only where
   touch-callout is not `none`, so links opt back in. An <img> INSIDE a link takes no pointer
   events: the right-click / long-press then lands on the <a> and the browser offers the LINK
   menu, never «Save image as» / «Copy image» — the photo stays guarded, the card stays a link.
   The JS guard (wholesale-market.js) lets `contextmenu` through on a[href] for the same reason. */
body.wsm-copyguard a[href] {
  -webkit-touch-callout: default;
}
body.wsm-copyguard a[href] img {
  pointer-events: none;
}
body.wsm-copyguard input,
body.wsm-copyguard textarea,
body.wsm-copyguard select,
body.wsm-copyguard [contenteditable],
body.wsm-copyguard [contenteditable] * {
  -webkit-user-select: text;
  -moz-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

/* The SOLD card (_card.php sold mode, Faire): one rule for every surface that shows an
   ended lot — the supplier Sold tab and the bag (moved from supplier.php, 2026-09-28). */
.wm-card.is-sold .wm-card-photo img,.wm-card.is-sold .wm-card-photo.has-cover{filter:saturate(.8)}
.wm-sold-ribbon{position:absolute;z-index:2;top:10px;right:10px;padding:3px 9px;border-radius:5px;background:#1A202C;color:#fff;font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase}
.wm-card-cta.wm-card-cta--sold{color:#3A4556;font-weight:600}
.wm-card.is-sold:hover .wm-card-cta--sold{color:#1A202C}
.wm-sold-ribbon.is-held{background:#452B90}
.wm-card.is-held .wm-card-photo img,.wm-card.is-held .wm-card-photo.has-cover{filter:none}
.wm-card.is-held .wm-card-cta--sold{color:#452B90}
/* ── S4S (2026-09-29, wsm_supplier_zero_live_v1): the supplier name page at 0 live lots —
   its Sold history in the Zillow order. ONE rule set for the status line under the tabs
   (with its «Alert me →» anchor) and the Sold tab's tiles printed after the grid. ── */
.wm-sup-zero.wm-hub2-sec{margin-bottom:0}
.wm-sup-zero-line{margin:0;font-size:15px;line-height:1.6;color:#3A4556}
.wm-sup-zero-line b{display:inline-flex;align-items:center;gap:8px;vertical-align:baseline;font-family:Poppins, Poppins Fallback,Inter, Inter Fallback,sans-serif;font-size:17px;font-weight:700;color:#0F1729}
.wm-sup-zero-line b::before{content:"";width:9px;height:9px;border-radius:50%;background:#B45309;flex:0 0 auto}
.wm-sup-zero-line .mono{font-family:"JetBrains Mono",ui-monospace,monospace;font-size:14px;font-weight:500;color:#0F1729}
.wm-sup-zero-alert{margin-left:6px;font-size:14px;font-weight:600;color:#452B90;text-decoration:none;white-space:nowrap}
.wm-sup-zero-alert:hover{text-decoration:underline}
.wm-sup-soldpage .wm-sup-soldhead.is-after{margin-top:34px}
.wm-sup-soldsum.is-after{margin:0}
@media (max-width:640px){.wm-sup-zero-line{font-size:14px}.wm-sup-zero-line b{font-size:16px}.wm-sup-zero-alert{font-size:13.5px}.wm-sup-soldpage .wm-sup-soldhead.is-after{margin-top:26px}}
/* A brand's About band (_category_intro.php, Ivan 02.10): «Ships from» and «Shelves» chip rows under the lede */
.wm-about-chips { margin-top: 16px; }
.wm-about-chips > b { display: block; margin-bottom: 8px; font: 600 12px/1.3 Inter, Inter Fallback, sans-serif; letter-spacing: .06em; text-transform: uppercase; color: #556070; }
.wm-about-chips .wsf-related-chips { padding-top: 0; }
.hub-facts-more > summary { margin-top: 12px; }
/* W3 lot page (ADR D3, 2026-10-02): the signed-in buyer's buy box and manifest while their personal
   copy is swapped in (wholesale-lot-viewer.js). Set ONLY once the fragment has said «signed in» — an
   anonymous reader never sees it. Dims in place: no size change, so no layout shift; taps wait. */
[data-wsm-lot-buybox].is-hydrating, [data-wsm-lot-manifest].is-hydrating { opacity: .55; pointer-events: none; transition: opacity .15s ease; }
@media (prefers-reduced-motion: reduce) { [data-wsm-lot-buybox].is-hydrating, [data-wsm-lot-manifest].is-hydrating { transition: none; } }

/* ── Closo Reseller Panel share blocks (Ivan 2026-10-02; _reseller_panel.php) ──────────────
   ONE component on four owner pages: /wholesale/from/<state> (and a metro's anchor city page),
   /registry/in/<st>, /registry/places/<kind>/in/<st>. The block brings NO gutter and NO section
   margin of its own: the host's section class does (`.wm-sec` + the programmatic rhythm list
   above, `.wpl-sec` in `.wpl-doc`, `.rg-sec` on the registry), so the 64 / 44 seam is the page's.
   Shares are printed, never counts. Palette = the storefront's closed one (accent #452B90, tint
   #EDE8F8, line #E4E2EE, edge #7A7290); the bars are the accent's own ramp. */
/* The Reseller Panel block (_reseller_panel.php) joined the ONE section rule above as a top-level
   `.rpb.wm-sec`. Its BOTTOM keeps the token too, on purpose: on a programmatic page with the filter
   rail, [data-wsm-page="programmatic"] sits inside .wm-layout, so `body.wm:has(> [data-wsm-page…])`
   does not match and the sections after the grid keep their old 24px tops (measured 2026-10-04 on
   /wholesale/from/texas: suppliers → «How it works» 24px — pre-existing, reported, not changed here).
   This bottom margin collapses with the next section's top, so the seam on each side of the block is
   --wm-sec (64 / 44) without touching the neighbours; where the family rule does match, the next
   section brings 64 itself and the collapse changes nothing. */
body.wm > .rpb.wm-sec { margin-bottom: var(--wm-sec); }
.rpb-head { max-width: 760px; margin: 0 0 28px; }
.rpb-h { font: 600 clamp(24px, 2.4vw, 30px)/1.18 "Poppins", Poppins Fallback, "Inter", Inter Fallback, system-ui, sans-serif; letter-spacing: -.02em; color: #1A202C; margin: 0 0 10px; text-wrap: balance; }
.rpb-lede { font: 400 15px/1.6 Inter, Inter Fallback, system-ui, sans-serif; color: #556070; margin: 0; max-width: 72ch; text-wrap: pretty; }
.rpb-grid { display: grid; gap: 20px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.rpb-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.rpb-grid--1 { grid-template-columns: minmax(0, 560px); }
.rpb-card { display: flex; flex-direction: column; min-width: 0; box-sizing: border-box; background: #fff; border: 1px solid #E4E2EE; border-radius: 18px; padding: 22px 24px 24px; }
.rpb-card-label { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; font: 700 12px/1.3 Inter, Inter Fallback, system-ui, sans-serif; letter-spacing: .08em; text-transform: uppercase; color: #452B90; }
.rpb-ico { flex: none; width: 18px; height: 18px; display: block; }
.rpb-card-h { font: 600 18px/1.3 "Poppins", Poppins Fallback, "Inter", Inter Fallback, system-ui, sans-serif; color: #1A202C; margin: 0 0 18px; text-wrap: balance; }
.rpb-bars { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.rpb-bar { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; column-gap: 12px; row-gap: 6px; }
.rpb-bar-l { min-width: 0; font: 400 14px/1.35 Inter, Inter Fallback, system-ui, sans-serif; color: #333A45; overflow-wrap: anywhere; }
.rpb-pct { font: 600 14px/1 "JetBrains Mono", ui-monospace, monospace; color: #1A202C; font-variant-numeric: tabular-nums; white-space: nowrap; }
.rpb-track { grid-column: 1 / -1; display: block; height: 8px; border-radius: 999px; background: #F0EEF6; overflow: hidden; }
.rpb-fill { display: block; height: 100%; border-radius: inherit; background: #B9A9E3; }
.rpb-bar.is-top .rpb-fill { background: #452B90; }
.rpb-bar.is-other .rpb-bar-l { color: #556070; }
.rpb-bar.is-other .rpb-fill { background: #D5D8DE; }
.rpb-stack { display: flex; gap: 2px; height: 14px; border-radius: 999px; overflow: hidden; }
.rpb-stack-seg { flex-basis: 0; min-width: 4px; }
.rpb-tone-0 { background: #452B90; } .rpb-tone-1 { background: #7C63C7; } .rpb-tone-2 { background: #B9A9E3; } .rpb-tone-3 { background: #DCD3F2; } .rpb-tone-o { background: #D5D8DE; }
.rpb-legend { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 10px; }
.rpb-legend li { display: flex; align-items: center; gap: 10px; font: 400 14px/1.35 Inter, Inter Fallback, system-ui, sans-serif; color: #333A45; }
.rpb-legend-l { flex: 1; min-width: 0; }
.rpb-dot { flex: none; width: 10px; height: 10px; border-radius: 3px; }
.rpb-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; margin-top: 28px; }
.rpb-btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 48px; box-sizing: border-box; padding: 0 26px; border-radius: 999px; background: #452B90; color: #fff; font: 600 15px/1.2 Inter, Inter Fallback, system-ui, sans-serif; text-decoration: none; transition: background .15s ease; }
.rpb-btn:hover { background: #321F69; color: #fff; }
.rpb-btn:focus-visible { outline: 2px solid #1A202C; outline-offset: 2px; }
.rpb-chips { display: flex; flex-wrap: wrap; gap: 10px; min-width: 0; }
.rpb-chips .relchip .relchip-v { font: 400 12.5px/1.25 Inter, Inter Fallback, system-ui, sans-serif; color: #7A7290; }
.rpb-caption { margin: 16px 0 0; font: 400 12.5px/1.4 Inter, Inter Fallback, system-ui, sans-serif; color: #7A7290; }
.rpb-caption a { color: #452B90; text-decoration: underline; text-underline-offset: 2px; }
@media (max-width: 960px) {
  .rpb-grid, .rpb-grid--2, .rpb-grid--1 { grid-template-columns: minmax(0, 1fr); gap: 14px; }
}
@media (max-width: 760px) {
  .rpb-head { margin-bottom: 20px; }
  .rpb-h { font-size: 22px; }
  .rpb-lede { font-size: 14.5px; }
  .rpb-card { padding: 18px 18px 20px; border-radius: 16px; }
  .rpb-card-h { font-size: 17px; margin-bottom: 14px; }
  .rpb-foot { margin-top: 20px; }
  .rpb-btn { width: 100%; }
}

/* ── Closo Research — subscription form (zone D, contracts §8; modules/shop/views/research/_rs_subscribe.php).
   Moved from the partial's inline <style> (fresh review 2026-10-05, P2): one shared sheet, rs-* names kept. ── */
.rs-subscribe{border:1px solid #E4E2EE;border-radius:12px;padding:24px;background:#fff;max-width:720px}
.rs-subscribe-title{margin:0 0 6px;font-size:20px;line-height:1.3;font-weight:700;color:#1A202C}
.rs-subscribe-lede{margin:0 0 20px;font-size:15px;line-height:1.5;color:#556070}
.rs-subscribe-form{display:grid;gap:16px}
.rs-subscribe-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px}
.rs-subscribe-field{display:grid;gap:6px;min-width:0;margin:0;padding:0;border:0}
.rs-subscribe-field>label,.rs-subscribe-field>legend{padding:0;font-size:13px;font-weight:600;color:#1A202C}
.rs-subscribe-field input[type=email],.rs-subscribe-field input[type=text],.rs-subscribe-field select{width:100%;box-sizing:border-box;height:44px;padding:0 12px;border:1px solid #D9D6E6;border-radius:8px;background:#fff;font:inherit;font-size:15px;color:#1A202C}
.rs-subscribe-field input:focus,.rs-subscribe-field select:focus{outline:2px solid #452B90;outline-offset:1px;border-color:#452B90}
.rs-subscribe-note{font-size:12px;color:#556070}
.rs-subscribe-chips{display:flex;flex-wrap:wrap;gap:8px}
.rs-subscribe-chip{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid #D9D6E6;border-radius:999px;font-size:14px;color:#1A202C;cursor:pointer}
.rs-subscribe-chip input{margin:0;accent-color:#452B90}
.rs-subscribe-chip:has(input:checked){border-color:#452B90;background:#F7F5FC}
.rs-subscribe.is-js [data-rs-for]:not(.is-on){display:none}
.rs-subscribe-trap{position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden}
.rs-subscribe-actions{display:flex;flex-wrap:wrap;align-items:center;gap:12px 16px}
.rs-subscribe-btn{height:44px;padding:0 22px;border:0;border-radius:8px;background:#452B90;color:#fff;font:inherit;font-size:15px;font-weight:600;cursor:pointer}
.rs-subscribe-btn:hover{background:#321F69}
.rs-subscribe-btn[disabled]{opacity:.6;cursor:default}
.rs-subscribe-hint{margin:0;font-size:14px;color:#B42318}
.rs-subscribe-ok{margin:0;padding:14px 16px;border-radius:8px;background:#E8F5EC;font-size:15px;color:#186A3B}
@media (max-width:760px){.rs-subscribe{padding:16px}.rs-subscribe-row{grid-template-columns:minmax(0,1fr)}}

/* ── Closo Research — demand strip (zone D, contracts §8; modules/shop/views/market/_research_strip.php,
   on the category shelf and every hub). Index, change and share figures only — never a count. ── */
.rs-strip{margin-top:32px;border:1px solid #452B90;border-radius:12px;padding:20px 24px;background:#F7F5FC;display:grid;grid-template-columns:minmax(0,1.4fr) repeat(3,minmax(0,1fr)) auto;gap:24px;align-items:center}
.rs-strip-head{min-width:0}
.rs-strip-eyebrow{display:flex;align-items:center;gap:8px;margin:0 0 6px;font-family:"JetBrains Mono",ui-monospace,monospace;font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:#556070}
.rs-strip-eyebrow svg{color:#452B90}
.rs-strip-lede{margin:0;font-size:15px;line-height:1.45;color:#1A202C}
.rs-strip-note{display:block;margin-top:4px;font-size:12px;color:#556070}
.rs-strip-item{min-width:0}
.rs-strip-value{display:block;font-family:"JetBrains Mono",ui-monospace,monospace;font-weight:500;font-variant-numeric:tabular-nums;font-size:26px;line-height:1.1;color:#1A202C}
.rs-strip-value.is-none{font-size:15px;line-height:1.4;color:#556070}
.rs-strip-label{display:block;font-size:13px;color:#556070}
.rs-strip-link{font-size:14px;font-weight:500;white-space:nowrap;color:#452B90;text-decoration:none}
.rs-strip-link:hover{color:#321F69;text-decoration:underline}
/* W2 2026-10-08: a lot strip with a category AND its single brand stacks the two links in the last column */
.rs-strip-links{display:flex;flex-direction:column;align-items:flex-start;gap:6px;min-width:0}
@media (max-width:760px){.rs-strip{grid-template-columns:repeat(3,minmax(0,1fr));gap:16px 12px;padding:16px}.rs-strip-head,.rs-strip-link,.rs-strip-links{grid-column:1/-1}.rs-strip-value{font-size:22px}}
/* wave 3 (Ivan 2026-10-23, Faire collection cards): THE theme card — /wholesale/themes grid and the
   home «Collections» rail. A 2x2 mosaic of the theme's own lots (fewer photos fill the square), the
   name, one line «{n} lots · from $X · categories». */
.wsf-theme{display:flex;flex-direction:column;gap:4px;min-width:0;color:#1A202C;text-decoration:none}
.wsf-theme:hover{color:#1A202C}
.wsf-theme:hover .wsf-theme-mo{box-shadow:0 10px 28px rgba(26,32,44,.12)}
.wsf-theme-mo{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;gap:2px;aspect-ratio:1/1;border-radius:12px;overflow:hidden;background:#F1ECFA;margin-bottom:6px;transition:box-shadow .15s ease}
.wsf-theme-mo img{width:100%;height:100%;object-fit:cover;display:block;min-width:0;min-height:0}
.wsf-theme-mo.is-n1 img{grid-column:1/-1;grid-row:1/-1}
.wsf-theme-mo.is-n2 img{grid-row:1/-1}
.wsf-theme-mo.is-n3 img:first-child{grid-row:1/-1}
.wsf-theme-t{font-size:15px;font-weight:700;line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wsf-theme-l{font-size:13px;line-height:1.4;color:#556070;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.wsf-theme-sec{margin-bottom:72px}
.wsf-theme-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:28px 16px}
@media (max-width:960px){.wsf-theme-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:640px){.wsf-theme-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:20px 12px}.wsf-theme-sec{margin-bottom:44px}.wsf-theme-t{font-size:14px}}
@media (prefers-reduced-motion:reduce){.wsf-theme-mo{transition:none}}
/* wave 3: the Collections menu groups (By condition · By size · By theme · Lists) — a theme's live lot count */
.mm-n{margin-left:6px;font-size:12px;font-weight:500;color:#6B7280;font-variant-numeric:tabular-nums}
.mm-foot.mm-foot--groups{flex-direction:column;align-items:flex-start;gap:10px}
/* wave 3 task H (Ivan 2026-10-23, Faire home rows): the row head eyebrow (the .wsrc-eyebrow
   type), the home «Collections» card rail (chips toggle server-rendered tracks; 4 cards visible
   desktop, 2 on a phone), the condition gradient cards and the photo ribbon «New · today». */
.wsf-row-eyebrow { margin: 0 0 12px; font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: #452B90; }
.wsf-rail { gap: 16px; }
.wsf-rail-end { display: flex; align-items: center; gap: 16px; flex-shrink: 0; }
/* Ivan 2026-10-25 («листающими а не в два ряда»): ONE line that swipes sideways on a phone,
   never a second row — the .wm-fmt-tabs scroller; the cut last chip says there is more.
   overflow-x clips y too: the 4px pad (cancelled by -4px margin) keeps the 2px+2px focus ring whole. */
.wsf-rail-chips { display: flex; flex-wrap: nowrap; gap: 8px; padding: 4px; margin: -4px; overflow-x: auto; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.wsf-rail-chips::-webkit-scrollbar { display: none; }
.wsf-rail-chips > .wm-chip { flex: 0 0 auto; white-space: nowrap; }
/* H4 (review P1): the New this week row while a chip's cards are read in place. */
.wsf-lots[aria-busy="true"] { opacity: .55; transition: opacity .15s ease; }
.wsf-rail-track[hidden] { display: none !important; }
.wsf-rail-track>* { flex: 0 0 calc((100% - 3 * 12px) / 4); min-width: 0; box-sizing: border-box; scroll-snap-align: start; }
.wsf-cond { position: relative; display: flex; flex-direction: column; justify-content: flex-end; gap: 4px; min-height: 120px; aspect-ratio: 1/1; padding: 14px; border-radius: 12px; color: #1A202C; text-decoration: none; transition: box-shadow .15s ease; }
.wsf-cond:hover { color: #1A202C; box-shadow: 0 10px 28px rgba(26,32,44,.12); }
.wsf-cond-ic { position: absolute; top: 14px; right: 14px; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; color: #452B90; }
.wsf-cond-ic svg { width: 24px; height: 24px; }
.wsf-cond-t { font-size: 15px; font-weight: 700; line-height: 1.3; }
.wsf-cond-l { font-size: 13px; line-height: 1.4; color: #556070; }
.wsf-ribbon { position: absolute; top: 10px; left: 10px; z-index: 2; background: #FFFFFF; color: #452B90; box-shadow: 0 1px 4px rgba(26,32,44,.14); }
@media (max-width:640px) { .wsf-rail-track>* { flex-basis: calc((100% - 12px) / 2.1); } .wsf-rail-end .wsf-car-nav { display: none !important; } }
@media (prefers-reduced-motion:reduce) { .wsf-cond { transition: none; } }
