/* Outdoor Living Trade — theme styles.
   Tokens live in style.css. Nothing here hardcodes a colour. */

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

body {
  margin: 0;
  background: var(--olt-paper);
  color: var(--olt-ink);
  font-family: var(--olt-body);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, .olt-display {
  font-family: var(--olt-display);
  font-weight: 300;
  letter-spacing: -0.012em;
  line-height: 1.18;
  text-wrap: pretty;
  margin: 0 0 0.5em;
}
h1 { font-size: clamp(30px, 4.2vw, 46px); }
h2 { font-size: clamp(25px, 3vw, 32px); }
h3 { font-size: 20px; font-weight: 400; }

p { margin: 0 0 1em; }
a { color: var(--olt-brand-text); text-decoration: none; }
a:hover { color: var(--olt-action-hover); }
a:focus-visible, button:focus-visible, summary:focus-visible {
  outline: 2px solid var(--olt-brand-deep); outline-offset: 3px; border-radius: 2px;
}
img { max-width: 100%; height: auto; }
[hidden] { display: none !important; }

.mono, .olt-card__code, .olt-card__logistics, .olt-spec-value {
  font-family: var(--olt-mono);
  font-variant-numeric: tabular-nums;
}

.olt-skip {
  position: absolute; left: -9999px;
}
.olt-skip:focus {
  left: 12px; top: 12px; z-index: 100; background: var(--olt-ink);
  color: #fff; padding: 10px 16px;
}

/* ---------- layout ---------- */

.olt-wrap { max-width: var(--olt-max); margin: 0 auto; padding-inline: var(--olt-gutter); }
.olt-wrap--narrow { max-width: 760px; padding-block: 48px 72px; }
.olt-wrap--wide { padding-block: 0 72px; }

/* ---------- buttons ---------- */

.olt-btn, .olt-btn--ghost {
  font-family: var(--olt-display);
  font-weight: 500;
  font-size: 14px;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 13px 22px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.olt-btn { background: var(--olt-action); color: #fff; }
.olt-btn:hover { background: var(--olt-action-hover); color: #fff; }
.olt-btn--ghost { background: transparent; color: var(--olt-ink); border-color: var(--olt-ink); }
.olt-btn--ghost:hover { background: var(--olt-ink); color: #fff; }
.olt-btn--loop { width: 100%; justify-content: center; padding: 11px 16px; font-size: 13px; }
.olt-link { font-family: var(--olt-display); font-size: 14px; color: var(--olt-ink-2); }

/* ---------- header ---------- */

.olt-header {
  background: var(--olt-surface);
  border-bottom: 1px solid var(--olt-rule-soft);
  position: sticky;
  top: env(safe-area-inset-top, 0px);
  z-index: 40;
}
.olt-header.is-scrolled { box-shadow: 0 1px 12px -6px rgba(1, 48, 51, .22); }
.olt-header__inner {
  max-width: var(--olt-max); margin: 0 auto;
  padding-inline: var(--olt-gutter);
  min-height: 108px;
  display: flex; align-items: center; gap: 28px;
}
.olt-brand { display: flex; align-items: center; gap: 11px; color: var(--olt-ink); }
/* The raw logo lime, 2.65:1 on white. Logos and brand names are exempt from
   the contrast minimum (WCAG 1.4.3) — and this one has to match the artwork. */
.olt-brand__mark { color: var(--olt-logo-lime); display: flex; }
.olt-brand__name {
  font-family: var(--olt-display); font-size: 21px; font-weight: 400;
  letter-spacing: -0.01em; display: block; line-height: 1.1;
}
.olt-brand__tld { color: var(--olt-ink-3); }
.olt-brand__strap {
  /* ink-3, not ink-4: this is 8px uppercase text and it has to clear 4.5:1 */
  font-family: var(--olt-display); font-size: 8px; font-weight: 500;
  letter-spacing: 0.24em; text-transform: uppercase; color: var(--olt-ink-3);
  display: block; margin-top: 2px;
}
.olt-brand--sm .olt-brand__name { font-size: 17px; }

/* The uploaded logo, when Site Identity has one. The artwork is 2:1 and holds
   both the icon and a two-line wordmark, so it is sized by height and given
   room to breathe rather than squeezed into the text lockup's footprint. */
.olt-brand--logo { gap: 0; }
/* The artwork is roughly 3:1, so height drives the width. 76px tall gives a
   lockup about 228px wide — the dominant element in the bar, which is the
   point. The header grows to match rather than the logo being squeezed into
   a bar sized for a text mark. */
/* SPECIFICITY, and why every header rule below is prefixed .olt-header.
   woocommerce-layout.css ships:
       .woocommerce img, .woocommerce-page img { height: auto; max-width: 100% }
   That is (0,1,1). A bare .olt-brand__logo is (0,1,0), so WooCommerce won on
   EVERY WooCommerce page — shop, product, cart, checkout, my-account and the
   trade dashboard — and the header logo rendered at its natural aspect.
   Measured on /my-account/ 16 Oct: 757x206 instead of 280x76, which pushed the
   header to 206px tall and broke the menu onto three lines. Load order does not
   help here; theme.css already loads last and still lost.
   .olt-header .olt-brand__logo is (0,2,0) and wins everywhere.
   The footer uses .olt-brand--sm .olt-brand__logo, already (0,2,0), so it was
   never affected and needs no prefix. */
/* REGRESSION, 16 Oct: scoping the whole base rule to .olt-header took
   width:auto, display:block and object-fit:contain away from the FOOTER logo,
   which only ever got its height and max-width from .olt-brand--sm. Without
   width:auto the img fell back to its width="1899" HTML attribute, clamped to
   max-width:320px, and without object-fit it stretched to fill 320x58 instead
   of letterboxing at its natural 213x58. The footer mark was rendering 50%
   too wide.
   My own specificity guard passed it, because it only checked height and
   max-width — the two properties that were never the footer's problem.
   So: the shared, non-sizing declarations stay unscoped (nothing in
   WooCommerce contests width, display or object-fit), and only the SIZING is
   scoped, because sizing is the only part that has to outrank
   `.woocommerce img`. */
.olt-brand__logo {
  display: block; width: auto; object-fit: contain;
}
.olt-header .olt-brand__logo { height: 76px; max-width: 400px; }
.olt-brand--sm .olt-brand__logo { height: 58px; max-width: 320px; }
@media (max-width: 900px) {
  .olt-header .olt-brand__logo { height: 50px; max-width: 260px; }
  .olt-brand--sm .olt-brand__logo { height: 44px; max-width: 230px; }
}
@media (max-width: 420px) {
  .olt-header .olt-brand__logo { height: 42px; max-width: 200px; }
}

/* The header is sticky, so a 108px bar would eat the screen on the way down.
   Full size at the top where it introduces the brand, compact once scrolling.
   The .is-scrolled class is already toggled by theme.js. */
.olt-header__inner,
.olt-brand__logo { transition: min-height .18s ease, height .18s ease; }
.olt-header.is-scrolled .olt-header__inner { min-height: 74px; }
.olt-header.is-scrolled .olt-brand__logo { height: 52px; }

@media (prefers-reduced-motion: reduce) {
  .olt-header__inner,
  .olt-brand__logo { transition: none; }
}

/* Visually hidden but read aloud. Core markup and olt_brand() both rely on it. */
.screen-reader-text {
  position: absolute !important; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  border: 0;
}
.screen-reader-text:focus {
  position: static !important; width: auto; height: auto; margin: 0;
  clip-path: none; white-space: normal;
}

/* ---------------------------------------------------------------- utility bar
   The trade claim and the phone number, above the header proper. It is the
   first thing a buyer looks for and it should not cost them a click. */
.olt-utility { background: var(--olt-ink); color: #e4ebda; }
.olt-utility__inner {
  max-width: var(--olt-max); margin: 0 auto; padding: 7px var(--olt-gutter);
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  font-size: 12.5px; line-height: 1.5;
}
.olt-utility__claim { margin: 0; color: var(--olt-brand-on-ink); font-weight: 500; }
.olt-utility__contact { display: flex; gap: 22px; list-style: none; margin: 0; padding: 0; }
.olt-utility__contact a { color: #e4ebda; font-variant-numeric: tabular-nums; }
.olt-utility__contact a:hover { color: #fff; text-decoration: underline; }

/* ----------------------------------------------------------------------- nav */
.olt-nav { margin-left: auto; }
/* nowrap matters: the logo lockup is wide, and without this the bar squeezes
   multi-word items like "How it works" onto three lines rather than wrapping
   the bar itself. Below 1200px the gaps tighten before anything breaks. */
.olt-menu { display: flex; align-items: center; gap: 4px; list-style: none; margin: 0; padding: 0; }
.olt-menu__item { white-space: nowrap; }
@media (max-width: 1280px) {
  .olt-menu__item > a,
  .olt-menu__trigger { padding-inline: 8px; font-size: 14px; }
  .olt-header .olt-brand__logo { height: 64px; max-width: 330px; }
}
@media (max-width: 1100px) {
  .olt-header .olt-brand__logo { height: 54px; max-width: 280px; }
  .olt-menu__item > a,
  .olt-menu__trigger { padding-inline: 6px; font-size: 13.5px; }
}
.olt-menu__item > a,
.olt-menu__trigger {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--olt-display); font-size: 14.5px; font-weight: 400;
  color: var(--olt-ink-2); background: none; border: 0; cursor: pointer;
  padding: 9px 12px; border-radius: 3px; line-height: 1;
}
.olt-menu__item > a:hover,
.olt-menu__trigger:hover { color: var(--olt-ink); background: var(--olt-brand-wash); }
.olt-menu__item.is-current > a,
.olt-menu .current-menu-item > a,
.olt-menu .current-page-ancestor > a {
  color: var(--olt-ink); box-shadow: inset 0 -1.5px 0 var(--olt-brand-deep);
}
.olt-menu__chev { transition: transform .16s ease; }
.olt-menu__item--has-panel.is-open .olt-menu__chev { transform: rotate(180deg); }
.olt-menu__item--has-panel.is-open .olt-menu__trigger { color: var(--olt-ink); background: var(--olt-brand-wash); }

/* ----------------------------------------------------- the products dropdown */
.olt-menu__item--has-panel { position: static; }
.olt-panel {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 40;
  background: var(--olt-surface);
  border-top: 1px solid var(--olt-rule);
  box-shadow: 0 18px 34px -24px rgba(1, 48, 51, .5);
}
/* The column count comes from PHP, via --olt-panel-cols on the element, because
   it must equal the number of top-level categories in olt_category_tree().
   It was hardcoded `repeat(5, 1fr) 1.2fr` — six tracks — written when the
   taxonomy had five top-level categories and the note sat in the sixth as a
   sidebar. The real catalogue import produced SIX (Sofas, Dining Furniture,
   Beds & Mattresses, Living Room, Garden, Christmas), which filled all six
   tracks and pushed the note onto a second row, squeezed into column 1 at 194px
   wide. That is the squashed box at the bottom of the menu.
   The note now spans the full width as a deliberate bottom strip, so it cannot
   break again however many categories are added. */
.olt-panel__inner {
  max-width: var(--olt-max); margin: 0 auto; padding: 30px var(--olt-gutter) 34px;
  display: grid;
  grid-template-columns: repeat(var(--olt-panel-cols, 6), minmax(0, 1fr));
  gap: 30px;
}
.olt-panel__col--note {
  grid-column: 1 / -1;
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 18px;
  margin-top: 4px;
}
/* --olt-ink, not the --olt-ink-2 used for body copy elsewhere: on
   --olt-brand-wash that token is 4.39:1, just under the 4.5:1 floor. There is
   no token between the two, so this box takes the darker one. */
.olt-panel__col--note .olt-panel__copy { margin: 0; flex: 1 1 320px; color: var(--olt-ink); }
.olt-panel__col--note .olt-panel__eyebrow { margin: 0; flex: 0 0 auto; }
.olt-panel__head {
  display: block; font-family: var(--olt-display); font-size: 14px; font-weight: 500;
  color: var(--olt-ink); padding-bottom: 9px; margin-bottom: 9px;
  border-bottom: 1px solid var(--olt-rule);
}
.olt-panel__head:hover { color: var(--olt-brand-text); }
.olt-panel__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }
.olt-panel__list a { font-size: 13.5px; color: var(--olt-ink-2); }
.olt-panel__list a:hover { color: var(--olt-brand-text); }
.olt-panel__col--note {
  background: var(--olt-brand-wash); padding: 18px 20px; border-radius: 3px;
}
.olt-panel__eyebrow {
  font-family: var(--olt-display); font-size: 9.5px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase; color: var(--olt-brand-text);
  margin: 0 0 8px;
}
.olt-panel__copy { font-size: 13px; color: var(--olt-ink-2); margin: 0 0 12px; line-height: 1.55; }
/* Explicit, not inherited. The base .olt-link colour (--olt-ink-2) lands at
   4.39:1 on --olt-brand-wash — under the 4.5:1 floor by a hair, which is the
   kind of near-miss that survives a glance. --olt-ink is 9.71:1 here and
   matches the panel headings. */
.olt-panel__col--note .olt-link { color: var(--olt-ink); font-weight: 500; }
.olt-panel__col--note .olt-link:hover { color: var(--olt-brand-text); }
.olt-link--arrow::after { content: " \2192"; }

/* --------------------------------------------------------- burger and mobile */
.olt-burger {
  display: none; align-items: center; justify-content: center;
  width: 42px; height: 42px; margin-left: 10px;
  background: none; border: 1px solid var(--olt-rule); border-radius: 3px; cursor: pointer;
}
.olt-burger__bars { display: grid; gap: 4px; width: 17px; }
.olt-burger__bars span { height: 1.5px; background: var(--olt-ink); border-radius: 2px; }
.olt-mobile { display: none; border-top: 1px solid var(--olt-rule); background: var(--olt-surface); }
.olt-mobile__actions { display: flex; flex-direction: column; gap: 10px; padding: 0 var(--olt-gutter) 22px; }
.olt-mobile__actions .olt-btn { justify-content: center; }
.olt-header__actions { display: flex; align-items: center; gap: 16px; }

/* ---------- hero ---------- */

.olt-hero { position: relative; background: var(--olt-placeholder); overflow: hidden; }
/* Solid brand teal, not the pale --olt-placeholder the generic .olt-hero sets.
   The placeholder exists for a hero that will carry a category PHOTOGRAPH; the
   scrim below then darkens the left so white text reads over the image. With no
   photographs loaded there was nothing but scrim over pale grey, and because
   the scrim fades to fully transparent at 80% the white heading had no ground
   at all on the right — a longer category name than "Dining Sets" would have
   run straight into invisibility.
   On a solid teal base white is 10.91:1 across the full width, image or not. */
.olt-hero--archive {
  min-height: 240px; display: flex; align-items: center;
  background: var(--olt-dark);
}
.olt-hero__inner {
  max-width: var(--olt-max); margin: 0 auto; width: 100%;
  padding: 56px var(--olt-gutter);
  position: relative; z-index: 2;
}
/* The same wash as the home hero, so the two read as one design rather than
   two teals. Chris asked for "that darker blended colour" and this is it: a
   left-to-right scrim over --olt-dark that bottoms out at .30 rather than
   fading to nothing, giving the band depth with the weight on the left where
   the heading sits. Identical stops to .olt-home-hero::after — if one is ever
   retuned, retune both.
   If category PHOTOGRAPHS are added later this still works: the scrim is
   exactly what makes white text readable over an image. */
.olt-hero--archive::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(1,48,51,.92) 0%, rgba(1,68,73,.72) 46%, rgba(1,68,73,.30) 78%);
}
.olt-hero--archive .olt-hero__title,
.olt-hero--archive .olt-hero__sub { color: #fff; }
.olt-hero__title { margin: 0 0 10px; }
.olt-hero__sub { margin: 0; font-size: 17px; max-width: 34em; opacity: .92; }

/* ---------- propositions ---------- */

.olt-props { list-style: none; margin: 0; padding: 0; }
.olt-props li { display: flex; gap: 13px; align-items: flex-start; }
.olt-props svg { color: var(--olt-brand-deep); flex-shrink: 0; margin-top: 3px; }
.olt-props__title { font-family: var(--olt-display); font-size: 15px; font-weight: 400; display: block; }
.olt-props__note { font-size: 13px; color: var(--olt-ink-3); display: block; }
.olt-props--stack { display: flex; flex-direction: column; gap: 15px; margin: 22px 0; }
.olt-props--row {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  background: var(--olt-stone); border-block: 1px solid var(--olt-rule-soft);
}
.olt-props--row li {
  justify-content: center; align-items: center; padding: 22px 16px;
  border-right: 1px solid var(--olt-rule);
}
.olt-props--row li:last-child { border-right: 0; }

/* ---------- prices ---------- */

.olt-price { display: flex; flex-direction: column; gap: 3px; }
.olt-price__row { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.olt-price__label {
  font-family: var(--olt-mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--olt-ink-3);
}
.olt-price__value {
  font-family: var(--olt-mono); font-variant-numeric: tabular-nums;
  font-size: 15px; font-weight: 500; color: var(--olt-ink);
}
.olt-price__vat { font-size: 10px; color: var(--olt-ink-3); margin-left: 5px; }
.olt-price__gate {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 13px; color: var(--olt-ink-3); font-style: italic;
}
.olt-price__gate svg { color: var(--olt-ink-4); }
.olt-price__row--rrp .olt-price__value { font-weight: 400; color: var(--olt-ink-2); }
.olt-price__row--margin .olt-price__value { color: var(--olt-good); }
.single-product .olt-price__value { font-size: 22px; font-family: var(--olt-display); font-weight: 400; }

/* ---------- stock ---------- */

.olt-stock, .stock {
  font-family: var(--olt-mono); font-size: 11px; letter-spacing: .05em;
  padding: 3px 8px; display: inline-block;
}
.olt-stock--in { background: var(--olt-good-wash); color: var(--olt-good); }
.olt-stock--seasonal { background: var(--olt-warn-wash); color: var(--olt-warn); }
.olt-stock--gone { background: var(--olt-signal-wash); color: var(--olt-signal); }

/* ---------- shop layout ---------- */

.olt-shop { display: grid; grid-template-columns: 236px minmax(0, 1fr); gap: 28px; align-items: start; }
.olt-filters {
  background: var(--olt-surface); border: 1px solid var(--olt-rule);
  padding: 20px 22px; position: sticky; top: 100px;
}
.olt-filters__head {
  font-family: var(--olt-display); font-size: 15px; font-weight: 500;
  padding-bottom: 12px; border-bottom: 1px solid var(--olt-rule-soft); margin-bottom: 16px;
}
.olt-filters__group { margin-bottom: 20px; }
.olt-filters__label {
  font-family: var(--olt-mono); font-size: 10px; letter-spacing: .11em;
  text-transform: uppercase; color: var(--olt-ink-3); margin-bottom: 9px;
}
.olt-filters ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.olt-filters a {
  display: flex; align-items: center; gap: 9px;
  font-size: 14px; color: var(--olt-ink-2);
}
.olt-check {
  width: 14px; height: 14px; border: 1px solid var(--olt-rule);
  background: var(--olt-surface); flex-shrink: 0;
}
.olt-filters a:hover .olt-check { border-color: var(--olt-brand-deep); }
.olt-filters__clear {
  display: block; text-align: center; font-family: var(--olt-display);
  font-size: 13px; font-weight: 500; padding: 10px;
  border: 1px solid var(--olt-rule);
}
.olt-filters__toggle { display: none; }

/* product grid */
ul.products {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px;
}
/* WooCommerce lays its product loop out with floats and percentage widths, and
   both of its stylesheets outgun a plain `ul.products li.product` (0,2,2):

     woocommerce-layout.css       .woocommerce ul.products li.product        (0,3,2)
         float: left; width: 22.05%; margin: 0 3.8% 2.992em 0
     woocommerce-smallscreen.css  .woocommerce ul.products[class*="columns-"] li.product
         width: 48%; float: left; clear: both                               (0,4,2)

   Our loop is a CSS grid, so float and clear are already inert on these items.
   `width` is not. 22.05% of a 350px grid cell is 77px — which is exactly what
   the category pages were rendering: 77px-wide tiles with the titles breaking
   one word per line, and thumbnails shrunk to match.

   Beating (0,4,2) takes five classes, which is why this selector looks the way
   it does. The RIGHT fix is to stop enqueuing WooCommerce's float grid at all,
   since this theme lays out its own — but those two files also carry cart,
   checkout and account-page layout, so that is a job for after launch rather
   than the week of it. Noted in the project doc.

   SCOPING, corrected 16 Oct: these were first written against
   `.olt-shop__grid`, the shop/category wrapper. But WooCommerce renders
   `ul.products` in several places that wrapper never touches — related
   products, upsells, cross-sells, the cart page and any `[products]`
   shortcode — so Related Products stayed broken after the category pages were
   fixed. The wrapper dependency is gone; the doubled `.product` buys the
   specificity instead, which is ugly but works anywhere the loop appears. */
.woocommerce ul.products[class*="columns-"] li.product.product,
.woocommerce ul.products li.product.product {
  width: auto; margin: 0; float: none; clear: none;
}

/* Second symptom of the same disease, found 16 Oct: every category page was
   missing its first tile.
   WooCommerce clears its floats with a table clearfix on the list itself —
     .woocommerce ul.products::before, ::after { content:" "; display:table }
   shipped from BOTH woocommerce-layout.css and woocommerce.css at (0,2,2).
   In a float layout those pseudo-elements are invisible. In a GRID container
   they are grid items, so ::before silently ate cell 1 and pushed the first
   product into column 2, with ::after taking a cell at the end.
   Measured: products began at x=785 (column 2) and wrapped at 417; with the
   pseudo-elements removed they begin at 417 as intended.
   content:none removes the box entirely rather than hiding it. */
.woocommerce ul.products.products::before,
.woocommerce ul.products.products::after {
  content: none;
}
ul.products li.product { background: var(--olt-surface); border: 1px solid var(--olt-rule); }
ul.products li.product > a:first-of-type { display: block; }
ul.products li.product img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
ul.products li.product .woocommerce-loop-product__title {
  font-family: var(--olt-display); font-size: 15px; font-weight: 400;
  line-height: 1.35; margin: 0; padding: 16px 18px 0;
}
.olt-card__meta { padding: 8px 18px 18px; display: flex; flex-direction: column; gap: 9px; }
.olt-card__code { font-size: 11px; color: var(--olt-brand-text); letter-spacing: .05em; }
.olt-card__logistics { font-size: 11px; color: var(--olt-ink-3); }
.olt-card__meta .olt-btn, .olt-card__meta .button { width: 100%; justify-content: center; }

/* ---------- product page ---------- */

.olt-spec-table { width: 100%; border-collapse: collapse; }
.olt-spec-table th {
  text-align: left; font-weight: 400; font-size: 14px; color: var(--olt-ink-2);
  padding: 11px 0; border-bottom: 1px solid var(--olt-rule-soft); width: 45%;
}
.olt-spec-table td {
  padding: 11px 0; border-bottom: 1px solid var(--olt-rule-soft);
  font-size: 13px; text-align: right;
}

.olt-assetpack {
  background: var(--olt-surface); border: 1px solid var(--olt-rule);
  padding: 36px 40px; margin: 44px 0;
  display: grid; grid-template-columns: 340px minmax(0, 1fr); gap: 44px; align-items: start;
}
.olt-assetpack__head h2 { margin: 0 0 12px; font-size: 27px; }
.olt-assetpack__head p { margin: 0 0 20px; color: var(--olt-ink-2); font-size: 15px; }
.olt-assetpack__list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 36px;
}
.olt-assetpack__list li {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 12px 0; border-bottom: 1px solid var(--olt-rule-soft);
}
.olt-assetpack__list svg { color: var(--olt-brand-deep); flex-shrink: 0; margin-top: 4px; }
.olt-assetpack__title { font-family: var(--olt-display); font-size: 15px; display: block; }
.olt-assetpack__note { font-size: 13px; color: var(--olt-ink-3); display: block; }
.olt-assetpack .olt-btn { grid-column: 1; }

/* ---------- the condition ---------- */

.olt-condition {
  background: var(--olt-surface); border: 1px solid var(--olt-rule);
  border-left: 3px solid var(--olt-signal);
  padding: 24px 28px; margin: 36px 0 0;
}
.olt-condition__label {
  font-family: var(--olt-display); font-size: 11px; font-weight: 500;
  letter-spacing: .19em; text-transform: uppercase;
  color: var(--olt-signal); margin-bottom: 9px;
}
.olt-condition p { margin: 0; font-size: 15px; color: var(--olt-ink-2); max-width: 70em; }

/* ---------- breadcrumb ---------- */

.olt-breadcrumb {
  font-family: var(--olt-mono); font-size: 11px; color: var(--olt-ink-3);
  padding-block: 18px;
}
.olt-crumb-sep { padding-inline: 7px; color: var(--olt-ink-4); }

/* ---------- footer ---------- */

.olt-footer { background: var(--olt-surface); border-top: 1px solid var(--olt-rule-soft); margin-top: 72px; }
/* The 72px above is right when the page ends in light content — the footer
   needs air. It is wrong when the page ends with the dark CTA band, because
   then two dark blocks are separated by a 72px strip of white, which reads as
   a mistake rather than as spacing. Closing it lets the CTA and the footer
   form one continuous dark base, with the tone step between --olt-dark-deep
   and --olt-dark doing the separating instead of a gap.
   :has() is the honest way to say "a footer that directly follows the CTA".
   Where it is unsupported the rule is ignored and the 72px gap returns, which
   is cosmetic, not broken. */
.olt-main:has(> .olt-cta:last-child) + .olt-footer { margin-top: 0; }
.olt-footer__top {
  max-width: var(--olt-max); margin: 0 auto; padding: 34px var(--olt-gutter);
  display: flex; align-items: center; justify-content: space-between; gap: 36px; flex-wrap: wrap;
}
.olt-footer__nav ul { display: flex; gap: 26px; list-style: none; margin: 0; padding: 0; }
.olt-footer__nav a { font-family: var(--olt-display); font-size: 14px; color: var(--olt-ink-2); }
.olt-footer__legal {
  max-width: var(--olt-max); margin: 0 auto;
  padding: 18px var(--olt-gutter) 30px;
  border-top: 1px solid var(--olt-rule-soft);
  display: flex; justify-content: space-between; gap: 24px; flex-wrap: wrap;
}
.olt-footer__legal p { margin: 0; font-size: 13px; color: var(--olt-ink-4); }

/* ---------- mobile bottom bar ---------- */

.olt-bottombar { display: none; }

/* ---------- responsive ---------- */

@media (max-width: 1100px) {
  .olt-nav ul { gap: 18px; }
  ul.products { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .olt-assetpack { grid-template-columns: minmax(0, 1fr); gap: 26px; }
}

@media (max-width: 860px) {
  .olt-header__inner { min-height: 0; padding-block: 14px; gap: 14px; }

  /* The desktop bar and the account buttons collapse into the panel. A nav
     that scrolls sideways hides items off-screen with no sign they exist. */
  .olt-nav,
  /* The actions collapse into the burger on small screens — EXCEPT the basket.
     A partner mid-order should never have to open a menu to find out what is
     in their basket or how to check out, and on a phone that is exactly the
     moment they give up. For a guest there is no basket, so this collapses to
     nothing and behaves as it did before. */
  .olt-header__actions { display: flex; gap: 10px; }
  .olt-header__actions > :not(.olt-cart) { display: none; }
  .olt-cart__text { display: none; }
  .olt-burger { display: flex; margin-left: auto; }

  .olt-mobile { display: block; }
  .olt-mobile[hidden] { display: none; }
  .olt-mobile .olt-menu { flex-direction: column; align-items: stretch; gap: 0; padding: 6px 0 14px; }
  .olt-mobile .olt-menu__item { border-bottom: 1px solid var(--olt-rule-soft); }
  .olt-mobile .olt-menu__item > a,
  .olt-mobile .olt-menu__trigger {
    width: 100%; justify-content: space-between; padding: 15px var(--olt-gutter);
    border-radius: 0; font-size: 16px;
  }
  /* In the panel the dropdown is just a nested list — no overlay on a phone. */
  .olt-mobile .olt-panel {
    position: static; box-shadow: none; border-top: 0;
    background: var(--olt-stone);
  }
  .olt-mobile .olt-panel__inner {
    grid-template-columns: minmax(0, 1fr); gap: 20px; padding: 18px var(--olt-gutter) 22px;
  }
  .olt-mobile .olt-panel__col--note { display: none; }

  .olt-utility__inner { flex-direction: column; align-items: flex-start; gap: 4px; padding-block: 8px; }
  .olt-utility__claim { font-size: 12px; }
  .olt-utility__contact { gap: 16px; }
  .olt-shop { grid-template-columns: minmax(0, 1fr); }
  .olt-filters { position: static; }
  .olt-filters__toggle {
    display: flex; width: 100%; justify-content: center;
    font-family: var(--olt-display); font-size: 14px; font-weight: 500;
    padding: 13px; border: 1px solid var(--olt-ink); background: transparent;
  }
  .olt-filters:not(.is-open) .olt-filters__group,
  .olt-filters:not(.is-open) .olt-filters__clear,
  .olt-filters:not(.is-open) .olt-filters__head { display: none; }
  .olt-props--row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .olt-props--row li:nth-child(2) { border-right: 0; }
  .olt-assetpack__list { grid-template-columns: minmax(0, 1fr); }
  .olt-footer__top { flex-direction: column; align-items: flex-start; }

  /* bottom bar: Home | Products | Search | Account | Basket */
  .olt-bottombar {
    display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
    background: var(--olt-surface); border-top: 1px solid var(--olt-rule);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .olt-bottombar ul {
    display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
    list-style: none; margin: 0; padding: 0;
  }
  .olt-bottombar a {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; min-height: 56px; font-family: var(--olt-display); font-size: 11px;
    color: var(--olt-ink-2);
  }
  body { padding-bottom: 56px; }
}

@media (max-width: 560px) {
  ul.products { grid-template-columns: minmax(0, 1fr); }
  .olt-spec-table th, .olt-spec-table td { font-size: 13px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* =========================================================================
   Homepage
   ========================================================================= */

.olt-eyebrow {
  font-family: var(--olt-display); font-size: 11px; font-weight: 500;
  letter-spacing: .19em; text-transform: uppercase; color: var(--olt-ink-3);
  margin: 0 0 11px;
}

.olt-home-hero {
  position: relative; min-height: 430px; display: flex; align-items: center;
  background-size: cover; background-position: center;
}
/* The deep, blended wash that gives the hero its depth. Left-to-right, and it
   never reaches zero — it bottoms out at .30, so the whole band is darkened
   with the weight on the left where the headline sits.
   This WAS rgba(31,42,34) — the old Outdoor Living olive — and it was still
   rendering on the live home page. A teal replacement had been written, but it
   targeted .olt-home-hero__media and .olt-home-hero__scrim, child elements
   that do not exist in the markup, so it styled nothing at all while looking
   like the job was done. The values below are those intended ones, moved onto
   the pseudo-element that actually renders. */
.olt-home-hero::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(1,48,51,.92) 0%, rgba(1,68,73,.72) 46%, rgba(1,68,73,.30) 78%);
}
.olt-home-hero__inner {
  position: relative; z-index: 2;
  max-width: var(--olt-max); margin: 0 auto; width: 100%;
  padding: 72px var(--olt-gutter);
}
.olt-home-hero__title {
  color: #fff; max-width: 17em; margin: 0 0 18px;
  font-size: clamp(32px, 4.6vw, 54px); line-height: 1.06;
}
.olt-home-hero__sub { color: #dde5d1; font-size: 18px; max-width: 30em; margin: 0 0 14px; }
.olt-home-hero__strap {
  font-family: var(--olt-display); font-size: 14px; font-weight: 500;
  letter-spacing: .1em; color: var(--olt-brand-on-ink); margin: 0 0 28px;
}
.olt-home-hero__actions { display: flex; gap: 12px; flex-wrap: wrap; }
.olt-btn--on-dark { border-color: #fff; color: #fff; }
.olt-btn--on-dark:hover { background: #fff; color: var(--olt-ink); }
.olt-btn--on-dark-solid { background: var(--olt-paper); color: var(--olt-ink); }
.olt-btn--on-dark-solid:hover { background: #fff; color: var(--olt-ink); }

.olt-section { padding-block: 60px 0; }
.olt-section__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; margin-bottom: 26px; flex-wrap: wrap;
}
.olt-section__head h2 { margin: 0 0 6px; }
.olt-section__sub { margin: 0; color: var(--olt-ink-3); font-size: 16px; }
.olt-more {
  font-family: var(--olt-display); font-size: 14px; font-weight: 500;
  display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
}

.olt-cats { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 14px; }
.olt-cats a { display: block; background: var(--olt-surface); border: 1px solid var(--olt-rule); color: var(--olt-ink); }
.olt-cats a:hover { border-color: var(--olt-brand-deep); }
.olt-cats__img, .olt-cats__img img, .olt-ph { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.olt-ph { background: var(--olt-placeholder); }
.olt-cats__row { display: flex; align-items: center; justify-content: space-between; padding: 15px 17px; }
.olt-cats__name { font-family: var(--olt-display); font-size: 15px; }
.olt-cats__row svg { color: var(--olt-brand-deep); }

.olt-band { margin-top: 62px; }
.olt-band--stone { background: var(--olt-stone-2); padding-block: 54px; }
.olt-band--paper { background: var(--olt-surface); border-block: 1px solid var(--olt-rule-soft); padding-block: 54px; }

.olt-why { display: grid; grid-template-columns: 400px minmax(0, 1fr); gap: 56px; align-items: start; }
.olt-why h2 { margin: 0 0 14px; }
.olt-why p { color: var(--olt-ink-2); margin-bottom: 22px; }
.olt-steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 22px; }
.olt-steps li { display: flex; flex-direction: column; gap: 11px; }
.olt-steps__num {
  font-family: var(--olt-display); font-size: 14px; font-weight: 400;
  width: 40px; height: 40px; border: 1px solid var(--olt-brand-deep);
  border-radius: 50%; display: flex; align-items: center; justify-content: center;
  color: var(--olt-brand-text);
}
.olt-steps__title { font-family: var(--olt-display); font-size: 16px; display: block; margin-bottom: 5px; }
.olt-steps__body { font-size: 14px; color: var(--olt-ink-2); line-height: 1.6; display: block; }

.olt-resources { display: grid; grid-template-columns: 400px minmax(0, 1fr); gap: 56px; align-items: start; }
.olt-resources h2 { margin: 0 0 14px; }
.olt-resources p { color: var(--olt-ink-2); margin-bottom: 22px; }
.olt-resources__list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 40px; }
.olt-resources__list li { display: flex; gap: 12px; align-items: flex-start; padding: 12px 0; border-bottom: 1px solid var(--olt-rule-soft); }
.olt-resources__list svg { color: var(--olt-brand-deep); flex-shrink: 0; margin-top: 4px; }
.olt-resources__title { font-family: var(--olt-display); font-size: 15px; display: block; }
.olt-resources__note { font-size: 13px; color: var(--olt-ink-3); display: block; }

.olt-creds { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px; }
.olt-creds li { border-top: 2px solid var(--olt-ink); padding-top: 20px; }
.olt-creds__stat { font-family: var(--olt-display); font-size: 40px; font-weight: 300; line-height: 1; display: block; letter-spacing: -0.02em; }
.olt-creds__label { font-family: var(--olt-display); font-size: 15px; font-weight: 500; display: block; margin: 10px 0 7px; }
.olt-creds__note { font-size: 14px; color: var(--olt-ink-2); line-height: 1.6; display: block; }

.olt-cta { background: var(--olt-ink); color: #e4ebda; margin-top: 62px; }
.olt-cta__inner { padding-block: 52px; display: flex; align-items: center; justify-content: space-between; gap: 44px; flex-wrap: wrap; }
.olt-cta h2 { color: #fff; margin: 0 0 10px; }
.olt-cta p { margin: 0; color: #b3c0a8; max-width: 44em; }

/* =========================================================================
   Trade dashboard
   ========================================================================= */

.olt-dash__greeting { color: var(--olt-ink-3); margin-bottom: 22px; }
.olt-dash__stats { list-style: none; margin: 0 0 24px; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.olt-dash__stats li { background: var(--olt-surface); border: 1px solid var(--olt-rule); padding: 22px 24px; }
.olt-dash__label { font-family: var(--olt-mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--olt-ink-3); display: block; margin-bottom: 9px; }
.olt-dash__figure { font-family: var(--olt-display); font-size: 31px; font-weight: 300; line-height: 1; display: block; }
.olt-dash__figure .woocommerce-Price-amount { font-family: var(--olt-display); }
.olt-dash__note { font-size: 12px; color: var(--olt-ink-3); display: block; margin-top: 7px; }
.olt-dash__panel { background: var(--olt-surface); border: 1px solid var(--olt-rule); padding: 24px 26px; margin-bottom: 16px; }
.olt-dash__panel h3 { margin: 0; font-size: 17px; font-weight: 500; }
.olt-dash__panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; margin-bottom: 14px; }
.olt-dash__table { width: 100%; border-collapse: collapse; }
.olt-dash__table th {
  font-family: var(--olt-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--olt-ink-3); text-align: left; padding: 0 12px 10px 0; border-bottom: 1px solid var(--olt-rule);
}
.olt-dash__table td { padding: 13px 12px 13px 0; border-bottom: 1px solid var(--olt-rule-soft); font-size: 14px; vertical-align: top; }
.olt-dash__sub { display: block; font-size: 12px; color: var(--olt-ink-3); }
.olt-dash__muted { color: var(--olt-ink-4); }
.olt-dash__empty { color: var(--olt-ink-3); }
.olt-dash__links { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.olt-dash__links a { display: flex; align-items: center; justify-content: space-between; padding: 12px 0; border-bottom: 1px solid var(--olt-rule-soft); font-size: 14px; }
.olt-dash--pending { background: var(--olt-warn-wash); border-left: 3px solid var(--olt-warn); padding: 26px 30px; }
.olt-dash--pending h3 { margin: 0 0 10px; }

.olt-pill { font-family: var(--olt-mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase; padding: 3px 8px; white-space: nowrap; background: var(--olt-stone); color: var(--olt-ink-2); }
.olt-pill--completed { background: var(--olt-good-wash); color: var(--olt-good); }
.olt-pill--processing { background: var(--olt-warn-wash); color: var(--olt-warn); }
.olt-pill--on-hold, .olt-pill--cancelled, .olt-pill--failed { background: var(--olt-signal-wash); color: var(--olt-signal); }

.olt-feed { display: flex; align-items: center; gap: 14px; padding: 13px 0; border-bottom: 1px solid var(--olt-rule-soft); flex-wrap: wrap; }
.olt-feed__label { font-family: var(--olt-mono); font-size: 10px; letter-spacing: .11em; text-transform: uppercase; color: var(--olt-ink-3); min-width: 180px; }
.olt-feed__url { font-family: var(--olt-mono); font-size: 12px; background: var(--olt-stone); padding: 8px 11px; color: var(--olt-ink-2); word-break: break-all; }
.olt-notice { background: var(--olt-warn-wash); border-left: 3px solid var(--olt-warn); padding: 14px 18px; font-size: 14px; }

@media (max-width: 1100px) {
  .olt-cats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .olt-why, .olt-resources { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  .olt-resources__list { grid-template-columns: minmax(0, 1fr); }
  .olt-creds { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .olt-dash__stats { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 660px) {
  .olt-cats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .olt-dash__table { display: block; overflow-x: auto; }
  .olt-cta__inner { flex-direction: column; align-items: flex-start; }
}

/* ===========================================================================
   LIVING WHOLESALE — the teal-led surfaces.
   ===========================================================================
   The logo is drawn for a dark ground: its green is 2.02:1 on white and 5.41:1
   on the teal. So the chrome — utility strip, header, hero, CTA band, footer —
   is teal, and the content between them stays white so a trade buyer can read
   price tables all day.

   This block is appended deliberately. The rules above it are the light-ground
   layout and still apply everywhere else; these override only the chrome.
   Nothing here re-colours the catalogue.
   ======================================================================== */

/* ------------------------------------------------------------- utility strip */
.olt-utility { background: var(--olt-dark-deep); color: var(--olt-on-dark-2); }
.olt-utility__claim { color: var(--olt-on-dark-acc); }
.olt-utility__contact a { color: var(--olt-on-dark-2); }
.olt-utility__contact a:hover { color: var(--olt-on-dark); }

/* -------------------------------------------------------------------- header */
.olt-header { background: var(--olt-dark); border-bottom-color: rgba(255,255,255,.10); }
.olt-header.is-scrolled {
  background: var(--olt-dark-deep);
  box-shadow: 0 1px 16px -6px rgba(0,0,0,.6);
}

.olt-brand { color: var(--olt-on-dark); }
.olt-brand__name { color: var(--olt-on-dark); }
/* Two-tone, as the logo is: "living" white, "wholesale" green. */
.olt-brand__tld  { color: var(--olt-on-dark-acc); }
.olt-brand__strap { color: var(--olt-on-dark-3); }
.olt-brand__mark { color: var(--olt-on-dark-acc); }

.olt-menu__item > a,
.olt-menu__trigger { color: var(--olt-on-dark-2); }
.olt-menu__item > a:hover,
.olt-menu__trigger:hover {
  color: var(--olt-on-dark);
  background: rgba(255,255,255,.08);
}
.olt-menu__item.is-current > a,
.olt-menu .current-menu-item > a,
.olt-menu .current-page-ancestor > a {
  color: var(--olt-on-dark);
  box-shadow: inset 0 -1.5px 0 var(--olt-on-dark-acc);
}
.olt-menu__item--has-panel.is-open .olt-menu__trigger {
  color: var(--olt-on-dark);
  background: rgba(255,255,255,.10);
}

/* The products panel stays light: it is a long list of category names and
   white is simply easier to scan than reversed text. */
.olt-panel { border-top-color: rgba(255,255,255,.12); }

/* SCOPED, 16 Oct. This was a bare `.olt-link`, written for the "Sign in" link
   that sits on the teal header chrome. But .olt-link is used in exactly two
   places, and the other one is the "View the full range" link inside the
   products panel — which sits on --olt-brand-wash, a LIGHT ground. A reversed
   colour landed on a light background and rendered at 1.33:1 against 4.5:1
   required: effectively invisible, which is what Chris spotted.
   tools/contrast.py did not catch it because it checks token pairings I listed
   by hand; it had no way to know this token ever met that background. The real
   pairing is now in its list. */
.olt-header__actions .olt-link { color: var(--olt-on-dark-2); }
.olt-header__actions .olt-link:hover { color: var(--olt-on-dark); }

.olt-burger { border-color: rgba(255,255,255,.28); }
.olt-burger__bars span { background: var(--olt-on-dark); }

.olt-mobile { background: var(--olt-dark-deep); border-top-color: rgba(255,255,255,.12); }
.olt-mobile .olt-menu__item { border-bottom-color: rgba(255,255,255,.10); }
.olt-mobile .olt-panel { background: var(--olt-dark); }
.olt-mobile .olt-panel__head { color: var(--olt-on-dark); border-bottom-color: rgba(255,255,255,.14); }
.olt-mobile .olt-panel__list a { color: var(--olt-on-dark-2); }
.olt-mobile .olt-panel__list a:hover { color: var(--olt-on-dark-acc); }

/* ------------------------------------------------------------------- buttons */
/* Green fill, TEAL label — 5.41:1. White on this green is 2.02:1 and is never
   used anywhere in this theme. */
.olt-btn {
  background: var(--olt-action);
  color: var(--olt-action-ink);
  font-weight: 500;
}
.olt-btn:hover {
  background: var(--olt-action-hover);
  color: var(--olt-action-ink);
}
.olt-btn--ghost { background: transparent; border: 1px solid var(--olt-rule); color: var(--olt-ink); }
.olt-btn--ghost:hover { background: var(--olt-ink); color: #fff; border-color: var(--olt-ink); }

/* A ghost button sitting on the teal chrome. */
.olt-header .olt-btn--ghost,
.olt-mobile .olt-btn--ghost,
.olt-home-hero .olt-btn--ghost,
.olt-footer .olt-btn--ghost {
  border-color: rgba(255,255,255,.45);
  color: var(--olt-on-dark);
}
.olt-header .olt-btn--ghost:hover,
.olt-mobile .olt-btn--ghost:hover,
.olt-home-hero .olt-btn--ghost:hover,
.olt-footer .olt-btn--ghost:hover {
  background: #fff; color: var(--olt-ink); border-color: #fff;
}

/* ---------------------------------------------------------------- home hero */
.olt-home-hero { background: var(--olt-dark); }
/* The .olt-home-hero__media and .olt-home-hero__scrim rules that used to sit
   here have been removed. They described a two-element structure the markup
   never had, so they matched nothing — and because they LOOKED like the hero
   had been rebranded, the old olive scrim above went unnoticed on the home
   page for weeks. Their values now live on .olt-home-hero::after, which is the
   element that actually renders. */
.olt-home-hero__sub { color: var(--olt-on-dark-2); }
.olt-home-hero__eyebrow,
.olt-hero__eyebrow { color: var(--olt-on-dark-acc); }

/* -------------------------------------------------------------- the CTA band */
.olt-cta { background: var(--olt-dark-deep); color: var(--olt-on-dark-2); }
.olt-cta h2 { color: var(--olt-on-dark); }
.olt-cta p  { color: var(--olt-on-dark-2); }

/* -------------------------------------------------------------------- footer */
.olt-footer { background: var(--olt-dark); border-top: 0; color: var(--olt-on-dark-2); }
/* :not(.olt-btn) matters. This was a bare `.olt-footer a`, meant for the text
   links — Delivery, Returns, Trade terms, Privacy, Contact — which sit on the
   dark teal. But the footer's "Apply for a Trade Account" button is also an
   <a>, with a GREEN fill, and `.olt-footer a` (0,1,1) outranks `.olt-btn`
   (0,1,0). So the button's label was painted --olt-on-dark-2, a reversed
   colour, on the brand green: 1.35:1. The identical button in the CTA band
   above carries .olt-btn--on-dark-solid and renders correctly at 5.41:1, which
   is why the two looked so different side by side.
   Same shape of bug as the products-panel link: a colour written for one
   context, applied with a selector broad enough to reach another. */
.olt-footer a:not(.olt-btn) { color: var(--olt-on-dark-2); }
.olt-footer a:not(.olt-btn):hover { color: var(--olt-on-dark-acc); }
.olt-footer__nav a { color: var(--olt-on-dark-2); }
.olt-footer__legal {
  border-top: 1px solid rgba(255,255,255,.12);
  color: var(--olt-on-dark-3);
}
.olt-footer .olt-brand__name { color: var(--olt-on-dark); }
.olt-footer .olt-brand__tld,
.olt-footer .olt-brand__strap { color: var(--olt-on-dark-3); }

/* ------------------------------------------------------------- skip link */
.olt-skip { background: var(--olt-action); color: var(--olt-action-ink); }

/* ------------------------------------------------------- the brand badge
   One livery, brands as labels: every product and card carries the brand it
   belongs to as a small badge rather than the site changing colour. */
.olt-badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--olt-display); font-size: 10.5px; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase;
  padding: 4px 9px; border-radius: 2px;
  background: var(--olt-stone-2); color: var(--olt-ink);
}
.olt-badge--on-dark { background: rgba(255,255,255,.12); color: var(--olt-on-dark); }
.olt-badge__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--olt-action); }

/* ------------------------------------------------------- trade application
   The /apply/ form. One column deliberately: this is a form a retailer fills
   in once, on whatever device is to hand, and a two-column layout only buys
   back vertical space nobody is short of. Labels sit above inputs so the eye
   travels in one line. */
.olt-apply { max-width: 34rem; margin: 0; }
.olt-apply__field { display: flex; flex-direction: column; gap: 5px; margin: 0 0 18px; }
.olt-apply__field label {
  font-family: var(--olt-display); font-size: 14px; font-weight: 500; color: var(--olt-ink);
}
.olt-apply__field abbr { color: var(--olt-signal); text-decoration: none; border: 0; }
.olt-apply input[type="text"],
.olt-apply input[type="email"],
.olt-apply input[type="tel"],
.olt-apply input[type="url"],
.olt-apply input[type="password"],
.olt-apply textarea {
  font: inherit; font-size: 15px; color: var(--olt-ink);
  background: var(--olt-paper); border: 1px solid var(--olt-rule);
  border-radius: 3px; padding: 11px 13px; width: 100%;
}
.olt-apply input:focus-visible,
.olt-apply textarea:focus-visible {
  outline: 2px solid var(--olt-brand); outline-offset: 1px; border-color: var(--olt-brand-text);
}
.olt-apply__hint { font-size: 12.5px; color: var(--olt-ink-2); line-height: 1.5; }
.olt-apply__error { font-size: 13px; color: var(--olt-signal); font-weight: 500; }
.olt-apply__error--form {
  background: var(--olt-stone); border-left: 3px solid var(--olt-signal);
  padding: 12px 14px; margin: 0 0 22px; font-size: 14px;
}

/* The checkbox rows read as one tappable line each, not a tiny box with text
   beside it — this form gets filled on phones. */
.olt-apply__field--checkbox label,
.olt-apply__options label {
  display: flex; align-items: flex-start; gap: 9px;
  font-weight: 400; font-family: var(--olt-body, inherit); font-size: 14.5px;
  color: var(--olt-ink); line-height: 1.45; cursor: pointer; padding: 3px 0;
}
.olt-apply__legend {
  font-family: var(--olt-display); font-size: 14px; font-weight: 500; color: var(--olt-ink);
}
.olt-apply__options { display: grid; gap: 2px; margin-top: 4px; }
.olt-apply input[type="checkbox"] { margin: 2px 0 0; width: 17px; height: 17px; accent-color: var(--olt-brand-text); flex: 0 0 auto; }

/* Honeypot. Off-screen rather than display:none — some bots skip hidden
   fields but not positioned ones, and a real browser never fills it. */
.olt-apply__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.olt-apply__submit { margin: 26px 0 0; }
.olt-apply__submit .olt-btn { width: 100%; justify-content: center; }
.olt-apply__note { font-size: 13px; color: var(--olt-ink-2); line-height: 1.6; margin: 14px 0 0; }
.olt-apply--done { background: var(--olt-brand-wash); padding: 20px 22px; border-radius: 3px; }
.olt-apply--done p { margin: 0; color: var(--olt-ink); }

@media (min-width: 640px) {
  .olt-apply__submit .olt-btn { width: auto; }
  .olt-apply__options { grid-template-columns: 1fr 1fr; }
}

/* ------------------------------------------------------------- the basket
   Header basket, approved partners only. Sits on the teal chrome, so the
   colours come from the on-dark tokens rather than the page ones. */
.olt-cart {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--olt-on-dark-2); text-decoration: none;
  padding: 7px 12px; border: 1px solid rgba(255,255,255,.18); border-radius: 3px;
  transition: color .15s, border-color .15s, background-color .15s;
}
.olt-cart:hover { color: var(--olt-on-dark); border-color: rgba(255,255,255,.4); background: rgba(255,255,255,.06); }
.olt-cart:focus-visible { outline: 2px solid var(--olt-brand); outline-offset: 2px; }
.olt-cart__icon { position: relative; display: inline-flex; }

/* The count rides on the icon. Green fill with the deep teal numeral — 5.41:1,
   the same pairing as the buttons. White on this green is 2.02:1 and is never
   used anywhere in this theme. */
.olt-cart__count {
  position: absolute; top: -7px; right: -9px;
  min-width: 17px; height: 17px; padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--olt-action); color: var(--olt-action-ink);
  font-family: var(--olt-display); font-size: 10.5px; font-weight: 600;
  border-radius: 9px; line-height: 1;
}
.olt-cart__text { display: flex; flex-direction: column; line-height: 1.25; }
.olt-cart__label { font-family: var(--olt-display); font-size: 12px; color: var(--olt-on-dark-3); }
.olt-cart__total { font-family: var(--olt-display); font-size: 14px; font-weight: 500; color: var(--olt-on-dark); }
.olt-cart__total .woocommerce-Price-amount { font-weight: 500; }
.olt-cart__vat { font-size: 9.5px; color: var(--olt-on-dark-3); margin-left: 4px; font-weight: 400; }

/* With nothing in it the basket is a quiet signpost, not a call to action. */
.olt-cart:not(.olt-cart--full) .olt-cart__total { display: none; }
.olt-cart:not(.olt-cart--full) .olt-cart__label { font-size: 13px; color: var(--olt-on-dark-2); }

/* ------------------------------------------------------------ feed URLs
   The URL is now a readonly input rather than a <code> block, because a
   partner's first action is always to copy it and a text node makes that a
   fiddly triple-click. Click selects the lot. */
.olt-feed { align-items: flex-start; }
.olt-feed__url {
  flex: 1 1 320px; min-width: 0;
  font-family: var(--olt-mono); font-size: 12px;
  background: var(--olt-stone); border: 1px solid var(--olt-rule);
  border-radius: 3px; padding: 9px 11px; color: var(--olt-ink);
}
.olt-feed__url:focus-visible { outline: 2px solid var(--olt-brand); outline-offset: 1px; }
.olt-feed__note { flex: 1 1 100%; font-size: 12.5px; color: var(--olt-ink-2); line-height: 1.5; }
.olt-feed__regen { margin: 18px 0 0; }
.olt-notice--good {
  background: var(--olt-brand-wash); border-left: 3px solid var(--olt-brand-text);
  padding: 12px 14px; color: var(--olt-ink);
}
