/* ==========================================================================
   main.css — page-level styles (hero, product listing, quote page, blog…)
   Load order in HTML:
     variables.css → fonts.css → reset.css → layout.css → components.css
     → main.css → responsive.css
   ========================================================================== */

/* ==========================================================================
   HOME — HERO / COVER
   --------------------------------------------------------------------------
   --p is the scroll progress (0 = closed, 1 = fully open), written to this
   element every frame by assets/js/hero.js. Everything below is a pure CSS
   function of --p, so the JS only ever sets one number.
   ========================================================================== */

/* .hero is only a scroll TRACK — it has no visible styling of its own. Its
   extra height (--hero-pin) is the scroll distance the box gets to open in,
   during which .hero__sticky stays put and the page appears to hold. Note
   there is deliberately no overflow:hidden here: an overflowing ancestor
   turns into the scroll container and silently kills position:sticky. */
.hero {
  --p: 0;
  --hero-pin: 85vh;
  position: relative;
  height: calc(100vh - var(--header-h) + var(--hero-pin));
  height: calc(100svh - var(--header-h) + var(--hero-pin));
}

.hero__sticky {
  position: sticky;
  top: var(--header-h);
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--header-h));
  height: calc(100svh - var(--header-h));
  overflow: hidden;
  padding-block: var(--sp-5);
  background:
    radial-gradient(1100px 620px at 78% 16%, rgba(136, 189, 164, 0.40), transparent 62%),
    radial-gradient(760px 520px at 6% 94%, rgba(177, 211, 185, 0.36), transparent 60%),
    linear-gradient(168deg, #ffffff 0%, var(--c-brand-tint) 100%);
}

.hero__particles {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.hero__inner {
  position: relative;   /* lift above the canvas */
  z-index: 1;
  flex: 1;
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  align-items: center;
  gap: var(--sp-7);
  min-height: 0;
}

/* --- Copy ------------------------------------------------------------- */
.hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  margin-bottom: var(--sp-5);
  border: 1px solid var(--c-brand);
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.7);
  color: var(--c-brand-deep);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.hero__title {
  font-size: clamp(2.25rem, 5.2vw, 3.75rem);
  font-weight: 700;
  margin-bottom: var(--sp-5);
}

/* <em> is the emphasis hook, not italics — brand colour + underline */
.hero__title em {
  position: relative;
  font-style: normal;
  color: var(--c-brand-deep);
  white-space: nowrap;
}
.hero__title em::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.08em;
  height: 0.14em;
  border-radius: var(--r-pill);
  background: var(--c-brand-soft);
  opacity: 0.55;
}

.hero__lead {
  max-width: 54ch;
  font-size: var(--fs-lg);
  color: var(--c-body);
  margin-bottom: var(--sp-6);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-bottom: var(--sp-7);
}

.hero__stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5) var(--sp-7);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--c-line);
}
.hero__stat strong {
  display: block;
  font-family: var(--font-head);
  font-size: var(--fs-2xl);
  font-weight: 700;
  letter-spacing: var(--ls-head);
  color: var(--c-ink);
}
.hero__stat span {
  font-size: var(--fs-xs);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--c-muted);
}

/* --- Scroll hint ------------------------------------------------------ */
.hero__hint {
  position: relative;
  z-index: 1;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  margin-top: var(--sp-6);
  font-size: var(--fs-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-muted);
  /* Fades out over the first half of the opening */
  opacity: calc(1 - var(--p) * 2);
}
.hero__hint .icon { animation: hintBob 1.8s var(--ease) infinite; }

@keyframes hintBob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(4px); }
}

/* ==========================================================================
   THE 3D BOX
   --------------------------------------------------------------------------
   Six walls + four lid flaps, all real CSS 3D transforms (no library, no
   canvas). Flap angles: 90deg = folded shut, ~-56deg = splayed open.
   Front/back and left/right open at slightly different rates so the two
   pairs never land coplanar — that's what stops z-fighting flicker.

   Everything is expressed as a ratio of --box-w/-d/-h, so resizing the box
   for a breakpoint is a three-value change and nothing else moves.
   ========================================================================== */

.scene {
  --box-w: 300px;   /* x */
  --box-d: 240px;   /* z */
  --box-h: 205px;   /* y */

  /* 90deg = lid shut, negative = splayed open past vertical. The side pair
     is hinged 2px higher (see --flap-*) so the two pairs stack like real
     board instead of landing coplanar and z-fighting at 90deg. */
  --fold-front: calc(90deg - 148deg * var(--p));
  --fold-side:  calc(90deg - 144deg * var(--p));

  /* Fake lighting — each plane gets a different value so the form reads */
  --skin-front:  linear-gradient(168deg, #C7A98A 0%, #AD7D52 100%);
  --skin-right:  linear-gradient(168deg, #B2926E 0%, #8F6740 100%);
  --skin-left:   linear-gradient(168deg, #9E7E5C 0%, #7A5636 100%);
  --skin-back:   linear-gradient(168deg, #8A6748 0%, #4A3928 100%);
  --skin-inner:  linear-gradient(180deg, #F7F1E8 0%, #E2D7C4 100%);

  position: relative;
  display: grid;
  place-items: center;
  min-height: 480px;
  perspective: 1400px;
  perspective-origin: 50% 44%;
}

.scene__float {
  transform-style: preserve-3d;
  animation: boxFloat 7s var(--ease) infinite;
}

@keyframes boxFloat {
  0%, 100% { transform: translateY(-8px); }
  50%      { transform: translateY(10px); }
}

.box {
  position: relative;
  width: var(--box-w);
  height: var(--box-h);
  transform-style: preserve-3d;
  /* Turns a little further toward the viewer as it opens */
  transform: rotateX(-16deg) rotateY(calc(-26deg + 15deg * var(--p)));
}

/* Every part is centred on the box origin, then pushed into place. */
.box > * {
  position: absolute;
  left: 50%;
  top: 50%;
}

/* --- Walls ------------------------------------------------------------ */
.box__face {
  transform-style: preserve-3d;
  backface-visibility: hidden;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
}

/* The reverse of every wall — the pale board you see inside the box */
.box__face::after,
.box__flap::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: rotateY(180deg);
  backface-visibility: hidden;
  background: var(--skin-inner);
  box-shadow: inset 0 0 0 1px rgba(63, 95, 86, 0.14);
}

.box__face--front {
  width: var(--box-w);
  height: var(--box-h);
  background: var(--skin-front);
  transform: translate(-50%, -50%) translateZ(calc(var(--box-d) / 2));
}

.box__face--back {
  width: var(--box-w);
  height: var(--box-h);
  background: var(--skin-back);
  transform: translate(-50%, -50%) translateZ(calc(var(--box-d) / -2)) rotateY(180deg);
}

.box__face--right {
  width: var(--box-d);
  height: var(--box-h);
  background: var(--skin-right);
  transform: translate(-50%, -50%) translateX(calc(var(--box-w) / 2)) rotateY(90deg);
}

.box__face--left {
  width: var(--box-d);
  height: var(--box-h);
  background: var(--skin-left);
  transform: translate(-50%, -50%) translateX(calc(var(--box-w) / -2)) rotateY(-90deg);
}

.box__face--bottom {
  width: var(--box-w);
  height: var(--box-d);
  background: var(--skin-back);
  transform: translate(-50%, -50%) translateY(calc(var(--box-h) / 2)) rotateX(90deg);
}

/* --- Brand mark on the front panel ------------------------------------ */
.box__brand {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 74px;
  height: 74px;
  transform: translate(-50%, -50%);
  color: #ffffff;
  opacity: 0.42;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --- Lid flaps -------------------------------------------------------- */
/* Hinge is the flap's own bottom edge, parked on the top edge of its wall. */
.box__flap {
  transform-origin: 50% 100%;
  transform-style: preserve-3d;
  backface-visibility: hidden;
  border-radius: 2px 2px 0 0;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
}

/* Outer pair — hinge on the W edges, reach across D. Length D/2 so they
   meet in the middle, less 2px so the seam reads as a seam. */
.box__flap--front {
  width: var(--box-w);
  height: calc(var(--box-d) / 2 - 2px);
  background: var(--skin-front);
  transform:
    translate(-50%, -50%)
    translateY(calc(var(--box-h) / -2 - var(--box-d) / 4 + 1px))
    translateZ(calc(var(--box-d) / 2))
    rotateX(var(--fold-front));
}

.box__flap--back {
  width: var(--box-w);
  height: calc(var(--box-d) / 2 - 2px);
  background: var(--skin-back);
  transform:
    translate(-50%, -50%)
    translateY(calc(var(--box-h) / -2 - var(--box-d) / 4 + 1px))
    translateZ(calc(var(--box-d) / -2))
    rotateY(180deg)
    rotateX(var(--fold-front));
}

/* Inner pair — hinge on the D edges, reach across W, and sit 2px proud so
   they lie *over* the outer pair when shut. */
.box__flap--right {
  width: var(--box-d);
  height: calc(var(--box-w) / 2 - 2px);
  background: var(--skin-right);
  transform:
    translate(-50%, -50%)
    translateY(calc(var(--box-h) / -2 - var(--box-w) / 4 - 1px))
    translateX(calc(var(--box-w) / 2))
    rotateY(90deg)
    rotateX(var(--fold-side));
}

.box__flap--left {
  width: var(--box-d);
  height: calc(var(--box-w) / 2 - 2px);
  background: var(--skin-left);
  transform:
    translate(-50%, -50%)
    translateY(calc(var(--box-h) / -2 - var(--box-w) / 4 - 1px))
    translateX(calc(var(--box-w) / -2))
    rotateY(-90deg)
    rotateX(var(--fold-side));
}

/* --- Contents --------------------------------------------------------- */
/* Panels parallel to the front wall, so they read as product inside the
   box. They sit below the rim at --p:0 and are occluded by the front wall,
   then rise clear of it as the flaps open. */
.box__item {
  border-radius: var(--r-sm);
  box-shadow: 0 10px 24px rgba(27, 43, 38, 0.22);
  opacity: calc(var(--p) * 2 - 0.55);
}

/* Sizes and travel are all ratios of the box, never fixed px — the box
   shrinks on small screens, and fixed distances would fling the contents
   proportionally much higher and collide with the copy above. */
.box__item--1 {
  width: calc(var(--box-w) * 0.393);
  height: calc(var(--box-h) * 0.410);
  background: linear-gradient(150deg, #ffffff 0%, #DCEAD2 100%);
  transform:
    translate(-50%, -50%)
    translate3d(
      calc(var(--box-w) * -0.207),
      calc(var(--box-h) * -0.068 - var(--box-h) * 0.380 * var(--p)),
      calc(var(--box-d) * 0.183))
    rotate(-7deg);
}

.box__item--2 {
  width: calc(var(--box-w) * 0.320);
  height: calc(var(--box-h) * 0.527);
  background: linear-gradient(150deg, #B1D3B9 0%, #88BDA4 100%);
  transform:
    translate(-50%, -50%)
    translate3d(
      calc(var(--box-w) * 0.060),
      calc(var(--box-h) * -0.146 - var(--box-h) * 0.546 * var(--p)),
      calc(var(--box-d) * 0.025))
    rotate(5deg);
}

.box__item--3 {
  width: calc(var(--box-w) * 0.347);
  height: calc(var(--box-h) * 0.361);
  background: linear-gradient(150deg, #F4F9EF 0%, #B1D3B9 100%);
  transform:
    translate(-50%, -50%)
    translate3d(
      calc(var(--box-w) * 0.247),
      calc(var(--box-h) * -0.029 - var(--box-h) * 0.302 * var(--p)),
      calc(var(--box-d) * -0.142))
    rotate(11deg);
}

/* --- Ground shadow ---------------------------------------------------- */
/* Spreads and softens as the box lifts, which sells the float. */
.scene__shadow {
  position: absolute;
  left: 50%;
  bottom: 8%;
  width: calc(var(--box-w) + var(--box-w) * 0.2 * var(--p));
  height: calc(var(--box-h) * 0.2);
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(ellipse at center, rgba(27, 43, 38, 0.30) 0%, rgba(27, 43, 38, 0) 70%);
  filter: blur(6px);
  opacity: calc(0.9 - var(--p) * 0.25);
}

/* --- Motion opt-out ---------------------------------------------------- */
/* hero.js pins --p to 1 and skips the particle loop; kill the idle float
   and the bobbing chevron here so nothing moves at all. */
@media (prefers-reduced-motion: reduce) {
  .scene__float { animation: none; }
  .hero__hint { display: none; }

  /* Drop the pin as well — holding the page hostage to an animation the
     user opted out of is exactly the thing they opted out of. */
  .hero { height: auto; }
  .hero__sticky {
    position: static;
    height: auto;
    padding-block: var(--sp-8);
  }
}

/* ==========================================================================
   HOME — SHOWCASE BAND
   --------------------------------------------------------------------------
   Inverted section: two promo cards plus a square portfolio tile. The
   reference for this used a black ground with a lime accent; translated to
   our palette that becomes --c-ink with the brand greens carrying the
   accent work. Every pair here is contrast-checked (see variables.css).
   ========================================================================== */

.showcase {
  background: var(--c-ink);
  color: var(--c-on-dark-soft);
}

.showcase__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 250px;
  gap: var(--sp-5);
  align-items: stretch;
}

/* --- Promo card ------------------------------------------------------- */
.promo-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 38%;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-6);
  border-radius: var(--r-lg);
  background: var(--c-ink-panel);
  transition: background var(--dur) var(--ease);
}
.promo-card:hover { background: #27403A; }

.promo-card__tag {
  display: inline-block;
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-pill);
  background: var(--c-brand-pale);
  color: var(--c-ink);              /* 9.08:1 */
  font-family: var(--font-head);
  font-size: var(--fs-sm);
  font-weight: 600;
}

.promo-card__text {
  max-width: 36ch;
  margin-block: var(--sp-4) var(--sp-5);
  font-size: var(--fs-sm);
  color: var(--c-on-dark-soft);     /* 8.72:1 on the panel */
}

/* No justify-self here: it shrink-wraps the grid item, and the img's
   width:100% then resolves against that collapsed width. Let it stretch. */
.promo-card__media {
  align-self: center;
  min-width: 0;
}
.promo-card__media img { display: block; width: 100%; height: auto; }

/* --- Outlined pill button (dark ground only) --------------------------- */
.btn-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5);
  border: 1px solid rgba(255, 255, 255, 0.38);
  border-radius: var(--r-pill);
  color: #ffffff;
  font-size: var(--fs-sm);
  font-weight: 600;
  white-space: nowrap;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.btn-pill .icon {
  color: var(--c-brand-pale);
  transition: color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.btn-pill:hover {
  background: #ffffff;
  border-color: #ffffff;
  color: var(--c-ink);
}
.btn-pill:hover .icon {
  color: var(--c-brand-deep);
  transform: translate(2px, -2px);
}

/* --- Portfolio tile ---------------------------------------------------- */
/* No aspect-ratio: the tile stretches to the row height set by the cards,
   which keeps all three the same height and lands it near-square anyway. */
.promo-tile {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 240px;
  padding: var(--sp-6);
  border-radius: var(--r-lg);
  background: var(--c-brand-soft);
  color: var(--c-ink);              /* 6.95:1 */
  transition: background var(--dur) var(--ease);
}
.promo-tile:hover { background: var(--c-brand-pale); }

.promo-tile__arrow {
  width: 76px;
  height: 76px;
  margin-left: auto;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform var(--dur) var(--ease);
}
.promo-tile:hover .promo-tile__arrow { transform: translate(4px, -4px); }

.promo-tile__label {
  font-family: var(--font-head);
  font-size: var(--fs-2xl);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: var(--ls-head);
}

/* ==========================================================================
   HOME — POPULAR PRODUCTS
   ========================================================================== */

.products__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-5);
}

.product-card {
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  overflow: hidden;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.product-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
  border-color: var(--c-brand-soft);
}
/* The whole card is the hit area, so the focus ring belongs on the card
   rather than the inline link box. */
.product-card:focus-within {
  border-color: var(--c-brand-deep);
  box-shadow: var(--shadow-md);
}
.product-card__link:focus-visible { outline: none; }

.product-card__link { display: block; height: 100%; }

/* The image is taken OUT OF FLOW deliberately. In normal flow a percentage
   height against a grid track whose size depends on content is cyclic, so the
   browser falls back to the image's intrinsic height — and a taller-than-4:3
   asset then overrides aspect-ratio and grows the frame, dropping that card's
   title out of line with its neighbours. Absolutely positioned, the image can
   never size its container, whatever ratio the artwork is. */
.product-card__media {
  /* Required: this is a <span>, and aspect-ratio does nothing on an inline
     box — without it the frame collapses to zero height. */
  display: block;
  position: relative;
  aspect-ratio: 4 / 3;
  background: linear-gradient(168deg, var(--c-brand-tint) 0%, #F6FAF2 100%);
}
.product-card__media img {
  position: absolute;
  top: var(--sp-5);
  left: var(--sp-5);
  /* Sized explicitly, NOT via the `inset` shorthand: for an absolutely
     positioned replaced element, width/height:auto resolve to the intrinsic
     size and the right/bottom insets are simply ignored, so the artwork
     spills out of the frame. These two calcs are the old padding. */
  width: calc(100% - 2 * var(--sp-5));
  height: calc(100% - 2 * var(--sp-5));
  object-fit: contain;
  transition: transform var(--dur) var(--ease);
}
.product-card:hover .product-card__media img { transform: scale(1.05); }

.product-card__body {
  display: block;
  padding: var(--sp-5);
}

.product-card__title {
  display: block;
  margin-bottom: var(--sp-2);
  font-family: var(--font-head);
  font-size: var(--fs-lg);
  font-weight: 600;
  letter-spacing: var(--ls-head);
  color: var(--c-ink);
}

.product-card__text {
  display: block;
  margin-bottom: var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--c-muted);
}

.product-card__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--c-brand-deep);
}
.product-card__cta .icon { transition: transform var(--dur) var(--ease); }
.product-card:hover .product-card__cta .icon { transform: translate(2px, -2px); }

.products__foot {
  display: flex;
  justify-content: center;
  margin-top: var(--sp-6);
}

/* ==========================================================================
   MARQUEE BAND
   --------------------------------------------------------------------------
   Rotated infinite ticker, pure CSS. The track holds two identical groups
   and translates exactly -50%, which lands group 2 precisely where group 1
   started — so the loop has no visible seam and needs no JS.
   ========================================================================== */

.marquee-band {
  /* Clips the rotated bar's corners. Without this the rotation pushes the
     ends past the viewport and the page gains a horizontal scrollbar. */
  overflow: hidden;
  padding-block: var(--sp-7);
  background: var(--c-surface);
}

.marquee {
  /* Oversized so the rotated ends still cover the full viewport width
     instead of leaving wedge-shaped gaps at the corners. */
  width: 112%;
  margin-left: -6%;
  padding-block: var(--sp-4);
  transform: rotate(-2.5deg);
  background: var(--c-brand-dark);
  color: var(--c-on-dark);          /* 5.71:1 */
  overflow: hidden;
}

.marquee__track {
  display: flex;
  width: max-content;
  animation: marquee 38s linear infinite;
}

.marquee:hover .marquee__track { animation-play-state: paused; }

@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.marquee__group {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  padding-right: var(--sp-5);
  flex: none;
}

.marquee__item {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-base);
  white-space: nowrap;
}
.marquee__item strong { color: #ffffff; font-weight: 600; }   /* 7.04:1 */

.marquee__icon {
  flex: none;
  width: 22px;
  height: 22px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--c-brand-pale);
}

@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
}

/* --- Per-product accents ------------------------------------------------
   Each construction owns a hue, and the artwork inside it was hue-rotated to
   match. Colour here is an identifier, not decoration: the same hue follows a
   product across its card, its media wash and its CTA. The card body stays
   white so only the frame carries colour and the type contrast never moves. */
.product-card--amber      .product-card__media { background: linear-gradient(168deg, var(--a-amber-tint) 0%, #FDFBF6 100%); }
.product-card--terracotta .product-card__media { background: linear-gradient(168deg, var(--a-terracotta-tint) 0%, #FDF8F6 100%); }
.product-card--plum       .product-card__media { background: linear-gradient(168deg, var(--a-plum-tint) 0%, #FBF7F9 100%); }
.product-card--indigo     .product-card__media { background: linear-gradient(168deg, var(--a-indigo-tint) 0%, #F6F8FB 100%); }
.product-card--teal       .product-card__media { background: linear-gradient(168deg, var(--a-teal-tint) 0%, #F4FAFB 100%); }

.product-card--amber:hover      { border-color: var(--a-amber); }
.product-card--terracotta:hover { border-color: var(--a-terracotta); }
.product-card--plum:hover       { border-color: var(--a-plum); }
.product-card--indigo:hover     { border-color: var(--a-indigo); }
.product-card--teal:hover       { border-color: var(--a-teal); }

/* -deep steps only — each clears 4.5:1 on the white card body */
.product-card--amber      .product-card__cta { color: var(--a-amber-deep); }
.product-card--terracotta .product-card__cta { color: var(--a-terracotta-deep); }
.product-card--plum       .product-card__cta { color: var(--a-plum-deep); }
.product-card--indigo     .product-card__cta { color: var(--a-indigo-deep); }
.product-card--teal       .product-card__cta { color: var(--a-teal-deep); }

/* ==========================================================================
   HOME — HOW IT WORKS
   --------------------------------------------------------------------------
   main.js writes --flow (0 → 1) on the track as the section scrolls past.
   Each step derives its own --on from --flow and its index, so the whole
   sequence is one number — no per-step JS, no timers.
   ========================================================================== */

.process { background: var(--c-surface-alt); }

.process__track {
  /* Defaults to 1 (everything lit) so the section is fully legible with no
     JS at all. initFlow() resets it to 0 before it starts animating. */
  --flow: 1;
  display: grid;
  /* gap:0 on purpose — equal flush columns put the icon centres at exactly
     10/30/50/70/90%, which is what lets the connectors line up. Breathing
     room comes from padding on the step instead. */
  grid-template-columns: repeat(5, 1fr);
  gap: 0;
  margin-top: var(--sp-7);
}

.process__step {
  --on:  clamp(0, (var(--flow) * 5 - var(--i)) * 1.6, 1);
  --on2: clamp(0, (var(--flow) * 5 - var(--i) - 1) * 1.6, 1);  /* the next step */
  position: relative;
  padding-inline: var(--sp-3);
  text-align: center;
  /* Motion only — deliberately NO opacity fade on the step. Dimming the
     copy sinks it below AA against this tinted ground (measured: --c-body
     at 0.85 opacity is 4.44:1, and it only gets worse from there). State
     is carried by the icon fill and the connector instead, which are
     non-text UI and only need 3:1. */
  transform: translateY(calc(10px - 10px * var(--on)));
}

/* Connector: rail underneath, brand-coloured fill on top driven by --on2 */
.process__step:not(:last-child)::before,
.process__step:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 33px;
  left: calc(50% + 38px);
  height: 3px;
  border-radius: var(--r-pill);
}
.process__step:not(:last-child)::before {
  width: calc(100% - 76px);
  background: var(--c-line);
}
.process__step:not(:last-child)::after {
  width: calc((100% - 76px) * var(--on2));
  background: var(--c-brand-deep);
}

.process__icon {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 68px;
  height: 68px;
  margin: 0 auto var(--sp-4);
  border-radius: var(--r-pill);
  border: 2px solid var(--c-line);
  box-shadow: 0 0 0 6px var(--c-surface-alt);   /* masks the rail behind it */
  /* Small pop as the flow arrives — this is where the state change reads */
  transform: scale(calc(0.9 + 0.1 * var(--on)));
  /* Unlit state is WHITE, not --c-brand-tint: the section background is
     already that colour, so a tinted circle would be invisible.
     Static fallback first; color-mix cross-fades white → deep on activation. */
  background: var(--c-surface);
  color: var(--c-brand-deep);
  background: color-mix(in srgb, var(--c-brand-deep) calc(var(--on) * 100%), var(--c-surface));
  border-color: color-mix(in srgb, var(--c-brand-deep) calc(var(--on) * 100%), var(--c-line));
  color: color-mix(in srgb, #ffffff calc(var(--on) * 100%), var(--c-brand-deep));
}
.process__icon .icon { width: 28px; height: 28px; }

.process__num {
  display: block;
  margin-bottom: var(--sp-1);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--c-brand-deep);
}

.process__title {
  font-size: var(--fs-lg);
  margin-bottom: var(--sp-2);
}

.process__text {
  font-size: var(--fs-sm);
  color: var(--c-muted);
}

/* --- Help bar --------------------------------------------------------- */
.help-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  margin-top: var(--sp-8);
  padding: var(--sp-5) var(--sp-6);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  box-shadow: var(--shadow-sm);
}

.help-bar__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 56px;
  height: 56px;
  border-radius: var(--r-pill);
  background: var(--c-brand-tint);
  color: var(--c-brand-deep);
}
.help-bar__icon .icon { width: 28px; height: 28px; }

.help-bar__text { flex: 1; min-width: 0; }
.help-bar__text strong {
  display: block;
  font-family: var(--font-head);
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--c-ink);
}
.help-bar__text span {
  display: block;
  margin-top: 2px;
  font-size: var(--fs-sm);
  color: var(--c-muted);
}

.help-bar__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  flex: none;
}

/* --- Motion opt-out ---------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  /* main.js pins --flow to 1; make sure nothing is left mid-transition */
  .process__step { transform: none; }
  .process__icon { transform: none; }
}

/* --- Step accents --------------------------------------------------------
   The chip carries only an icon (the "Step n" label is a separate element),
   so the bar here is 1.4.11's 3:1 for non-text contrast, not 4.5:1. Measured
   3.78–3.96 on their own tints — comfortably clear. Do NOT put text in these
   chips without re-checking. */
.process__step--amber      .process__icon { background: var(--a-amber-tint);      color: var(--a-amber-deep); }
.process__step--terracotta .process__icon { background: var(--a-terracotta-tint); color: var(--a-terracotta-deep); }
.process__step--plum       .process__icon { background: var(--a-plum-tint);       color: var(--a-plum-deep); }
.process__step--indigo     .process__icon { background: var(--a-indigo-tint);     color: var(--a-indigo-deep); }
.process__step--teal       .process__icon { background: var(--a-teal-tint);       color: var(--a-teal-deep); }

/* ==========================================================================
   HOME — BENTO FEATURE GRID
   --------------------------------------------------------------------------
   Three coloured cards: two on the top row, one full-width beneath. The
   reference used red / grey / lime; mapped onto our palette that becomes
   brand-dark / tint / brand-soft. Note the mint card carries INK text, not
   white — white on --c-brand-soft is only 2.4:1.
   ========================================================================== */

.bento__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
  gap: var(--sp-5);
}

.bento-card {
  position: relative;
  padding: var(--sp-7);
  border-radius: var(--r-lg);
  overflow: hidden;
}

/* --- Colour variants --------------------------------------------------- */
.bento-card--dark {
  background: var(--c-brand-dark);
  color: var(--c-on-dark);              /* 5.71:1 */
}
.bento-card--dark .bento-card__title,
.bento-card--dark .bento-card__list li { color: #ffffff; }
.bento-card--dark .bento-card__list .icon { color: var(--c-brand-pale); }

.bento-card--light {
  background: var(--c-brand-tint);
  color: var(--c-body);
}

.bento-card--mint {
  background: var(--c-brand-soft);
  color: var(--c-ink);                  /* 6.95:1 — white would be 2.4:1 */
}
.bento-card--mint .bento-card__list .icon { color: var(--c-brand-dark); }

/* --- Internal layouts --------------------------------------------------- */
.bento-card--split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.95fr);
  align-items: center;
  gap: var(--sp-4);
}

.bento-card--stack {
  /* Was `grid-template-rows: auto 1fr` — since this card is stretched to
     match the (now taller, longer-copy) split card's height, the 1fr row
     shoved the image to the very bottom and left a dead gap above it.
     Centering body+media as one flexed group keeps them close together
     regardless of how much taller the card gets. */
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--sp-5);
  height: 100%;
}

.bento-card--wide {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.15fr);
  align-items: center;
  gap: var(--sp-6);
}

/* --- Card content ------------------------------------------------------- */
.bento-card__eyebrow {
  margin-bottom: var(--sp-3);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* --c-brand-pale is only 4.32:1 on the dark card — fine for the check
     icons (3:1 bar) but this is 12px text, so it takes the lighter tone. */
  color: var(--c-on-dark);
}

.bento-card__title {
  font-size: var(--fs-2xl);
  font-weight: 600;
  margin-bottom: var(--sp-4);
}
.bento-card__title em {
  font-style: normal;
  color: var(--c-brand-deep);
}

.bento-card__text {
  font-size: var(--fs-sm);
  max-width: 42ch;
}

.bento-card__list {
  display: grid;
  gap: var(--sp-3);
  margin-bottom: var(--sp-6);
}
.bento-card__list li {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-size: var(--fs-sm);
  font-weight: 600;
}
.bento-card--wide .bento-card__list { margin-bottom: 0; }

/* --- Media -------------------------------------------------------------- */
.bento-card__media {
  position: relative;
  align-self: end;
  min-width: 0;
  /* Bleed into the card padding so the illustration anchors to the corner
     instead of floating in the middle. */
  margin-right: calc(var(--sp-7) * -1);
  margin-bottom: calc(var(--sp-7) * -1);
}
.bento-card__media img {
  display: block;
  width: 100%;
  height: auto;
  /* Capped so a tall SVG can't stretch the card. object-fit keeps the
     aspect ratio once max-height starts binding. Sized to the card's
     current (longer) copy so the illustration fills the column instead
     of leaving a gap above it. */
  max-height: 320px;
  object-fit: contain;
  object-position: bottom right;
}

.bento-card--stack .bento-card__media {
  margin-inline: calc(var(--sp-7) * -1);
}
.bento-card--stack .bento-card__media img {
  max-height: 340px;
  object-position: bottom center;
}

.bento-card--wide { padding-block: var(--sp-6); }
.bento-card--wide .bento-card__media img { max-height: 210px; }

/* --- Volume badge ------------------------------------------------------- */
.bento-badge {
  position: absolute;
  left: -6px;
  top: 50%;
  /* pull back by half its own height, or it hangs below the card and the
     card's overflow:hidden slices it */
  transform: translateY(-50%);
  z-index: 1;
  display: grid;
  place-content: center;
  gap: 2px;
  width: 112px;
  height: 112px;
  border-radius: 50%;
  background: var(--c-ink);
  color: #ffffff;                       /* 14.79:1 */
  text-align: center;
}
.bento-badge span {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.85;
}
.bento-badge strong {
  font-family: var(--font-head);
  font-size: var(--fs-2xl);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-head);
}

/* --- Light button (for use on dark cards) -------------------------------- */
.btn--light {
  background: #ffffff;
  color: var(--c-ink);
}
.btn--light:hover { background: var(--c-brand-tint); }

/* ==========================================================================
   HOME — FINISHING & MATERIALS (tabs)
   ========================================================================== */

.tabs__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-6);
}

.tabs__tab {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5);
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-pill);
  background: var(--c-surface);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--c-ink);
  white-space: nowrap;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
.tabs__tab:hover {
  border-color: var(--c-brand-deep);
  color: var(--c-brand-deep);
}
/* Each tab owns the hue of the swatches it reveals — amber for special
   finishes, teal for lamination, brand green for board. White on every -deep
   step clears 4.5:1 (4.52–5.34). */
#tab-special[aria-selected="true"]    { background: var(--a-amber-deep); border-color: var(--a-amber-deep); }
#tab-lamination[aria-selected="true"] { background: var(--a-teal-deep);  border-color: var(--a-teal-deep); }
#tab-special:hover    { border-color: var(--a-amber-deep); color: var(--a-amber-deep); }
#tab-lamination:hover { border-color: var(--a-teal-deep);  color: var(--a-teal-deep); }
#tab-special[aria-selected="true"]:hover,
#tab-lamination[aria-selected="true"]:hover { color: #ffffff; }

.tabs__tab[aria-selected="true"] {
  background: var(--c-brand-deep);
  border-color: var(--c-brand-deep);
  color: #ffffff;                 /* 5.34:1 */
}
.tabs__tab .icon { color: currentColor; }

/* The panel is focusable (it's the tab's content), so it needs a ring */
.tabs__panel:focus-visible {
  outline: 2px solid var(--c-brand-deep);
  outline-offset: 6px;
  border-radius: var(--r-md);
}
.tabs__panel:not([hidden]) { animation: tabIn var(--dur) var(--ease) both; }

@keyframes tabIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .tabs__panel:not([hidden]) { animation: none; }
}

.finish-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-5);
}

/* Image-led card: the swatch is the hero, so it runs edge to edge and the
   copy sits beneath it. */
.finish-card {
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  overflow: hidden;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.finish-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
  border-color: var(--c-brand-soft);
}

.finish-card__media {
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--c-brand-tint);
}
.finish-card__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Slower than --dur: a slow push on a large image reads as intentional,
     a fast one reads as a glitch. */
  transition: transform 0.5s var(--ease);
}
.finish-card:hover .finish-card__media img { transform: scale(1.06); }

@media (prefers-reduced-motion: reduce) {
  .finish-card,
  .finish-card__media img { transition: none; }
  .finish-card:hover { transform: none; }
  .finish-card:hover .finish-card__media img { transform: none; }
}

.finish-card__body { padding: var(--sp-5); }

.finish-card__title {
  font-size: var(--fs-lg);
  margin-bottom: var(--sp-2);
}
.finish-card__text {
  font-size: var(--fs-sm);
  color: var(--c-muted);
}

/* ==========================================================================
   HOME — TESTIMONIALS
   ========================================================================== */

.testimonials { background: var(--c-surface-alt); }

.testimonial-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-5);
}

.testimonial {
  position: relative;
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: var(--sp-6);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.testimonial:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }

/* Oversized quote glyph, kept decorative and out of the way of the text */
.testimonial__mark {
  position: absolute;
  top: var(--sp-5);
  right: var(--sp-5);
  width: 44px;
  height: 44px;
  stroke: none;
  fill: var(--c-brand-tint);
  pointer-events: none;
}

.stars { display: flex; gap: 3px; margin-bottom: var(--sp-4); }
/* .icon is stroke-only by default; stars need to be solid */
.stars .icon {
  width: 16px;
  height: 16px;
  fill: var(--c-brand);
  stroke: none;
}

.testimonial__quote { margin: 0 0 var(--sp-5); flex: 1; }
.testimonial__quote p {
  font-size: var(--fs-base);
  line-height: 1.6;
  color: var(--c-body);
}

.testimonial__author {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--c-line);
}

.testimonial__avatar {
  display: grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--c-brand-deep);
  color: #ffffff;
  font-family: var(--font-head);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.02em;
}

.testimonial__meta { min-width: 0; }
.testimonial__meta strong {
  display: block;
  font-family: var(--font-head);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--c-ink);
}
.testimonial__meta span {
  display: block;
  font-size: var(--fs-xs);
  color: var(--c-muted);
}

/* White initials on each -deep step: 4.51–4.54:1, all clear AA */
.testimonial__avatar--amber { background: var(--a-amber-deep); }
.testimonial__avatar--teal  { background: var(--a-teal-deep); }
.testimonial__avatar--plum  { background: var(--a-plum-deep); }

/* ==========================================================================
   HOME — CLIENT LOGOS
   ========================================================================== */

.client-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  /* 1px gap over a line-coloured ground draws the hairline rules between
     cells — no per-cell border maths, and no doubled edges. */
  background: var(--c-line);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.client-grid__item {
  display: grid;
  place-items: center;
  padding: var(--sp-6) var(--sp-4);
  background: var(--c-surface);
}

.client-logo {
  width: 100%;
  max-width: 176px;
  height: auto;
  /* Resting state is quiet so the wall reads as texture, not as eight
     competing marks; each comes forward on hover. 0.8 is the floor —
     at 0.7 the wordmarks blend to 2.95:1, and although logotypes are
     exempt from contrast rules these read as text. */
  color: var(--c-muted);
  opacity: 0.8;
  transition: color var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.client-grid__item:hover .client-logo {
  color: var(--c-brand-deep);
  opacity: 1;
}

.client-logo__word {
  font-family: var(--font-head);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.01em;
  fill: currentColor;
}

/* ==========================================================================
   HOME — COVERAGE MAP  [EXPERIMENTAL — safe to delete with its section]
   --------------------------------------------------------------------------
   Dark band so the map reads as a distinct object, and so it doesn't have to
   fight the alternating light sections either side of it.
   ========================================================================== */

.coverage {
  background: var(--c-ink);
  color: var(--c-on-dark-soft);
}
.coverage .section-head__title { color: #ffffff; }
.coverage .section-head__text { color: var(--c-on-dark-soft); }
.coverage .section-head__eyebrow { color: var(--c-brand-soft); }

.coverage__layout {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: var(--sp-7);
  align-items: center;
}

.coverage__map { display: grid; place-items: center; }
.uk-map { width: 100%; max-width: 360px; height: auto; }

/* --- Hex tiles --------------------------------------------------------- */
/* Fill encodes DELIVERY SPEED permanently — a sequential cool-to-warm ramp,
   fastest to slowest. Selection deliberately uses a different channel (a white
   ring), so picking a region never destroys the data reading the colour gives.
   Ink labels measure 4.92–6.94:1 on every band. */
.uk-map__region polygon {
  stroke: transparent;
  stroke-width: 3;
  transition: stroke var(--dur) var(--ease), filter var(--dur) var(--ease);
}
.uk-map__region--b1 polygon { fill: var(--a-teal); }        /* next working day */
.uk-map__region--b2 polygon { fill: var(--c-brand-soft); }  /* 1–2 days */
.uk-map__region--b3 polygon { fill: var(--a-amber); }       /* 2–3 days */
.uk-map__region--b4 polygon { fill: var(--a-terracotta); }  /* 3–5 days */

.uk-map__region text {
  fill: var(--c-ink);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  text-anchor: middle;
  pointer-events: none;
}
.uk-map__region.is-active polygon {
  stroke: #ffffff;
  filter: brightness(1.08);
}

/* --- Legend: without it the ramp is decoration, not information --------- */
.coverage__legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3) var(--sp-5);
  margin-top: var(--sp-5);
  font-size: var(--fs-xs);
  color: var(--c-on-dark-soft);
}
.coverage__legend li { display: inline-flex; align-items: center; gap: var(--sp-2); }
.coverage__key {
  width: 14px;
  height: 14px;
  border-radius: 3px;
  flex: none;
}
.coverage__key--b1 { background: var(--a-teal); }
.coverage__key--b2 { background: var(--c-brand-soft); }
.coverage__key--b3 { background: var(--a-amber); }
.coverage__key--b4 { background: var(--a-terracotta); }

/* --- Region list ------------------------------------------------------- */
.coverage__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-2);
}

.coverage__row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--r-md);
  text-align: left;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.coverage__row:hover { border-color: var(--c-brand-soft); }
.coverage__row[aria-pressed="true"] {
  background: rgba(136, 189, 164, 0.14);
  border-color: var(--c-brand-soft);
}

.coverage__name {
  font-family: var(--font-head);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: #ffffff;
}
.coverage__lead { font-size: var(--fs-xs); color: var(--c-brand-soft); }  /* 6.94:1 */

.coverage__note {
  margin-top: var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-size: var(--fs-sm);
  color: var(--c-on-dark-soft);
}

@media (prefers-reduced-motion: reduce) {
  .uk-map__region polygon,
  .uk-map__region text,
  .coverage__row { transition: none; }
}

/* ==========================================================================
   HOME — FAQ
   ========================================================================== */

.faq { background: var(--c-surface-alt); }

.faq__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* column gap only — the items carry their own vertical rhythm */
  gap: 0 var(--sp-7);
  align-items: start;
}

.faq__col { align-self: start; }
/* The two columns run independently, so the top border on each column's
   first item keeps them visually level. */
.faq__col .accordion__item:first-child { border-top: 1px solid var(--c-line); }

/* ==========================================================================
   HOME — QUOTE SPLIT
   Scrollable content panel on the left, dotted quote card on the right.
   ========================================================================== */

.quote-split { background: var(--c-surface-alt); }

.quote-split__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
  gap: var(--sp-7);
  /* start, not stretch. Stretching looks tempting — match the panel to the
     form card — but the row then sizes to the TALLER column, which is the
     prose. The panel would grow to fit all its content and stop scrolling
     altogether. The cap below has to be an explicit height. */
  align-items: start;
}

/* --- Scrollable content panel ------------------------------------------ */
.scroll-panel-wrap { position: relative; }

/* Fades the last line out so it's obvious more content is below. Sits above
   the panel but must not swallow clicks or the scroll wheel. */
.scroll-panel-wrap::after {
  content: "";
  position: absolute;
  left: 0;
  right: 6px;                    /* clear of the scrollbar */
  bottom: 0;
  height: 64px;
  background: linear-gradient(to bottom, rgba(230, 242, 221, 0), var(--c-surface-alt));
  pointer-events: none;
}

.scroll-panel {
  /* Sized so the panel's bottom lands near the form card's — head (~150px)
     + 660px ≈ the 820px card. Retune if the form gains or loses fields. */
  max-height: 660px;
  overflow-y: auto;
  /* stops the page behind from scrolling once this panel hits its end */
  overscroll-behavior: contain;
  padding-right: var(--sp-5);
  scrollbar-width: thin;
  scrollbar-color: var(--c-brand) var(--c-brand-pale);
}
.scroll-panel:focus-visible {
  outline: 2px solid var(--c-brand-deep);
  outline-offset: 4px;
}

.scroll-panel::-webkit-scrollbar { width: 6px; }
.scroll-panel::-webkit-scrollbar-track {
  background: var(--c-brand-pale);
  border-radius: var(--r-pill);
}
.scroll-panel::-webkit-scrollbar-thumb {
  background: var(--c-brand);
  border-radius: var(--r-pill);
}
.scroll-panel::-webkit-scrollbar-thumb:hover { background: var(--c-brand-deep); }

/* --- Prose ------------------------------------------------------------- */
.prose h3 {
  font-size: var(--fs-lg);
  margin-top: var(--sp-6);
  margin-bottom: var(--sp-3);
}
.prose h3:first-child { margin-top: 0; }

.prose p {
  margin-bottom: var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--c-body);
  max-width: 64ch;
}
.prose a {
  color: var(--c-brand-deep);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.prose a:hover { color: var(--c-brand-dark); }
.prose ul {
  display: grid;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-4);
  padding-left: var(--sp-5);
  max-width: 64ch;
}
.prose li {
  list-style: disc;
  font-size: var(--fs-sm);
  color: var(--c-body);
}
/* Room at the bottom so the last line clears the fade overlay */
.prose > :last-child { margin-bottom: var(--sp-8); }

/* --- Dotted quote card -------------------------------------------------- */
.quote-card {
  padding: var(--sp-5);
  border-radius: var(--r-lg);
  /* Dotted rather than solid — reads as a die-cut / perforated line, which
     suits packaging. --c-brand is 3.49:1 on white, over the 3:1 UI bar. */
  border: 2px dotted var(--c-brand);
  background: var(--c-surface);
  box-shadow: var(--shadow-sm);
}

.quote-card__head {
  margin-bottom: var(--sp-4);
  padding-bottom: var(--sp-3);
  border-bottom: 1px dotted var(--c-brand);
}
.quote-card__title { font-size: var(--fs-lg); margin-bottom: 2px; }
.quote-card__note { font-size: var(--fs-sm); color: var(--c-muted); }

/* --- Compact form density (desktop) -------------------------------------
   The card carries a lot of fields, so everything inside it runs tighter
   than the default form component. Touch sizing is restored below 992px in
   responsive.css — 36px controls are fine for a mouse, not for a thumb. */
.quote-card .form__control { padding: 10px var(--sp-3); }
.quote-card textarea.form__control { min-height: 68px; }
.quote-card .form__group { gap: 4px; }
.quote-card .form__label { font-size: var(--fs-xs); }
.quote-card .form__row { gap: var(--sp-3); margin-bottom: var(--sp-3); }
.quote-card .form__note { font-size: 11px; }

/* Two-up field rows inside the card */
.form__row--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* --- Sizing fields ------------------------------------------------------ */
/* fieldset carries browser defaults that break the flex column layout */
.form__fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }
.form__fieldset > legend { padding: 0; }

.dims {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr) auto minmax(0, 1fr) 78px;
  align-items: center;
  gap: var(--sp-2);
}
.dims__field { text-align: center; padding-inline: var(--sp-2); }
.dims__unit { padding-inline: var(--sp-2); }
.dims__x {
  font-size: var(--fs-sm);
  color: var(--c-muted);
  user-select: none;
}
/* Strip the spinner — it steals width from an already tight field */
.dims__field::-webkit-outer-spin-button,
.dims__field::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.dims__field { -moz-appearance: textfield; appearance: textfield; }

.form__note--center { text-align: center; }

/* --- Drag & drop -------------------------------------------------------- */
.dropzone {
  position: relative;
  display: grid;
  place-items: center;
  gap: var(--sp-1);
  padding: var(--sp-4) var(--sp-3);
  border: 2px dashed var(--c-line-strong);
  border-radius: var(--r-md);
  background: var(--c-brand-tint);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.dropzone:hover { border-color: var(--c-brand-deep); }
/* Set by forms.js while a drag is over the zone */
.dropzone.is-over {
  border-color: var(--c-brand-deep);
  background: #D7E9CE;
}

/* Visually hidden but still focusable and clickable — display:none would
   drop it from the tab order and break keyboard upload. */
.dropzone__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.dropzone:focus-within {
  outline: 2px solid var(--c-brand-deep);
  outline-offset: 2px;
}

.dropzone__icon { width: 22px; height: 22px; color: var(--c-brand-deep); }
.dropzone__title { font-size: var(--fs-sm); font-weight: 600; color: var(--c-ink); }
.dropzone__hint { font-size: var(--fs-xs); color: var(--c-muted); }

/* --- File previews ------------------------------------------------------ */
.file-list { display: grid; gap: var(--sp-2); }
.file-list:not(:empty) { margin-top: var(--sp-3); }

.file-item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2);
  border: 1px solid var(--c-line);
  border-radius: var(--r-sm);
  background: var(--c-surface);
}

.file-item__thumb {
  display: grid;
  place-items: center;
  flex: none;
  width: 42px;
  height: 42px;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--c-brand-tint);
  color: var(--c-brand-deep);
}
.file-item__thumb img { width: 100%; height: 100%; object-fit: cover; }
.file-item__thumb .icon { width: 20px; height: 20px; }

.file-item__meta { flex: 1; min-width: 0; }
.file-item__name {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--c-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.file-item__size { font-size: var(--fs-xs); color: var(--c-muted); }

.file-item__remove {
  display: grid;
  place-items: center;
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: var(--r-sm);
  color: var(--c-muted);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.file-item__remove:hover { background: var(--c-danger-bg); color: var(--c-danger); }
.file-item__remove .icon { width: 16px; height: 16px; }
.quote-card .form__row { margin-bottom: var(--sp-4); }
.quote-card .btn { margin-top: var(--sp-2); }
.quote-card .form__note { margin-top: var(--sp-2); text-align: center; }
.quote-card .alert[hidden] { display: none; }
.quote-card .alert:not([hidden]) { margin-bottom: var(--sp-4); }

/* ==========================================================================
   HOME — RECENT BLOG
   ========================================================================== */

/* Head + CTA on one row, instead of the centred head used elsewhere */
.section-head-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-5);
  margin-bottom: var(--sp-6);
}
.section-head-row .section-head { margin-bottom: 0; }
.section-head-row__cta { flex: none; }

.blog-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-5);
}

.post-card {
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  overflow: hidden;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.post-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
  border-color: var(--c-brand-soft);
}
/* Whole card is one link, so focus belongs on the card, not the inline box */
.post-card:focus-within {
  border-color: var(--c-brand-deep);
  box-shadow: var(--shadow-md);
}
.post-card__link:focus-visible { outline: none; }

.post-card__link { display: block; height: 100%; }

.post-card__media {
  position: relative;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: var(--c-brand-tint);
}
.post-card__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s var(--ease);
}
.post-card:hover .post-card__media img { transform: scale(1.05); }

.post-card__tag {
  position: absolute;
  left: var(--sp-4);
  top: var(--sp-4);
  padding: 4px var(--sp-3);
  border-radius: var(--r-pill);
  background: var(--c-surface);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--c-brand-deep);
  box-shadow: var(--shadow-sm);
}

/* Category is categorical data, so it gets the colour channel */
.post-card__tag--indigo { color: var(--a-indigo-deep); }
.post-card__tag--green  { color: var(--c-brand-deep); }  /* sustainability stays green — semantic */
.post-card__tag--amber  { color: var(--a-amber-deep); }

.post-card__body { padding: var(--sp-5); }

.post-card__meta {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--c-muted);
}

.post-card__title {
  font-size: var(--fs-lg);
  line-height: 1.35;
  margin-bottom: var(--sp-3);
}

.post-card__text {
  margin-bottom: var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--c-muted);
}

.post-card__more {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--c-brand-deep);
}
.post-card__more .icon { transition: transform var(--dur) var(--ease); }
.post-card:hover .post-card__more .icon { transform: translateX(3px); }

@media (prefers-reduced-motion: reduce) {
  .post-card,
  .post-card__media img,
  .post-card__more .icon { transition: none; }
  .post-card:hover { transform: none; }
  .post-card:hover .post-card__media img { transform: none; }
}

/* ==========================================================================
   Remaining home sections — design pending
   ========================================================================== */
.logo-strip { /* design pending */ }
.capabilities { /* design pending */ }
.product-grid { /* design pending */ }
.process { /* design pending */ }
.quote-form { /* design pending */ }
.blog-detail { /* design pending */ }
/* ==========================================================================
   CTA BAND — dark full-width close, reusable on any page
   ========================================================================== */
.cta-band { background: var(--c-brand-dark); padding-block: var(--sp-8); }

.cta-band__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
}
.cta-band__title { color: #ffffff; font-size: var(--fs-2xl); margin-bottom: var(--sp-2); }
.cta-band__text { color: var(--c-on-dark-soft); font-size: var(--fs-base); max-width: 46ch; }

/* ==========================================================================
   BREADCRUMB
   ========================================================================== */
.breadcrumb { padding: var(--sp-4) 0; border-bottom: 1px solid var(--c-line); }
.breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  list-style: none;
  font-size: var(--fs-sm);
  color: var(--c-muted);
}
.breadcrumb__list li:not(:last-child)::after {
  content: "/";
  margin-left: var(--sp-2);
  color: var(--c-line-strong);
}
.breadcrumb__list a { color: var(--c-muted); text-decoration: none; }
.breadcrumb__list a:hover { color: var(--c-brand-deep); text-decoration: underline; }
.breadcrumb__list li[aria-current="page"] { color: var(--c-ink); font-weight: 600; }

/* ==========================================================================
   PRODUCT DETAILS
   Three columns: image gallery / title + short description / quote form.
   Collapses to a stacked single column below 1100px, gallery-first.
   ========================================================================== */
.product-detail { padding-top: var(--sp-7); }

.product-detail__grid {
  display: grid;
  /* 3 columns again: gallery / title+description / quote form. */
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1fr) minmax(0, 0.9fr);
  gap: var(--sp-7);
  align-items: start;
}

/* --- Column 1: gallery -------------------------------------------------- */
.product-gallery { position: sticky; top: calc(var(--header-h) + var(--sp-4)); }

.product-gallery__main {
  aspect-ratio: 1 / 1;
  border-radius: var(--r-lg);
  background: var(--c-brand-tint);
  border: 1px solid var(--c-line);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.product-gallery__main img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: var(--sp-6);
}

.product-gallery__thumbs {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-3);
  margin-top: var(--sp-3);
}
.product-gallery__thumb {
  aspect-ratio: 1 / 1;
  padding: 0;
  border-radius: var(--r-md);
  border: 2px solid var(--c-line);
  background: var(--c-surface);
  overflow: hidden;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease);
}
.product-gallery__thumb img { width: 100%; height: 100%; object-fit: contain; padding: var(--sp-2); }
.product-gallery__thumb:hover { border-color: var(--c-brand-soft); }
.product-gallery__thumb.is-active { border-color: var(--c-brand); }

/* --- Column 2: title + short description -------------------------------- */
.product-info__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--c-brand-deep);
  margin-bottom: var(--sp-3);
}
.product-info__title {
  font-size: var(--fs-3xl);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-head);
  color: var(--c-ink);
  margin-bottom: var(--sp-3);
}
.product-info__rating {
  display: flex;
  align-items: center;
  gap: 2px;
  color: var(--a-amber);
  font-size: var(--fs-sm);
  margin-bottom: var(--sp-5);
}
.product-info__rating span { margin-left: var(--sp-2); color: var(--c-muted); }

.product-info__text {
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  color: var(--c-body);
  margin-bottom: var(--sp-5);
}

.product-info__specs {
  display: grid;
  gap: var(--sp-3);
  list-style: none;
  margin-bottom: var(--sp-6);
}
.product-info__specs li {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--c-body);
}
.product-info__specs .icon { color: var(--c-brand-deep); flex: none; }

.product-info__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
}

/* --- Column 3: quote form ------------------------------------------------ */
.product-quote { position: sticky; top: calc(var(--header-h) + var(--sp-4)); }

@media (max-width: 1100px) {
  .product-detail__grid { grid-template-columns: 1fr; }
  .product-gallery,
  .product-quote { position: static; }
  .product-gallery__thumbs { grid-template-columns: repeat(6, 1fr); }
}
@media (max-width: 560px) {
  .product-gallery__thumbs { grid-template-columns: repeat(4, 1fr); }
  .product-info__actions .btn { width: 100%; }
}

/* ==========================================================================
   PRODUCT TABS — Description / Specification
   Reuses the generic .tabs__list / .tabs__tab / .tabs__panel widget
   (initTabs() in main.js). Left-aligned rather than centred, since this
   sits under a two/three-column layout rather than a centred section head.
   ========================================================================== */
.product-tabs .tabs__list { justify-content: flex-start; margin-bottom: var(--sp-5); }

.product-tabs .prose h2 {
  font-size: var(--fs-xl);
  color: var(--c-ink);
  margin-top: var(--sp-6);
  margin-bottom: var(--sp-3);
}
.product-tabs .prose h2:first-child { margin-top: 0; }
.product-tabs .prose h3 { font-size: var(--fs-base); }
.product-tabs .prose p { font-size: var(--fs-base); max-width: 75ch; }
.product-tabs .prose ul {
  display: grid;
  gap: var(--sp-2);
  margin-bottom: var(--sp-4);
  padding-left: var(--sp-5);
  max-width: 75ch;
  color: var(--c-body);
  font-size: var(--fs-base);
}
.product-tabs .prose li { list-style: disc; font-size: var(--fs-base); }
.product-tabs .prose > :last-child { margin-bottom: 0; }

/* --- Description: table of contents + body ------------------------------- */
.desc {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 220px;
  gap: var(--sp-7);
  align-items: start;
}

/* --- Scrollable body, same pattern as .scroll-panel on the homepage
   quote-split section: a fixed max-height with its own scrollbar instead
   of letting a long description push the whole page height out. --- */
.desc__body-wrap { position: relative; }
.desc__body-wrap::after {
  content: "";
  position: absolute;
  left: 0;
  right: 6px;
  bottom: 0;
  height: 64px;
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--c-surface));
  pointer-events: none;
}
.desc__body {
  max-height: 600px;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-right: var(--sp-5);
  scrollbar-width: thin;
  scrollbar-color: var(--c-brand) var(--c-brand-pale);
}
.desc__body:focus-visible {
  outline: 2px solid var(--c-brand-deep);
  outline-offset: 4px;
}
.desc__body::-webkit-scrollbar { width: 6px; }
.desc__body::-webkit-scrollbar-track {
  background: var(--c-brand-pale);
  border-radius: var(--r-pill);
}
.desc__body::-webkit-scrollbar-thumb {
  background: var(--c-brand);
  border-radius: var(--r-pill);
}
.desc__body::-webkit-scrollbar-thumb:hover { background: var(--c-brand-deep); }

.desc__toc {
  position: sticky;
  top: calc(var(--header-h) + var(--sp-4));
  padding: var(--sp-4);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  background: var(--c-brand-tint);
}
.desc__toc-title {
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--c-muted);
  margin-bottom: var(--sp-3);
}
.desc__toc ul { display: grid; gap: var(--sp-2); list-style: none; }
.desc__toc a {
  display: block;
  padding: var(--sp-1) 0 var(--sp-1) var(--sp-3);
  border-left: 2px solid var(--c-line-strong);
  font-size: var(--fs-sm);
  color: var(--c-body);
  text-decoration: none;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.desc__toc a:hover { color: var(--c-brand-deep); border-color: var(--c-brand-deep); }
.desc__toc a.is-active {
  color: var(--c-brand-deep);
  font-weight: 600;
  border-color: var(--c-brand-deep);
}

@media (max-width: 860px) {
  .desc { grid-template-columns: 1fr; }
  .desc__toc { position: static; }
  .desc__toc ul { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
  .desc__toc a { border-left: none; border-bottom: 2px solid var(--c-line-strong); padding: 0 0 var(--sp-1); }
}

/* --- Specification table ------------------------------------------------- */
.spec-table-wrap { overflow-x: auto; border: 1px solid var(--c-line); border-radius: var(--r-md); }

.spec-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.spec-table tr:not(:last-child) { border-bottom: 1px solid var(--c-line); }
.spec-table tr:nth-child(even) { background: var(--c-brand-tint); }

.spec-table th,
.spec-table td {
  padding: var(--sp-3) var(--sp-4);
  text-align: left;
  vertical-align: top;
}
.spec-table th {
  width: 42%;
  color: var(--c-ink);
  font-weight: 600;
}
.spec-table td { color: var(--c-body); }

@media (max-width: 560px) {
  .spec-table th, .spec-table td { padding: var(--sp-2) var(--sp-3); }
}

/* ==========================================================================
   PRODUCT FEATURE SPLIT — admin-managed image + text sections
   Two fixed rows (Admin → Products → Features tab), each a 50/50 grid;
   the second one reverses column order so the layout alternates.
   ========================================================================== */
.feature-split__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-7);
  align-items: center;
}
.feature-split--reverse .feature-split__grid { direction: rtl; }
.feature-split--reverse .feature-split__media,
.feature-split--reverse .feature-split__content { direction: ltr; }

.feature-split__media {
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--c-brand-tint);
  border: 1px solid var(--c-line);
  aspect-ratio: 4 / 3;
}
.feature-split__media img { width: 100%; height: 100%; object-fit: cover; }

.feature-split__title {
  font-family: var(--font-head);
  font-size: var(--fs-h3, 1.5rem);
  color: var(--c-ink);
  margin-bottom: var(--sp-4);
}
.feature-split__body { color: var(--c-body); }
.feature-split__body p { margin-bottom: var(--sp-3); max-width: 60ch; }
.feature-split__body p:last-child { margin-bottom: 0; }

.feature-split + .feature-split { padding-top: 0; }

@media (max-width: 860px) {
  .feature-split__grid { grid-template-columns: 1fr; }
  .feature-split--reverse .feature-split__grid { direction: ltr; }
  .feature-split__media { order: -1; }
}

/* ==========================================================================
   RELATED PRODUCTS — lightweight carousel
   Pure native scroll-snap: no slider library, no clones, no autoplay timer,
   no per-slide JS. .carousel is the real scroll container (overflow-x:auto,
   scroll-snap-type:x), so it is draggable/swipeable and keyboard-scrollable
   with zero JS. The two arrow buttons in main.js just call scrollBy() by
   one card width — a progressive enhancement, not the mechanism.
   ========================================================================== */
.carousel__nav { display: flex; gap: var(--sp-2); flex: none; }

.carousel__btn {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-pill);
  background: var(--c-surface);
  color: var(--c-ink);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
.carousel__btn:hover { background: var(--c-brand-deep); border-color: var(--c-brand-deep); color: #fff; }
.carousel__btn--prev .icon { transform: rotate(180deg); }
.carousel__btn:disabled { opacity: 0.4; pointer-events: none; }

.carousel {
  display: flex;
  gap: var(--sp-5);
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-left: var(--gutter);
  padding-bottom: var(--sp-3); /* room for the scrollbar so it doesn't clip the card shadow */
  /* Native scrollbar, styled thin rather than hidden — hiding it would
     remove the only visual cue (besides the arrows) that there's more
     to scroll. */
  scrollbar-width: thin;
  scrollbar-color: var(--c-brand-pale) transparent;
}
.carousel::-webkit-scrollbar { height: 6px; }
.carousel::-webkit-scrollbar-track { background: transparent; }
.carousel::-webkit-scrollbar-thumb { background: var(--c-brand-pale); border-radius: var(--r-pill); }
.carousel::-webkit-scrollbar-thumb:hover { background: var(--c-brand); }

.carousel:focus-visible {
  outline: 2px solid var(--c-brand-deep);
  outline-offset: 4px;
  border-radius: var(--r-md);
}

.carousel__slide {
  flex: 0 0 auto;
  width: 300px;
  scroll-snap-align: start;
}
.carousel__slide .product-card { height: 100%; }

@media (max-width: 640px) {
  .carousel__slide { width: 78vw; }
}

/* ==========================================================================
   REQUEST A QUOTE — dedicated conversion page
   ========================================================================== */

/* --- Intro stats --------------------------------------------------------- */
.quote-intro__stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-4);
  list-style: none;
  max-width: 960px;
  margin: var(--sp-7) auto 0;
}
.quote-intro__stats li {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  background: var(--c-brand-tint);
}
.quote-intro__stats .icon { color: var(--c-brand-deep); flex: none; }
.quote-intro__stats strong { display: block; font-family: var(--font-head); font-size: var(--fs-lg); color: var(--c-ink); }
.quote-intro__stats span { display: block; font-size: var(--fs-xs); color: var(--c-muted); }

.quote-page { padding-top: 0; }

/* --- Two-column layout: content left, form right --------------------------
   The form is the conversion goal, so it outweighs the content column:
   wider track, an elevated card (border + shadow-lg vs. the content's plain
   text), and a muted/condensed treatment on the left so the eye lands on
   the form first. */
.quote-page__grid {
  display: grid;
  grid-template-columns: minmax(0, 0.75fr) minmax(0, 1.15fr);
  gap: var(--sp-8);
  align-items: start;
}

.quote-page__content { padding-top: var(--sp-2); color: var(--c-muted); }
.quote-page__content .quote-steps__item h3 { color: var(--c-body); }

.quote-page__form {
  position: sticky;
  top: calc(var(--header-h) + var(--sp-4));
  border: 1px solid var(--c-brand-soft);
  box-shadow: var(--shadow-lg);
}

/* --- Numbered process steps ------------------------------------------------ */
.quote-steps { display: grid; gap: var(--sp-5); margin-bottom: var(--sp-7); }

.quote-steps__item {
  display: flex;
  gap: var(--sp-4);
  align-items: flex-start;
}
.quote-steps__num {
  display: grid;
  place-items: center;
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: var(--r-pill);
  background: var(--c-brand-deep);
  color: #fff;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: var(--fs-sm);
}
.quote-steps__item h3 { font-size: var(--fs-base); color: var(--c-ink); margin-bottom: 2px; }
.quote-steps__item p { font-size: var(--fs-sm); color: var(--c-body); }

/* --- Guarantee checklist --------------------------------------------------- */
.quote-guarantees {
  display: grid;
  gap: var(--sp-3);
  list-style: none;
  margin-bottom: var(--sp-7);
}
.quote-guarantees li {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--c-body);
}
.quote-guarantees .icon { color: var(--c-success); flex: none; }

/* --- Compact help bar (fits under a narrower content column) -------------- */
/* The generic .help-bar assumes a wide track (icon, text and actions in one
   row). In the quote page's narrower content column that squeezes
   .help-bar__text to a sliver and wraps every word onto its own line, so the
   compact variant stacks instead: icon+heading row, then full-width actions. */
.help-bar--compact {
  flex-wrap: wrap;
  align-items: flex-start;
  margin-top: 0;
  gap: var(--sp-4);
}
.help-bar--compact .help-bar__text { flex-basis: 200px; }
.help-bar--compact .help-bar__actions { flex-basis: 100%; }

@media (max-width: 1100px) {
  .quote-page__grid { grid-template-columns: 1fr; }
  .quote-page__form { position: static; max-width: 620px; }
}
@media (max-width: 700px) {
  .quote-intro__stats { grid-template-columns: repeat(2, 1fr); }
  .help-bar--compact { text-align: center; justify-content: center; }
  .help-bar--compact .help-bar__text { flex-basis: 100%; }
}

/* ==========================================================================
   ABOUT US
   ========================================================================== */

/* --- Hero: copy + illustration, stat strip beneath ------------------------ */
.about-hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr);
  gap: var(--sp-8);
  align-items: center;
}
.about-hero__title {
  font-size: var(--fs-4xl);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-head);
  color: var(--c-ink);
  margin: var(--sp-3) 0 var(--sp-4);
}
.about-hero__title em { color: var(--c-brand-deep); font-style: normal; }
.about-hero__lead { font-size: var(--fs-lg); color: var(--c-body); margin-bottom: var(--sp-6); max-width: 56ch; }
.about-hero__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

.about-hero__media {
  aspect-ratio: 6 / 5;
  border-radius: var(--r-lg);
  background: var(--c-brand-tint);
  display: flex;
  align-items: center;
  justify-content: center;
}
.about-hero__media img { width: 80%; height: 80%; object-fit: contain; }

.about-hero__stats { margin-top: var(--sp-8); }

/* --- Story: image + prose, alternates the hero's copy-first layout -------- */
.about-story__grid {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr);
  gap: var(--sp-8);
  align-items: center;
}
.about-story__media {
  aspect-ratio: 6 / 5;
  border-radius: var(--r-lg);
  background: var(--c-brand-tint);
  display: flex;
  align-items: center;
  justify-content: center;
}
.about-story__media img { width: 80%; height: 80%; object-fit: contain; }

.about-story__copy p { font-size: var(--fs-base); color: var(--c-body); margin-top: var(--sp-4); max-width: 62ch; }

/* --- Values: four icon cards ---------------------------------------------- */
.value-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-5);
}
.value-card {
  padding: var(--sp-5);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.value-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }

.value-card__icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: var(--r-pill);
  background: var(--c-brand-tint);
  color: var(--c-brand-deep);
  margin-bottom: var(--sp-4);
}
.value-card__title { font-size: var(--fs-base); color: var(--c-ink); margin-bottom: var(--sp-2); }
.value-card__text { font-size: var(--fs-sm); color: var(--c-body); }

@media (max-width: 992px) {
  .about-hero__grid,
  .about-story__grid { grid-template-columns: 1fr; }
  .about-hero__media { order: -1; max-width: 420px; margin-inline: auto; }
  .about-story__media { max-width: 420px; margin-inline: auto; }
  .value-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .value-grid { grid-template-columns: 1fr; }
  .cta-band__inner { text-align: center; justify-content: center; }
}

/* ==========================================================================
   BLOG LISTING — post grid + sidebar
   ========================================================================== */
.blog-intro { padding-bottom: 0; }

.blog-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: var(--sp-8);
  align-items: start;
}

/* Narrower than the home page's 3-up strip, since it now shares the row
   with a sidebar. */
.blog-layout .blog-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-5);
  margin-bottom: var(--sp-7);
}

/* --- Pagination ------------------------------------------------------------ */
.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
}
.pagination__link {
  display: grid;
  place-items: center;
  min-width: 40px;
  height: 40px;
  padding-inline: var(--sp-2);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--c-body);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.pagination__link:hover { border-color: var(--c-brand-deep); color: var(--c-brand-deep); }
.pagination__link.is-active { background: var(--c-brand-deep); border-color: var(--c-brand-deep); color: #fff; }
.pagination__link.is-disabled { opacity: 0.4; pointer-events: none; }
.pagination__ellipsis { color: var(--c-muted); padding-inline: var(--sp-1); }

/* --- Sidebar widgets -------------------------------------------------------- */
.blog-sidebar { display: grid; gap: var(--sp-6); align-content: start; }

.widget {
  padding: var(--sp-5);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  background: var(--c-surface);
}
.widget__title {
  font-size: var(--fs-base);
  color: var(--c-ink);
  margin-bottom: var(--sp-4);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--c-line);
}
.widget-search { width: 100%; }

.widget-recent { display: grid; gap: var(--sp-4); list-style: none; }
.widget-recent a { display: flex; gap: var(--sp-3); align-items: flex-start; }
.widget-recent img {
  width: 64px;
  height: 64px;
  border-radius: var(--r-md);
  object-fit: cover;
  flex: none;
  background: var(--c-brand-tint);
}
.widget-recent strong {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: 1.35;
  color: var(--c-ink);
  margin-bottom: 4px;
  transition: color var(--dur) var(--ease);
}
.widget-recent a:hover strong { color: var(--c-brand-deep); }
.widget-recent time { font-size: var(--fs-xs); color: var(--c-muted); }

@media (max-width: 992px) {
  .blog-layout { grid-template-columns: 1fr; }
  .blog-sidebar { grid-template-columns: repeat(2, minmax(0, 1fr)); display: grid; }
}
@media (max-width: 700px) {
  .blog-layout .blog-grid { grid-template-columns: 1fr; }
  .blog-sidebar { grid-template-columns: 1fr; }
}

/* ==========================================================================
   CONTACT US
   ========================================================================== */
.contact-intro { padding-bottom: 0; }

/* --- Form + info cards ------------------------------------------------------ */
.contact-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: var(--sp-8);
  align-items: start;
}

.contact-info { display: grid; gap: var(--sp-4); align-content: start; }

.contact-info__card {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-4);
  padding: var(--sp-4);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  background: var(--c-surface);
}
.contact-info__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: var(--r-pill);
  background: var(--c-brand-tint);
  color: var(--c-brand-deep);
}
.contact-info__card strong { display: block; font-size: var(--fs-sm); color: var(--c-ink); margin-bottom: 2px; }
.contact-info__card a,
.contact-info__card span { font-size: var(--fs-sm); color: var(--c-body); }
.contact-info__card a:hover { color: var(--c-brand-deep); }

.contact-info__social {
  display: flex;
  gap: var(--sp-3);
  list-style: none;
  padding: var(--sp-2) 0;
}
.contact-info__social a {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--r-pill);
  border: 1px solid var(--c-line-strong);
  color: var(--c-ink);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.contact-info__social a:hover { background: var(--c-brand-deep); border-color: var(--c-brand-deep); color: #fff; }

/* --- Map: click-to-load ----------------------------------------------------- */
.contact-map {
  aspect-ratio: 16 / 6;
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 1px solid var(--c-line);
}
.contact-map__frame { width: 100%; height: 100%; border: 0; display: block; }

.contact-map__placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  background: var(--c-brand-tint);
  text-align: center;
  padding: var(--sp-5);
}
.contact-map__pin { width: 32px; height: 32px; color: var(--c-brand-deep); margin-bottom: var(--sp-2); }
.contact-map__address { font-family: var(--font-head); font-size: var(--fs-lg); color: var(--c-ink); margin-bottom: var(--sp-3); }
.contact-map__hint { font-size: var(--fs-xs); color: var(--c-muted); margin-top: var(--sp-2); }

@media (max-width: 992px) {
  .contact-layout { grid-template-columns: 1fr; }
  .contact-info { grid-template-columns: repeat(2, minmax(0, 1fr)); display: grid; }
}
@media (max-width: 560px) {
  .contact-info { grid-template-columns: 1fr; }
  .contact-map { aspect-ratio: 4 / 5; }
}

/* ==========================================================================
   PORTFOLIO
   ========================================================================== */
.portfolio-intro { padding-bottom: 0; }

/* --- Filter pills ----------------------------------------------------------- */
.portfolio-filter {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-6);
}
.portfolio-filter__btn {
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-pill);
  background: var(--c-surface);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--c-ink);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.portfolio-filter__btn:hover { border-color: var(--c-brand-deep); color: var(--c-brand-deep); }
.portfolio-filter__btn.is-active { background: var(--c-brand-deep); border-color: var(--c-brand-deep); color: #fff; }

/* --- Grid --------------------------------------------------------------- */
.portfolio-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-5);
}

.portfolio-item {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--c-surface);
}
.portfolio-item__btn {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  background: var(--c-brand-tint);
  cursor: pointer;
}
.portfolio-item__btn img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: var(--sp-5);
  transition: transform var(--dur) var(--ease);
}
.portfolio-item__btn:hover img { transform: scale(1.05); }

.portfolio-item__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  gap: 2px;
  padding: var(--sp-4);
  background: linear-gradient(to top, rgba(27, 43, 38, 0.78) 0%, rgba(27, 43, 38, 0) 55%);
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.portfolio-item__btn:hover .portfolio-item__overlay,
.portfolio-item__btn:focus-visible .portfolio-item__overlay { opacity: 1; }

.portfolio-item__tag {
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--c-brand-pale);
}
.portfolio-item__title { font-family: var(--font-head); font-size: var(--fs-base); color: #fff; }
.portfolio-item__zoom {
  position: absolute;
  top: var(--sp-3);
  right: var(--sp-3);
  width: 20px;
  height: 20px;
  color: #fff;
}

/* --- Gallery card body: visible name + CTA (not just a hover overlay) --- */
.portfolio-item__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4);
}
.portfolio-item__name { font-family: var(--font-head); font-size: var(--fs-base); font-weight: 600; color: var(--c-ink); }

.portfolio-empty { text-align: center; color: var(--c-muted); padding: var(--sp-7) 0; }

/* --- Lightbox: native <dialog> -------------------------------------------- */
.lightbox {
  /* The global reset's `* { margin: 0 }` wipes the UA stylesheet's
     `margin: auto`, which is what centers a <dialog> opened with
     showModal() — restore it explicitly, plus fixed positioning since the
     dialog is otherwise centered relative to its normal-flow position. */
  position: fixed;
  inset: 0;
  margin: auto;
  max-width: min(90vw, 900px);
  max-height: 90vh;
  padding: 0;
  border: 0;
  border-radius: var(--r-lg);
  background: var(--c-surface);
  box-shadow: var(--shadow-lg);
}
.lightbox::backdrop { background: rgba(27, 43, 38, 0.72); }

.lightbox__img {
  display: block;
  width: 100%;
  max-height: 72vh;
  object-fit: contain;
  background: var(--c-brand-tint);
}
.lightbox__caption { padding: var(--sp-4) var(--sp-5); font-size: var(--fs-sm); color: var(--c-body); }

.lightbox__close {
  position: absolute;
  top: var(--sp-3);
  right: var(--sp-3);
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: var(--r-pill);
  background: rgba(27, 43, 38, 0.55);
  color: #fff;
}
.lightbox__close:hover { background: rgba(27, 43, 38, 0.8); }

@media (max-width: 992px) {
  .portfolio-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 700px) {
  .portfolio-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 460px) {
  .portfolio-grid { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .portfolio-item__btn img,
  .portfolio-item__overlay { transition: none; }
  .portfolio-item__btn:hover img { transform: none; }
}
