/* ==========================================================================
   PAGES - section-level styles: hero, journey, capability band, CTA band
   Depends on tokens.css, base.css and components.css.
   ========================================================================== */

/* ==========================================================================
   SECTION FURNITURE
   ========================================================================== */

.section--surface { background: var(--color-surface); }

.section--dark {
  background: var(--blue-950);
  color: var(--steel-200);
}

.section--dark h2, .section--dark h3 { color: #fff; }
.section--dark .lede { color: var(--steel-400); }

.section-head { max-width: 62ch; margin-bottom: clamp(var(--space-6), 2.5vw, var(--space-10)); }
.section-head--center { margin-inline: auto; text-align: center; }
.section-head--center .eyebrow { justify-content: center; }
.section-head--center .lede { margin-inline: auto; }

.section-foot { margin-top: clamp(var(--space-6), 2.5vw, var(--space-10)); }
.section-head--center + .grid + .section-foot,
.section-foot--center { text-align: center; }

/* On dark backgrounds the red eyebrow loses contrast, so it goes light. */
.eyebrow--on-dark { color: var(--accent-300); }
.eyebrow--on-dark::before { background: linear-gradient(90deg, var(--accent-400), var(--accent-300)); }

/* ---- Framed media with a metallic edge -------------------------------- */

.media-frame {
  position: relative;
  border-radius: var(--radius-xl);
  overflow: hidden;
  box-shadow: var(--shadow-xl);
  border: 1px solid var(--color-border);
  transform-style: preserve-3d;
  transition: transform var(--dur-base) var(--ease-out);
  background: var(--color-muted);
}

/* The moving specular highlight, driven by --tilt-x / --tilt-y from motion.js */
.media-frame__sheen {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    420px circle at var(--tilt-x, 50%) var(--tilt-y, 0%),
    rgba(255, 255, 255, 0.22),
    transparent 60%
  );
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
  z-index: 3;
}

.media-frame:hover .media-frame__sheen { opacity: 1; }

/* ---- Tick list --------------------------------------------------------- */

.check-list { display: flex; flex-direction: column; gap: var(--space-3); }

.check-list li {
  position: relative;
  padding-left: var(--space-8);
  line-height: var(--leading-snug);
}

.check-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--blue-50);
  border: 1px solid var(--blue-200);
}

/* The tick itself, drawn with two borders rotated into an L. */
.check-list li::after {
  content: "";
  position: absolute;
  left: 6px;
  top: 8px;
  width: 8px;
  height: 4px;
  border-left: 2px solid var(--color-primary);
  border-bottom: 2px solid var(--color-primary);
  transform: rotate(-45deg);
}

/* ==========================================================================
   HERO - white page, full-bleed background visual

   The background runs off the right edge of the screen and a white gradient
   washes across it from the left, so the headline sits on clean white while
   the visual stays fully sharp on the right.

   This is deliberately NOT a dark scrim over a full-width image. A dark
   overlay would hide the supplied visual and turn a white brand navy. The
   wash goes the other way: it protects the text with white, and leaves the
   picture alone.
   ========================================================================== */

.hero {
  position: relative;
  padding-top: calc(var(--navbar-h) + clamp(var(--space-8), 5vw, var(--space-16)));
  padding-bottom: clamp(var(--space-10), 5vw, var(--space-20));
  background: var(--color-background);
  overflow: hidden;
  isolation: isolate;
}

/* ---- Background --------------------------------------------------------- */

.hero__bg.media--background {
  /* Anchored right, roughly two thirds wide, bleeding off the edge. */
  inset: 0 0 0 auto;
  width: min(68%, 1080px);
  z-index: 0;
}

.hero__bg .media-asset,
.hero__bg .media-anim__poster,
.hero__bg .media-anim__motion {
  object-fit: cover;
  object-position: center right;
}

/* ---- White wash ---------------------------------------------------------
   Two layers. The horizontal one protects the copy column. The vertical one
   softens the top and bottom edges so the visual does not end on a hard line
   against the next section.
   ---------------------------------------------------------------------- */

.hero__wash {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(
      100deg,
      #FFFFFF 0%,
      #FFFFFF 34%,
      rgba(255, 255, 255, 0.94) 44%,
      rgba(255, 255, 255, 0.55) 56%,
      rgba(255, 255, 255, 0.12) 72%,
      rgba(255, 255, 255, 0) 88%
    ),
    linear-gradient(to bottom, #FFFFFF 0%, rgba(255, 255, 255, 0) 14%),
    linear-gradient(to top, #FFFFFF 0%, rgba(255, 255, 255, 0) 16%);
}

.hero__texture {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: var(--grid-size) var(--grid-size);
  /* Grid only over the white area, so it does not sit on top of the visual. */
  mask-image: linear-gradient(100deg, #000 0%, #000 38%, transparent 58%);
  -webkit-mask-image: linear-gradient(100deg, #000 0%, #000 38%, transparent 58%);
}

/* ---- Layout ------------------------------------------------------------- */

.hero__inner {
  position: relative;
  z-index: 3;
}

.hero__content {
  /* Kept inside the washed area so every line sits on white. */
  max-width: min(58ch, 52%);
}

@media (max-width: 999px) {
  .hero__content { max-width: 100%; }
}

.hero__title {
  font-size: clamp(2.125rem, 1.3rem + 3.2vw, 3.5rem);
  font-weight: var(--weight-extrabold);
  line-height: 1.08;
  letter-spacing: -0.035em;
  color: var(--color-foreground);
  margin-block: var(--space-5) var(--space-5);
}

/* One accent, one colour. No gradient text: it reads as a template. */
.hero__title-accent {
  display: block;
  color: var(--color-primary);
}

.hero__lede {
  font-size: clamp(var(--text-base), 0.95rem + 0.35vw, var(--text-lg));
  line-height: var(--leading-relaxed);
  color: var(--color-muted-foreground);
  max-width: 52ch;
}

.hero__actions { margin-top: var(--space-7, var(--space-8)); }

/* ---- Fact strip -------------------------------------------------------- */

.hero__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: var(--space-5) var(--space-6);
  margin-top: clamp(var(--space-8), 3.5vw, var(--space-10));
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-border);
  max-width: 620px;
}

.hero__fact { display: flex; flex-direction: column; gap: var(--space-1); }

.hero__fact dt {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--color-accent);
}

.hero__fact dd {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  color: var(--color-foreground);
}

/* ---- Certification badge ---------------------------------------------- */

.hero__badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: clamp(var(--space-8), 3.5vw, var(--space-10));
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-pill);
  background: #fff;
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-md);
}

.hero__badge svg {
  width: 22px;
  height: 22px;
  flex: none;
  color: var(--color-primary);
}

.hero__badge span {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
  font-size: var(--text-xs);
  color: var(--color-muted-foreground);
}

.hero__badge strong {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--color-foreground);
  letter-spacing: -0.01em;
}

/* ==========================================================================
   HERO ON TABLET AND PHONE

   Below 1000px the background moves ABOVE the copy as a banner instead of
   sitting behind it. At 375px wide there is no room for text and a picture to
   share the same space, and washing the picture out far enough to read over
   would leave neither working.
   ========================================================================== */

@media (max-width: 999px) {
  .hero {
    padding-top: calc(var(--navbar-h) + var(--space-4));
    display: flex;
    flex-direction: column;
  }

  /* Without .media--background too: that class arrives with the script, and
     until then the box had no height, so the heading below jumped down by
     the picture's full height as the page loaded. */
  .hero__bg,
  .hero__bg.media--background {
    position: relative;
    inset: auto;
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius-lg);
    overflow: hidden;
    margin-bottom: var(--space-8);
    /* Pulled to the gutter so it matches the container width. */
    margin-inline: var(--gutter);
    width: calc(100% - var(--gutter) * 2);
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow-md);
  }

  .hero__wash { display: none; }

  .hero__texture {
    mask-image: linear-gradient(to bottom, #000, transparent 70%);
    -webkit-mask-image: linear-gradient(to bottom, #000, transparent 70%);
  }

  .hero__facts { max-width: 100%; }
}

@media (max-width: 560px) {
  .hero__bg,
  .hero__bg.media--background { aspect-ratio: 4 / 3; }
}

/* ---- Poster-first animated image --------------------------------------
   The still and the animation are stacked. The animation fades in on top
   once it has downloaded, so there is never a blank frame.
   ---------------------------------------------------------------------- */

.media-anim {
  position: absolute;
  inset: 0;
  display: block;
}

.media-anim__poster,
.media-anim__motion {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.media-anim__motion {
  opacity: 0;
  transition: opacity var(--dur-cinematic) var(--ease-out);
  z-index: 2;
}

.media-anim__motion.is-loaded { opacity: 1; }


/* ==========================================================================
   CAPABILITY CARDS - light, on white

   Was a dark navy band with glass cards over a background image. Changed to
   white: the page reads far cleaner, and the brand blue is worth more when it
   is used on a handful of elements than when it covers whole sections.
   ========================================================================== */

.capability { background: var(--color-background); }

.capability__card {
  position: relative;
  padding: var(--space-6);
  border-radius: var(--radius-lg);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-xs);
  transition:
    transform var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out);
}

.capability__card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: var(--color-border-strong);
}

.capability__card-num {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  color: var(--color-accent);
  margin-bottom: var(--space-3);
}

.capability__card-title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--color-foreground);
  margin-bottom: var(--space-3);
}

.capability__card p {
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  color: var(--color-muted-foreground);
}

/* ==========================================================================
   THE EXPORT JOURNEY - scroll-scrubbed stage

   The visual pins to the viewport while the eight steps scroll over it, and
   the canvas is repainted frame by frame from the scroll position. It reads
   as a video whose playhead is the scroll wheel.

   THE MECHANIC

   `.journey__stage` is `position: sticky` at 100vh, so it sticks to the
   viewport for as long as the section is passing through. `.journey__inner`
   is then pulled back up by exactly 100vh so the copy sits on top of the
   pinned stage instead of below it. Total section height minus one viewport
   is the distance the sequence plays over, which is what
   journey-scrub.js measures.

   The section needs real height for this to work: eight steps with generous
   gaps is what gives the sequence room to play. Shorten the gaps and the
   animation gets faster, not shorter.
   ========================================================================== */

.journey {
  position: relative;
  background: var(--blue-950);
  color: #fff;
  isolation: isolate;
  /* No overflow:hidden here. It would break position:sticky on the stage. */
}

/* ---- Pinned stage ------------------------------------------------------ */

.journey__stage {
  position: sticky;
  top: 0;
  height: 100vh;
  /* Falls back to the dynamic viewport unit where it is supported, so mobile
     browser chrome appearing and disappearing does not resize the stage. */
  height: 100dvh;
  z-index: 0;
  overflow: hidden;
  background: var(--blue-950);
}

.journey__canvas {
  display: block;
  width: 100%;
  height: 100%;
  /* The canvas is sized in device pixels by the script; this is the CSS box. */
}

/* Readability layer. Weighted to the left, where the copy sits on desktop. */
.journey__veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(
      100deg,
      rgba(4, 20, 47, 0.90) 0%,
      rgba(4, 20, 47, 0.78) 32%,
      rgba(4, 20, 47, 0.46) 54%,
      rgba(4, 20, 47, 0.24) 76%,
      rgba(4, 20, 47, 0.16) 100%
    ),
    linear-gradient(to bottom, rgba(4, 20, 47, 0.8) 0%, transparent 18%),
    linear-gradient(to top, rgba(4, 20, 47, 0.8) 0%, transparent 18%);
}

.journey__grid {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.045) 1px, transparent 1px);
  background-size: 52px 52px;
  mask-image: linear-gradient(100deg, #000 0%, #000 40%, transparent 70%);
  -webkit-mask-image: linear-gradient(100deg, #000 0%, #000 40%, transparent 70%);
}

/* ---- Content pulled over the pinned stage ----------------------------- */

.journey__inner {
  position: relative;
  z-index: 3;
  /* Exactly cancels the stage height, so the copy overlays it. */
  margin-top: -100vh;
  margin-top: -100dvh;
  padding-top: clamp(var(--space-16), 12vh, var(--space-24));
  padding-bottom: clamp(var(--space-16), 12vh, var(--space-24));
}

.journey__head {
  max-width: 54ch;
  margin-bottom: clamp(var(--space-10), 8vh, var(--space-16));
}

.journey__heading { color: #fff; }

/* ---- Progress rail ----------------------------------------------------- */

.journey__rail {
  position: sticky;
  top: calc(var(--navbar-h) + var(--space-4));
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-3) var(--space-4);
  margin-bottom: clamp(var(--space-10), 8vh, var(--space-16));
  border-radius: var(--radius-pill);
  background: rgba(4, 20, 47, 0.68);
  -webkit-backdrop-filter: blur(16px) saturate(170%);
  backdrop-filter: blur(16px) saturate(170%);
  border: 1px solid rgba(255, 255, 255, 0.16);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

/* The fill tracks the scrub position, so the rail and the frame agree.
   --journey-scrub is set on the section by journey-scrub.js; --journey-progress
   is the step-based value from motion.js. Either drives it. */
.journey__rail::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--journey-scrub, var(--journey-progress, 0%));
  background: linear-gradient(90deg, rgba(217, 26, 32, 0.34), rgba(17, 82, 196, 0.38));
  pointer-events: none;
  transition: width 120ms linear;
}

.journey__marker {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.56);
  white-space: nowrap;
  transition: color var(--dur-base) var(--ease-out), background var(--dur-base) var(--ease-out);
}

.journey__marker::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.3);
  flex: none;
  transition: background var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}

.journey__marker.is-done { color: rgba(255, 255, 255, 0.92); }
.journey__marker.is-done::before { background: var(--accent-400); }

.journey__marker[aria-current="step"] {
  color: #fff;
  background: rgba(255, 255, 255, 0.14);
}

.journey__marker[aria-current="step"]::before {
  background: var(--accent-400);
  box-shadow: 0 0 0 4px rgba(51, 140, 242, 0.28);
}

/* ---- Steps ------------------------------------------------------------- */

.journey__steps {
  display: flex;
  flex-direction: column;
  /* This gap is what gives the sequence its running length. */
  gap: clamp(var(--space-20), 34vh, var(--space-32));
}

.journey__step {
  max-width: 52ch;
  padding: var(--space-8);
  border-radius: var(--radius-xl);
  background: rgba(4, 20, 47, 0.58);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  backdrop-filter: blur(18px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.16);
  box-shadow: var(--shadow-xl);
  /* Low enough that an inactive panel reads as "not this one" rather than
     as half-legible clutter competing with the active step. At 0.34 the
     text was still readable and fought the panel in focus. */
  opacity: 0.2;
  transform: translateY(18px) scale(0.98);
  filter: blur(1px);
  transition:
    opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out),
    filter var(--dur-slow) var(--ease-out),
    border-color var(--dur-slow) var(--ease-out);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .journey__step { background: rgba(4, 20, 47, 0.92); }
}

.journey__step.is-active {
  opacity: 1;
  transform: none;
  filter: none;
  border-color: rgba(255, 255, 255, 0.3);
}

/* Alternate sides on wide screens so the eye travels down the page and the
   visual behind is never fully covered. */
@media (min-width: 1100px) {
  .journey__step:nth-child(even) { margin-left: auto; }
}

/* Reduced motion, no JavaScript, or a metered connection: every panel is
   fully visible and the stage holds a single still. */
.journey.is-static .journey__step,
.journey--static .journey__step,
.no-js .journey__step {
  opacity: 1;
  transform: none;
  filter: none;
}

.journey__step-index {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  color: var(--accent-300);
  margin-bottom: var(--space-3);
}

.journey__step-title {
  font-size: clamp(var(--text-2xl), 1.4rem + 1vw, var(--text-3xl));
  font-weight: var(--weight-extrabold);
  color: #fff;
  margin-bottom: var(--space-4);
}

.journey__step p {
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
  color: rgba(242, 244, 246, 0.88);
}

.journey__foot {
  margin-top: clamp(var(--space-16), 14vh, var(--space-24));
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

/* ---- No JavaScript ----------------------------------------------------
   The canvas stays blank without the script, so a still is shown instead.
   ------------------------------------------------------------------- */

.journey__fallback { position: absolute; inset: 0; }

.journey__fallback img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center right;
}

/* ---- Phone and tablet -------------------------------------------------
   The pinned stage is kept, because that is the whole effect, but the veil
   goes vertical since the copy sits over the middle rather than the left.
   ------------------------------------------------------------------- */

@media (max-width: 899px) {
  .journey__veil {
    background:
      linear-gradient(
        to bottom,
        rgba(4, 20, 47, 0.9) 0%,
        rgba(4, 20, 47, 0.72) 30%,
        rgba(4, 20, 47, 0.72) 70%,
        rgba(4, 20, 47, 0.9) 100%
      );
  }

  .journey__grid {
    mask-image: linear-gradient(to bottom, #000, transparent 70%);
    -webkit-mask-image: linear-gradient(to bottom, #000, transparent 70%);
  }

  /* The sticky rail costs too much vertical space on a phone. */
  .journey__rail { position: static; }

  .journey__step { padding: var(--space-6); }
  .journey__steps { gap: clamp(var(--space-16), 26vh, var(--space-24)); }
}


/* ==========================================================================
   CALL TO ACTION BAND
   ========================================================================== */

.cta-band {
  background: var(--grad-blue);
  color: #fff;
  position: relative;
  overflow: hidden;
}

.cta-band::after {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--grad-steel-edge);
  opacity: 0.55;
}

.cta-band__inner {
  display: grid;
  gap: var(--space-8);
  align-items: center;
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .cta-band__inner { grid-template-columns: 1.4fr auto; }
}

.cta-band__title {
  font-size: clamp(var(--text-2xl), 1.4rem + 1.4vw, var(--text-4xl));
  color: #fff;
  margin-bottom: var(--space-3);
}

.cta-band__text {
  color: rgba(255, 255, 255, 0.86);
  line-height: var(--leading-relaxed);
  max-width: 56ch;
}

.cta-band .btn--outline {
  color: #fff;
  border-color: rgba(255, 255, 255, 0.45);
  background: transparent;
}

.cta-band .btn--outline:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: #fff;
}

/* ==========================================================================
   PAGE HEADER (every page except home)
   ========================================================================== */

.page-header {
  position: relative;
  padding-top: calc(var(--navbar-h) + var(--space-16));
  padding-bottom: var(--space-16);
  background: var(--blue-900);
  color: #fff;
  overflow: hidden;
  isolation: isolate;
}

.page-header__bg.media--background { inset: -10% 0; z-index: 0; }

.page-header__inner { position: relative; z-index: 2; max-width: 68ch; }

.page-header__title {
  font-size: clamp(var(--text-3xl), 1.6rem + 2.4vw, var(--text-5xl));
  font-weight: var(--weight-extrabold);
  letter-spacing: -0.03em;
  color: #fff;
  margin-block: var(--space-4) var(--space-5);
  text-shadow: 0 2px 24px rgba(4, 20, 47, 0.45);
}

.page-header__lede {
  font-size: clamp(var(--text-base), 0.95rem + 0.3vw, var(--text-lg));
  line-height: var(--leading-relaxed);
  color: rgba(242, 244, 246, 0.88);
}

.page-header .breadcrumb { margin-bottom: var(--space-2); }

/* ==========================================================================
   PROCESS LIST - numbered steps with a connecting rule
   ========================================================================== */

.process-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  counter-reset: process;
  max-width: 900px;
}

.process-step {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-5);
  align-items: start;
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-xs);
  transition: border-color var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}

.process-step:hover {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-md);
}

.process-step__num {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 50%;
  background: var(--grad-blue);
  color: #fff;
  font-size: var(--text-lg);
  font-weight: var(--weight-extrabold);
  font-variant-numeric: tabular-nums;
  box-shadow: var(--shadow-inset-metal);
}

.process-step__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  margin-bottom: var(--space-2);
}

.process-step p {
  font-size: var(--text-sm);
  color: var(--color-muted-foreground);
  line-height: var(--leading-relaxed);
}

@media (max-width: 520px) {
  .process-step { grid-template-columns: 1fr; gap: var(--space-3); }
}

/* ==========================================================================
   FAQ - native details/summary, so it works without JavaScript
   ========================================================================== */

.faq { display: flex; flex-direction: column; gap: var(--space-3); }

.faq__item {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface-raised);
  overflow: hidden;
  transition: border-color var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}

.faq__item[open] {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-sm);
}

.faq__question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: var(--touch-target);
  padding: var(--space-4) var(--space-5);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  color: var(--color-foreground);
  cursor: pointer;
  list-style: none;
  transition: background var(--dur-fast) var(--ease-out);
}

/* Remove the default disclosure triangle in both engines. */
.faq__question::-webkit-details-marker { display: none; }
.faq__question::marker { content: ""; }

.faq__question:hover { background: var(--color-surface); }

.faq__question:focus-visible {
  outline: 3px solid var(--color-ring);
  outline-offset: -3px;
}

/* A plus that becomes a minus when open. */
.faq__question::after {
  content: "";
  width: 14px;
  height: 14px;
  flex: none;
  background:
    linear-gradient(var(--color-primary), var(--color-primary)) center / 100% 2px no-repeat,
    linear-gradient(var(--color-primary), var(--color-primary)) center / 2px 100% no-repeat;
  transition: transform var(--dur-base) var(--ease-metal), background-size var(--dur-base) var(--ease-out);
}

.faq__item[open] .faq__question::after {
  transform: rotate(180deg);
  background:
    linear-gradient(var(--color-accent), var(--color-accent)) center / 100% 2px no-repeat,
    linear-gradient(var(--color-accent), var(--color-accent)) center / 0 100% no-repeat;
}

.faq__answer {
  padding: 0 var(--space-5) var(--space-5);
  color: var(--color-muted-foreground);
  line-height: var(--leading-relaxed);
}

.faq__answer > * + * { margin-top: var(--space-3); }

/* ==========================================================================
   CATALOG - search bar, filter sidebar, results, pagination
   ========================================================================== */

.catalog-search {
  display: flex;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
  flex-wrap: wrap;
}

.catalog-search__field {
  position: relative;
  flex: 1 1 320px;
  min-width: 0;
}

.catalog-search__icon {
  position: absolute;
  left: var(--space-4);
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  color: var(--color-muted-foreground);
  pointer-events: none;
}

.catalog-search__input { padding-left: var(--space-10); }

.filter-toggle { margin-bottom: var(--space-4); width: 100%; }

.catalog {
  display: grid;
  gap: clamp(var(--space-6), 3vw, var(--space-10));
  grid-template-columns: 1fr;
  align-items: start;
}

@media (min-width: 900px) {
  .catalog { grid-template-columns: 264px 1fr; }
}

/* ---- Filters ----------------------------------------------------------- */

.catalog__filters {
  display: none;
  flex-direction: column;
  gap: var(--space-6);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-xs);
}

.catalog__filters.is-open { display: flex; }

@media (min-width: 900px) {
  .catalog__filters {
    display: flex;
    position: sticky;
    top: calc(var(--navbar-h) + var(--space-4));
    max-height: calc(100vh - var(--navbar-h) - var(--space-8));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

.filters__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.filters__title {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--color-muted-foreground);
}

.filters__clear {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  min-height: 32px;
}

.filters__group { border: none; padding: 0; margin: 0; }

.filters__legend {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--color-foreground);
  margin-bottom: var(--space-3);
  padding: 0;
}

.filters__options { display: flex; flex-direction: column; gap: 2px; }

.filters__loading {
  font-size: var(--text-sm);
  color: var(--color-muted-foreground);
}

.filter-option {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--touch-target);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}

.filter-option:hover { background: var(--blue-50); }

.filter-option input {
  width: 18px;
  height: 18px;
  flex: none;
  accent-color: var(--color-primary);
  cursor: pointer;
}

.filter-option input:focus-visible {
  outline: 3px solid var(--color-ring);
  outline-offset: 2px;
}

.filter-option__label {
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  /* Long grade designations wrap instead of overflowing the sidebar. */
  overflow-wrap: break-word;
  min-width: 0;
}

.filter-option__count {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--color-muted-foreground);
  font-variant-numeric: tabular-nums;
}

/* ---- Results bar ------------------------------------------------------- */

.catalog__results { min-width: 0; }

.catalog__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.catalog__count {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-muted-foreground);
}

.catalog__active { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* ---- Active filter chips ----------------------------------------------- */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 34px;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--blue-50);
  border: 1px solid var(--blue-200);
  color: var(--blue-800);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}

.chip:hover { background: var(--blue-100); }

.chip svg { width: 13px; height: 13px; flex: none; }

/* ---- Pagination -------------------------------------------------------- */

.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-10);
}

.pagination:empty { display: none; }

.pagination__btn {
  min-width: var(--touch-target);
  min-height: var(--touch-target);
  padding-inline: var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-raised);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--color-foreground);
  transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}

.pagination__btn:hover:not([disabled]) {
  background: var(--blue-50);
  border-color: var(--color-primary);
}

.pagination__btn.is-current {
  background: var(--grad-blue);
  border-color: transparent;
  color: var(--color-on-primary);
}

.pagination__btn[disabled] { opacity: 0.45; cursor: not-allowed; }

.pagination__gap { color: var(--color-muted-foreground); padding-inline: var(--space-1); }

/* ==========================================================================
   NOTE PANEL - guidance block with a metallic left edge
   ========================================================================== */

.note-panel {
  position: relative;
  padding: clamp(var(--space-6), 3vw, var(--space-10));
  border-radius: var(--radius-xl);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

.note-panel::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background: var(--grad-blue);
}

.note-panel__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  margin-bottom: var(--space-4);
}

.note-panel p { line-height: var(--leading-relaxed); color: var(--color-muted-foreground); }
.note-panel > * + * { margin-top: var(--space-4); }

.note-panel__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  counter-reset: note;
  padding-left: 0;
}

.note-panel__list li {
  position: relative;
  padding-left: var(--space-10);
  line-height: var(--leading-relaxed);
  color: var(--color-muted-foreground);
  counter-increment: note;
}

.note-panel__list li::before {
  content: counter(note);
  position: absolute;
  left: 0;
  top: 0;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--blue-50);
  border: 1px solid var(--blue-200);
  color: var(--blue-800);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

.note-panel__list strong { color: var(--color-foreground); }

/* ==========================================================================
   CONTACT
   ========================================================================== */

.contact-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-6);
  border-radius: var(--radius-lg);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-xs);
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}

.contact-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }

.contact-card__icon {
  width: 28px;
  height: 28px;
  color: var(--color-primary);
  margin-bottom: var(--space-2);
}

.contact-card__title {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--color-muted-foreground);
}

.contact-card__lines {
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-relaxed);
  /* Long email addresses wrap instead of overflowing the card. */
  overflow-wrap: break-word;
}

.contact-card__lines a { color: var(--color-foreground); text-decoration: none; }
.contact-card__lines a:hover { color: var(--color-primary); text-decoration: underline; }

.contact-card__note {
  font-size: var(--text-sm);
  color: var(--color-muted-foreground);
  margin-top: auto;
  padding-top: var(--space-2);
}

.card__text--address {
  font-style: normal;
  line-height: var(--leading-relaxed);
  color: var(--color-foreground);
  font-weight: var(--weight-semibold);
}

/* ---- Map --------------------------------------------------------------- */

.map-wrap { margin-top: clamp(var(--space-8), 4vw, var(--space-12)); }

.map-frame {
  position: relative;
  aspect-ratio: 16 / 7;
  border-radius: var(--radius-xl);
  overflow: hidden;
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-lg);
  background: var(--color-muted);
}

.map-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

@media (max-width: 600px) {
  .map-frame { aspect-ratio: 4 / 3; }
}

/* ==========================================================================
   ENQUIRY FORM
   ========================================================================== */

.enquiry-form {
  padding: clamp(var(--space-6), 3vw, var(--space-10));
  background: var(--color-surface-raised);
  box-shadow: var(--shadow-lg);
}

/* The card hover lift would be wrong on a form. */
.enquiry-form:hover { transform: none; }
.enquiry-form::after { display: none; }

.enquiry-form__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-border);
}

.enquiry-form__note {
  font-size: var(--text-sm);
  color: var(--color-muted-foreground);
}

/* ---- Result ------------------------------------------------------------ */

.form-result {
  margin-top: var(--space-6);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  border-left-width: 4px;
  background: var(--color-surface);
}

.form-result--success {
  border-left-color: var(--color-success);
  background: #F2FAF6;
}

.form-result--error {
  border-left-color: var(--color-danger);
  background: var(--red-50);
}

.form-result__title {
  font-weight: var(--weight-bold);
  margin-bottom: var(--space-2);
  color: var(--color-foreground);
}

.form-result__text {
  font-size: var(--text-sm);
  color: var(--color-muted-foreground);
  line-height: var(--leading-relaxed);
}

.form-result__text a { color: var(--color-primary); font-weight: var(--weight-semibold); }

/* Dark mode needs its own tints; the light ones go muddy. */
:root[data-theme="dark"] .form-result--success { background: rgba(15, 123, 79, 0.14); }
:root[data-theme="dark"] .form-result--error { background: rgba(217, 26, 32, 0.14); }

/* Dark-mode form tints are handled by the data-theme rule above only. */

/* ==========================================================================
   404
   ========================================================================== */

.error-page {
  min-height: 78vh;
  display: grid;
  place-items: center;
  padding-top: calc(var(--navbar-h) + var(--space-12));
  padding-bottom: var(--space-20);
  text-align: center;
  position: relative;
  overflow: hidden;
}

.error-page__code {
  font-family: var(--font-mono);
  font-size: clamp(4rem, 3rem + 8vw, 9rem);
  font-weight: var(--weight-bold);
  line-height: 1;
  letter-spacing: -0.04em;
  background: var(--grad-steel);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  margin-bottom: var(--space-4);
}

@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .error-page__code { color: var(--steel-500); background: none; }
}

.error-page__title {
  font-size: clamp(var(--text-2xl), 1.4rem + 1.6vw, var(--text-4xl));
  margin-bottom: var(--space-4);
}

.error-page__text {
  color: var(--color-muted-foreground);
  line-height: var(--leading-relaxed);
  max-width: 52ch;
  margin-inline: auto;
  margin-bottom: var(--space-8);
}

.error-page__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  justify-content: center;
}

/* ==========================================================================
   FOOTER STAFF LOCK
   Understated on purpose: an icon with no label, so a customer does not
   mistake it for something they should click.
   ========================================================================== */

.footer__lock {
  display: inline-grid;
  place-items: center;
  width: var(--touch-target);
  height: var(--touch-target);
  border-radius: var(--radius-md);
  color: var(--steel-600);
  border: 1px solid rgba(255, 255, 255, 0.10);
  transition:
    color var(--dur-fast) var(--ease-out),
    background var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

.footer__lock:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.24);
}

.footer__lock-icon { width: 16px; height: 16px; }

/* ==========================================================================
   AUTH PAGE - staff login
   Standalone layout with no navbar or footer, so there is nothing to click
   except signing in or going back to the site.
   ========================================================================== */

.auth-body {
  min-height: 100vh;
  background: var(--color-surface);
}

.auth {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--space-6) var(--gutter);
  position: relative;
  overflow: hidden;
}

/* One soft blue wash, keeping the page essentially white. */
.auth::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(50rem 26rem at 50% -10%, rgba(17, 82, 196, 0.08), transparent 70%),
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 100% 100%, var(--grid-size) var(--grid-size), var(--grid-size) var(--grid-size);
  pointer-events: none;
}

.auth__card {
  position: relative;
  width: 100%;
  max-width: 440px;
  padding: clamp(var(--space-6), 4vw, var(--space-10));
  border-radius: var(--radius-xl);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  box-shadow: 0 24px 56px -28px rgba(4, 20, 47, 0.28), 0 2px 6px rgba(4, 20, 47, 0.05);
}

.auth__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-8);
  text-decoration: none;
}

.auth__logo { width: 52px; height: 52px; object-fit: contain; flex: none; }

.auth__brand-name {
  display: block;
  font-size: var(--text-base);
  font-weight: var(--weight-extrabold);
  color: var(--color-primary);
  line-height: 1.15;
}

.auth__brand-sub {
  display: block;
  font-size: 0.6875rem;
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--color-muted-foreground);
}

.auth__title {
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  margin-bottom: var(--space-3);
}

.auth__text {
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  color: var(--color-muted-foreground);
  margin-bottom: var(--space-6);
}

.auth__form { display: flex; flex-direction: column; gap: var(--space-5); }

/* The code input: wide tracking so six digits are easy to read back. */
.auth__code {
  font-family: var(--font-mono);
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.34em;
  text-align: center;
  padding-inline: var(--space-4);
}

.auth__code::placeholder { letter-spacing: 0.34em; color: var(--steel-400); }

.auth__hint {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
  font-size: var(--text-xs);
  color: var(--color-muted-foreground);
  line-height: var(--leading-relaxed);
}

.auth__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}

.auth__link {
  min-height: 36px;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
  font-variant-numeric: tabular-nums;
}

.auth__link:hover:not([disabled]) { color: var(--color-primary-hover); }
.auth__link[disabled] { color: var(--color-muted-foreground); cursor: not-allowed; text-decoration: none; }

.auth__result {
  margin-top: var(--space-5);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  border-left-width: 3px;
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

.auth__result--info    { border-left-color: var(--color-info); background: var(--blue-50); color: var(--blue-800); }
.auth__result--success { border-left-color: var(--color-success); background: #F2FAF6; color: #0B5C3B; }
.auth__result--error   { border-left-color: var(--color-danger); background: var(--red-50); color: var(--red-700); }

.auth__home {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-target);
  margin-top: var(--space-6);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-muted-foreground);
  text-decoration: none;
}

.auth__home:hover { color: var(--color-primary); }
.auth__home svg { width: 16px; height: 16px; }

/* Without JavaScript the login cannot work, so say so rather than showing a
   form that silently does nothing. */
.no-js .auth__form { display: none; }

.no-js .auth__step[data-step="email"]::after {
  content: "JavaScript is required to sign in. Please enable it and reload this page.";
  display: block;
  padding: var(--space-4);
  border-radius: var(--radius-md);
  background: var(--red-50);
  border: 1px solid var(--red-200);
  color: var(--red-700);
  font-size: var(--text-sm);
}

/* ==========================================================================
   CAVEAT PANEL
   ========================================================================== */

.caveat {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border-radius: var(--radius-lg);
  background: #FDF6E8;
  border: 1px solid #F3DCB4;
  border-left: 4px solid var(--color-warning);
}

.caveat__icon { width: 24px; height: 24px; color: var(--color-warning); flex: none; margin-top: 2px; }

.caveat__title {
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: #6B3F00;
  margin-bottom: var(--space-2);
}

.caveat p {
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  color: #7A4800;
}

.caveat p + p { margin-top: var(--space-3); }
.caveat strong { font-weight: var(--weight-bold); }

@media (max-width: 520px) {
  .caveat { grid-template-columns: 1fr; }
}

/* ==========================================================================
   TABS
   ========================================================================== */

.tabs__list {
  display: flex;
  gap: var(--space-2);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-6);
  border-bottom: 1px solid var(--color-border);
  scrollbar-width: thin;
}

.tabs__tab {
  flex: none;
  min-height: var(--touch-target);
  padding: var(--space-2) var(--space-5);
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border);
  background: var(--color-surface-raised);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-muted-foreground);
  white-space: nowrap;
  transition:
    background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

.tabs__tab:hover { color: var(--color-primary); border-color: var(--blue-200); background: var(--blue-50); }

.tabs__tab[aria-selected="true"] {
  background: var(--grad-blue);
  border-color: transparent;
  color: var(--color-on-primary);
  box-shadow: var(--shadow-sm);
}

.tabs__panel:focus-visible { outline: 3px solid var(--color-ring); outline-offset: 4px; border-radius: var(--radius-md); }

/* ==========================================================================
   CALCULATOR
   ========================================================================== */

.calc {
  padding: clamp(var(--space-5), 3vw, var(--space-8));
  border-radius: var(--radius-xl);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
}

.calc__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  margin-bottom: var(--space-2);
}

.calc__formula {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-muted-foreground);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  margin-bottom: var(--space-6);
  overflow-x: auto;
}

.calc__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: var(--space-5);
}

/* Unit suffix sitting inside the input. */
.input-unit { position: relative; }

.input-unit .input { padding-right: var(--space-12); }

.input-unit__suffix {
  position: absolute;
  right: var(--space-4);
  top: 50%;
  transform: translateY(-50%);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-muted-foreground);
  pointer-events: none;
}

.calc__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

/* ---- Result ------------------------------------------------------------ */

.calc__result { display: none; }

.calc__result.is-visible {
  display: block;
  margin-top: var(--space-6);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--blue-50);
  border: 1px solid var(--blue-200);
}

.calc__result--error {
  background: var(--red-50);
  border-color: var(--red-200);
  color: var(--red-700);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.calc__rows { display: flex; flex-direction: column; gap: 0; }

.calc__row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--blue-200);
}

.calc__row:last-child { border-bottom: none; }

.calc__row dt {
  font-size: var(--text-sm);
  color: var(--blue-800);
  min-width: 0;
}

.calc__row dd {
  margin: 0;
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--color-foreground);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* The headline figure. */
.calc__row--primary {
  padding-top: 0;
  padding-bottom: var(--space-4);
}

.calc__row--primary dt {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

.calc__row--primary dd {
  font-size: clamp(var(--text-2xl), 1.3rem + 1.2vw, var(--text-4xl));
  font-weight: var(--weight-extrabold);
  color: var(--color-primary);
  letter-spacing: -0.02em;
}

.calc__unit {
  font-size: 0.6em;
  font-weight: var(--weight-semibold);
  color: var(--color-muted-foreground);
  letter-spacing: 0;
}

.calc__note {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--blue-200);
  font-size: var(--text-xs);
  line-height: var(--leading-relaxed);
  color: var(--blue-800);
}

/* ==========================================================================
   SMALL CONTAINERS
   Declared explicitly rather than relying on inherited layout, so a change
   elsewhere cannot silently collapse them.
   ========================================================================== */

.tabs { display: block; }

.cta-band__actions { justify-content: flex-start; }

@media (min-width: 900px) {
  .cta-band__actions { justify-content: flex-end; }
}

/* ---- 404 help block ---------------------------------------------------- */

.error-page__help {
  margin-top: clamp(var(--space-12), 6vw, var(--space-20));
  padding-top: var(--space-8);
  border-top: 1px solid var(--color-border);
  text-align: left;
  max-width: 480px;
  margin-inline: auto;
}

.error-page__help-title {
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  margin-bottom: var(--space-4);
  text-align: center;
}

.error-page__help-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-bottom: var(--space-6);
}

.error-page__help-list a {
  display: flex;
  align-items: center;
  min-height: var(--touch-target);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-primary);
  text-decoration: none;
  transition: background var(--dur-fast) var(--ease-out), padding-left var(--dur-fast) var(--ease-out);
}

.error-page__help-list a:hover { background: var(--blue-50); padding-left: var(--space-5); }

.error-page__help .error-page__text { text-align: center; margin-bottom: 0; }

/* ==========================================================================
   EXPORT - Incoterm cards, document cards
   ========================================================================== */

.incoterm-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: var(--space-5);
}

.incoterm {
  padding: var(--space-6);
  border-radius: var(--radius-lg);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-xs);
  transition: box-shadow var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}

.incoterm:hover { box-shadow: var(--shadow-md); border-color: var(--color-border-strong); }

.incoterm__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

/* The three-letter code, treated like a part number. */
.incoterm__code {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--grad-blue);
  color: #fff;
  flex: none;
}

.incoterm__name {
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
}

.incoterm__text {
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  color: var(--color-muted-foreground);
}

.incoterm__meta {
  margin-top: var(--space-3);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--color-muted-foreground);
}

.incoterm__meta strong { color: var(--color-foreground); font-weight: var(--weight-semibold); }

/* ---- Document cards ---------------------------------------------------- */

.doc-card {
  padding: var(--space-6);
  border-radius: var(--radius-lg);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-xs);
}

.doc-card__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  margin-bottom: var(--space-5);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.doc-card .check-list li { font-size: var(--text-sm); color: var(--color-muted-foreground); }
.doc-card .check-list strong { color: var(--color-foreground); }

/* ==========================================================================
   GALLERY
   ========================================================================== */

.gallery-filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-8);
}

.gallery-filter:empty { display: none; }

.gallery-filter__btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 40px;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border);
  background: var(--color-surface-raised);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-muted-foreground);
  transition:
    background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

.gallery-filter__btn:hover {
  color: var(--color-primary);
  border-color: var(--blue-200);
  background: var(--blue-50);
}

.gallery-filter__btn.is-active {
  background: var(--grad-blue);
  border-color: transparent;
  color: var(--color-on-primary);
}

.gallery-filter__count {
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  opacity: 0.72;
}

/* ---- Grid -------------------------------------------------------------- */

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
  gap: var(--space-4);
}

.gallery-tile {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--color-border);
  background: var(--color-muted);
  cursor: pointer;
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}

.gallery-tile:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }

.gallery-tile:focus-visible { outline: 3px solid var(--color-ring); outline-offset: 3px; }

.gallery-tile__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}

.gallery-tile:hover .gallery-tile__img { transform: scale(1.06); }

/* Play badge on a video tile. */
.gallery-tile__play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 52px;
  height: 52px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  color: var(--color-primary);
  box-shadow: var(--shadow-md);
  pointer-events: none;
  z-index: 2;
}

.gallery-tile__play svg { width: 24px; height: 24px; margin-left: 2px; }

.gallery-tile__overlay {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
  padding: var(--space-8) var(--space-4) var(--space-4);
  background: linear-gradient(to top, rgba(4, 20, 47, 0.88), transparent);
  text-align: left;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}

.gallery-tile:hover .gallery-tile__overlay,
.gallery-tile:focus-visible .gallery-tile__overlay { opacity: 1; transform: none; }

/* On touch there is no hover, so the caption is always visible. */
@media (hover: none) {
  .gallery-tile__overlay { opacity: 1; transform: none; }
}

.gallery-tile__title {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: #fff;
  line-height: var(--leading-snug);
}

.gallery-tile__tag {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--blue-200);
}

/* ==========================================================================
   LIGHTBOX
   ========================================================================== */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  padding: var(--space-4);
}

/* The closed lightbox must actually leave the page.

   `display: grid` above is an author declaration, so it beats the browser's
   own `[hidden] { display: none }`. Without this rule the closed dialog stays
   laid out over the whole viewport at zero opacity and silently swallows
   every click and tap on the page underneath, which reads as the page having
   frozen. Any full-screen overlay toggled by the `hidden` attribute needs the
   same line. */
.lightbox[hidden] { display: none; }

.lightbox__scrim {
  position: absolute;
  inset: 0;
  background: rgba(4, 20, 47, 0.92);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}

.lightbox.is-open .lightbox__scrim { opacity: 1; }

.lightbox__panel {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1100px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-3);
  opacity: 0;
  transform: scale(0.97);
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}

.lightbox.is-open .lightbox__panel { opacity: 1; transform: none; }

.lightbox__close {
  position: absolute;
  top: calc(var(--space-4) * -1);
  right: 0;
  z-index: 3;
  width: var(--touch-target);
  height: var(--touch-target);
  display: grid;
  place-items: center;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.28);
  color: #fff;
  transition: background var(--dur-fast) var(--ease-out);
}

.lightbox__close:hover { background: rgba(255, 255, 255, 0.26); }
.lightbox__close svg { width: 20px; height: 20px; }

.lightbox__nav {
  width: var(--touch-target);
  height: var(--touch-target);
  display: grid;
  place-items: center;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.24);
  color: #fff;
  flex: none;
  transition: background var(--dur-fast) var(--ease-out);
}

.lightbox__nav:hover { background: rgba(255, 255, 255, 0.24); }
.lightbox__nav svg { width: 22px; height: 22px; }
.lightbox__nav[hidden] { display: none; }

.lightbox__figure { margin: 0; min-width: 0; }

.lightbox__media {
  display: grid;
  place-items: center;
  /* Leaves room for the caption and the close button. */
  max-height: 72vh;
}

.lightbox__img,
.lightbox__video {
  max-width: 100%;
  max-height: 72vh;
  width: auto;
  height: auto;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  background: #000;
}

.lightbox__caption { padding: var(--space-4) var(--space-2) 0; text-align: center; }

.lightbox__title {
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: #fff;
}

.lightbox__text {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  color: rgba(242, 244, 246, 0.80);
  max-width: 70ch;
  margin-inline: auto;
}

.lightbox__count {
  margin-top: var(--space-3);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tracking-wide);
  color: rgba(242, 244, 246, 0.55);
}

/* On a phone the side arrows would squeeze the image, so they move below. */
@media (max-width: 720px) {
  .lightbox__panel { grid-template-columns: 1fr; }
  .lightbox__nav { position: absolute; bottom: calc(var(--space-12) * -1); }
  .lightbox__nav--prev { left: 25%; }
  .lightbox__nav--next { right: 25%; }
  .lightbox__close { top: calc(var(--space-12) * -1); right: var(--space-2); }
  .lightbox__img, .lightbox__video, .lightbox__media { max-height: 58vh; }
}

/* Blog category filter reuses the gallery filter chips. */
.blog-filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-8);
}

.blog-filter:empty { display: none; }

/* ==========================================================================
   INDUSTRIES SECTION

   The supplied industries.gif runs full-bleed behind this section with a
   white wash over it, the same treatment as the hero: the visual stays sharp,
   the page stays white, and nothing is buried under a dark scrim.
   ========================================================================== */

.industries {
  position: relative;
  /* Extra height at the top and bottom so the background animation is on
     screen by itself for a moment before the cards begin arriving, and again
     once they are past. Without it the section reads as a card grid that
     happens to have a picture behind it. */
  padding-block: clamp(4rem, 3rem + 5vw, 8rem);
  background: var(--color-surface);
  overflow: hidden;
  isolation: isolate;
}

.industries__bg.media--background {
  /* Slightly oversized so the edges never show while it settles. */
  inset: -4% -2%;
  z-index: 0;
}

.industries__bg .media-asset,
.industries__bg .media-anim__poster,
.industries__bg .media-anim__motion {
  object-fit: cover;
  object-position: center 40%;
}

/* The wash. Heavier at the top and bottom, lighter through the middle where
   the animation is worth seeing between the cards. */
.industries__wash {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(to bottom,
      var(--color-surface) 0%,
      rgba(247, 249, 251, 0.88) 10%,
      rgba(247, 249, 251, 0.60) 38%,
      rgba(247, 249, 251, 0.66) 72%,
      var(--color-surface) 100%),
    linear-gradient(to right,
      rgba(247, 249, 251, 0.40) 0%,
      rgba(247, 249, 251, 0.08) 50%,
      rgba(247, 249, 251, 0.40) 100%);
}

.industries__inner { position: relative; z-index: 2; }

/* ==========================================================================
   INDUSTRY CARD

   Picture box on top, icon badge overlapping the seam, copy below. The badge
   sitting across the join is what stops it reading as a plain stock card.
   ========================================================================== */

.industry-card {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
  transition:
    transform var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out);
}

.industry-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
  border-color: var(--color-border-strong);
}

/* The red rule along the top, growing on hover. */
.industry-card::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 46px;
  height: 3px;
  z-index: 4;
  background: var(--grad-accent);
  border-radius: 0 0 2px 0;
  transition: width var(--dur-base) var(--ease-out);
}

.industry-card:hover::before { width: 100%; border-radius: 0; }

/* ---- Picture box ------------------------------------------------------- */

.industry-card__media {
  position: relative;
  /* Taller than a 16:10 strip. The picture is the point of these cards, so it
     gets the room; the copy below is three lines either way. */
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}

/* A slow zoom on hover, on whichever slide is showing. */
.industry-card:hover .slideshow__slide.is-active { transform: scale(1.06); }

/* With no picture the box holds the icon tile and can be shorter. */
.industry-card__media--icon { aspect-ratio: 16 / 8; }
.industry-card__media--icon .icon-tile { min-height: 0; border-bottom: none; }
.industry-card__media--icon .icon-tile__mark { width: 72px; height: 72px; }
.industry-card__media--icon .icon-tile__mark svg { width: 36px; height: 36px; }

/* ---- Body -------------------------------------------------------------- */

.industry-card__body {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-5);
  flex: 1;
}

/* The badge straddles the seam between the picture and the copy. */
.industry-card__badge {
  position: absolute;
  top: calc(var(--space-6) * -1);
  left: var(--space-5);
  z-index: 3;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-md);
  background: #fff;
  border: 1px solid var(--color-border);
  color: var(--color-primary);
  box-shadow: var(--shadow-md);
  transition:
    transform var(--dur-base) var(--ease-metal),
    color var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out);
}

.industry-card__badge svg { width: 24px; height: 24px; }

.industry-card:hover .industry-card__badge {
  transform: translateY(-3px) scale(1.05);
  color: var(--color-accent);
  border-color: var(--accent-200);
}

/* A card with no picture has no seam to straddle, so the badge sits inline. */
.industry-card__media--icon + .industry-card__body { padding-top: var(--space-5); }
.industry-card__media--icon + .industry-card__body .industry-card__badge {
  position: static;
  margin-bottom: var(--space-2);
}

.industry-card__media + .industry-card__body { padding-top: var(--space-8); }

.industry-card__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
}

.industry-card__title a { color: inherit; text-decoration: none; }

/* Whole card clickable, while the anchor keeps the focus ring. */
.industry-card__title a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
}

.industry-card__text {
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--color-muted-foreground);
}

.industry-card__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: auto;
  padding-top: var(--space-4);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--color-primary);
}

.industry-card:hover .industry-card__link { gap: var(--space-3); }

/* ==========================================================================
   SLIDESHOW

   Slides are stacked and cross-faded by opacity. Opacity and transform are
   the only two properties a browser can animate without recalculating layout,
   which is what keeps this smooth next to a scroll-driven canvas.
   ========================================================================== */

.slideshow {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.slideshow__slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.02);
  transition:
    opacity var(--slide-fade, 1.1s) var(--ease-in-out),
    transform var(--dur-slow) var(--ease-out);
  will-change: opacity;
}

.slideshow__slide.is-active { opacity: 1; transform: scale(1); }

/* Under reduced motion only the first slide is shown, held still. */
.slideshow[data-slideshow-static] .slideshow__slide { transition: none; }

/* A quiet count, so it is obvious there is more than one picture. */
.slideshow__count {
  position: absolute;
  right: var(--space-3);
  bottom: var(--space-3);
  z-index: 2;
  display: grid;
  place-items: center;
  min-width: 22px;
  height: 22px;
  padding-inline: 6px;
  border-radius: var(--radius-pill);
  background: rgba(4, 20, 47, 0.62);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  .slideshow__slide { transition: none; }
  .industry-card:hover .slideshow__slide.is-active { transform: none; }
}


/* ==========================================================================
   CENTRE-OUT REVEAL

   Cards arrive one after another, starting from the middle of the grid.
   motion.js measures each card's real position and writes --reveal-order, so
   the sequence follows the layout rather than the markup and still reads
   correctly when four columns become two, or one on a phone.
   ========================================================================== */

.reveal-centre {
  opacity: 0;
  /* Rising and scaling from slightly small reads as arriving, where a plain
     fade reads as loading. */
  transform: translateY(34px) scale(0.94);
  transition:
    opacity 620ms var(--ease-out),
    transform 720ms var(--ease-metal);
  transition-delay: calc(var(--reveal-order, 0) * 110ms);
  will-change: opacity, transform;
}

.reveal-centre.is-in { opacity: 1; transform: none; }

.no-js .reveal-centre { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal-centre {
    opacity: 1;
    transform: none;
    transition: none;
    transition-delay: 0s;
  }
}

/* On a phone the cards are a single column, so the stagger is shortened:
   110ms each over eight cards would leave the last one nearly a second
   behind the scroll. */
@media (max-width: 640px) {
  .reveal-centre { transition-delay: calc(var(--reveal-order, 0) * 55ms); }
}

/* ==========================================================================
   ABOUT - THE DATED TIMELINE

   A sticky year on the left, a filling rail down the middle and one card per
   milestone. The rail fill and the year are written by about.js from scroll
   position; everything else here is static.
   ========================================================================== */

.timeline {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  margin-top: var(--space-10);
}

/* ---- The sticky year --------------------------------------------------- */

.timeline__aside { display: none; }

.timeline__aside-inner {
  position: sticky;
  /* Clears the navbar, which is fixed. */
  top: calc(var(--navbar-h) + var(--space-8));
}

.timeline__aside-label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--color-muted-foreground);
}

.timeline__aside-year {
  font-family: var(--font-mono);
  font-size: clamp(3rem, 2rem + 3.4vw, 5rem);
  font-weight: var(--weight-bold);
  line-height: 1;
  letter-spacing: var(--tracking-tight);
  color: var(--color-primary);
  margin-block: var(--space-3) var(--space-2);
  font-variant-numeric: tabular-nums;
}

.timeline__aside-count {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-muted-foreground);
}

/* ---- Track and rail ---------------------------------------------------- */

.timeline__track { position: relative; }

/* The unfilled rail. Sits under the markers, which is why the list is given
   the left padding rather than a margin. */
.timeline__rail {
  position: absolute;
  left: 13px;
  top: var(--space-2);
  bottom: var(--space-2);
  width: 2px;
  background: var(--color-border);
  border-radius: var(--radius-pill);
  overflow: hidden;
}

.timeline__rail-fill {
  display: block;
  width: 100%;
  height: 0;
  background: var(--grad-accent);
  border-radius: var(--radius-pill);
  transition: height var(--dur-fast) linear;
}

.timeline__list {
  display: grid;
  gap: var(--space-10);
}

/* ---- One milestone ----------------------------------------------------- */

.timeline__item {
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: var(--space-5);
  align-items: start;
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}

.timeline__item.is-in { opacity: 1; transform: none; }

.timeline__marker {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  /* Nudged down so the dot lines up with the first line of the year. */
  margin-top: var(--space-2);
}

.timeline__dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-background);
  border: 2px solid var(--color-border-strong);
  transition:
    background var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-metal);
}

.timeline__item.is-active .timeline__dot {
  background: var(--color-accent);
  border-color: var(--color-accent);
  transform: scale(1.25);
  box-shadow: 0 0 0 5px rgba(51, 140, 242, 0.20);
}

.timeline__body { min-width: 0; }

.timeline__year {
  font-family: var(--font-mono);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-wide);
  color: var(--color-muted-foreground);
  margin-bottom: var(--space-3);
  font-variant-numeric: tabular-nums;
  transition: color var(--dur-base) var(--ease-out);
}

.timeline__item.is-active .timeline__year { color: var(--color-accent); }

.timeline__card {
  position: relative;
  padding: var(--space-6);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xs);
  transition:
    border-color var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
}

.timeline__item.is-active .timeline__card {
  border-color: var(--accent-200);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.timeline__step {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  color: var(--color-muted-foreground);
  margin-bottom: var(--space-2);
}

.timeline__title {
  font-size: var(--text-xl);
  margin-bottom: var(--space-3);
}

.timeline__text {
  color: var(--color-muted-foreground);
  max-width: 62ch;
}

.timeline__media {
  margin-top: var(--space-5);
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--color-border);
}

.timeline__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

/* ---- From tablet up: the year moves out to its own sticky column -------- */

@media (min-width: 900px) {
  .timeline {
    grid-template-columns: minmax(180px, 240px) 1fr;
    gap: clamp(var(--space-8), 4vw, var(--space-16));
  }

  .timeline__aside { display: block; }

  /* The per-entry year is now redundant next to the big sticky one, but it
     stays in the markup for narrow screens and for anyone printing. */
  .timeline__year { font-size: var(--text-lg); }

  .timeline__item { grid-template-columns: 28px 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .timeline__item { opacity: 1; transform: none; transition: none; }
  .timeline__rail-fill { transition: none; }
}

/* ==========================================================================
   INDUSTRIES - THE 3D STAGE AND THE PORTAL

   Driven by industries-3d.js. Everything here is inert until that file adds
   `industries--stage`, so the section still reads correctly with no
   JavaScript, no GSAP, or reduced motion switched on.
   ========================================================================== */

.industries__stage { position: relative; }

/* While the conveyor runs, the section is trimmed so it fits on the screen:
   pinning something taller than the viewport would hide its own bottom, which
   is where the opening is. */
.industries--conveyor { padding-block: clamp(2rem, 4vh, 3rem); }

/* In conveyor mode the stage's own height is set by the script, measured from
   one row of cards plus room for the opening. The block padding would be
   added on top of that and push the section past the height of the screen,
   which is the one thing pinning cannot survive. */
.industries--conveyor .industries__stage { padding-block: 0; }

.industries__grid--placed {
  /* The cards are positioned by industries-3d.js against the slots this grid
     laid out. Display is dropped so the now-absolute cards do not also leave
     empty grid tracks behind them. */
  display: block;
  position: relative;
  height: 100%;
}

.industries--stage .industries__stage {
  /* The vanishing point, and the clip.

     Perspective and `overflow: hidden` sit on the same element on purpose: a
     card arriving from above is cut off at the top edge of this box instead
     of sliding across the heading. Clipping here rather than on the section
     also keeps the heading and the background untouched.

     `overflow` flattens the element it is set on, never its descendants, so
     the grid inside still holds its own 3D space. */
  perspective: 1500px;
  perspective-origin: 50% 30%;
  overflow: hidden;
  /* Room above the first row for a card to arrive into, and room below the
     last for the opening to sit in. */
  padding-block: clamp(1.5rem, 4vh, 3.5rem) clamp(5rem, 12vh, 9rem);
}

.industries--stage [data-industries] {
  transform-style: preserve-3d;
}

.industries--stage .industry-card {
  transform-style: preserve-3d;
  /* Rotation happens about the card's own middle, so a tipping card does not
     also drift sideways. */
  transform-origin: 50% 50%;
  will-change: transform, opacity;
  backface-visibility: hidden;
}

/* With reduced motion or no GSAP the stage is dropped entirely: a perspective
   with nothing moving in it only costs compositing, and the clip would hide
   content that is not going to animate into view. */
.industries--static .industries__stage {
  perspective: none;
  overflow: visible;
  padding-block: 0;
}

.industries--static .industry-card {
  will-change: auto;
  transform: none;
  opacity: 1;
}

/* ---- The hole the cards fall through ----------------------------------- */

.industries__portal {
  position: absolute;
  left: 50%;
  bottom: clamp(1rem, 3vh, 2.5rem);
  width: clamp(220px, 28vw, 420px);
  height: clamp(62px, 7.5vw, 116px);
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 0;
  opacity: 0;
}

.industries__portal > * {
  position: absolute;
  inset: 0;
  border-radius: 50%;
}

/* The opening: dark in the middle, so a card shrinking into it reads as
   going somewhere rather than just getting smaller. */
.industries__portal-mouth {
  background:
    radial-gradient(ellipse at 50% 50%,
      rgba(4, 20, 47, 0.92) 0%,
      rgba(4, 20, 47, 0.74) 38%,
      rgba(11, 62, 151, 0.26) 62%,
      rgba(11, 62, 151, 0) 78%);
  box-shadow: inset 0 6px 22px rgba(4, 20, 47, 0.55);
}

/* A highlight travelling around the rim.

   The angle of the gradient is animated, NOT the element. Rotating the
   element itself turns a wide, flat ellipse into a tall one, which swings a
   blue arc out across the cards every quarter turn. Animating the angle keeps
   the ellipse exactly where it is and moves only the light.

   `@property` is what makes an angle animatable at all; without it the
   custom property is a plain string and the highlight simply sits still,
   which is a perfectly acceptable way for this to degrade. */
@property --portal-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

.industries__portal-ring {
  --portal-angle: 0deg;
  background: conic-gradient(
    from var(--portal-angle),
    rgba(51, 140, 242, 0) 0deg,
    rgba(51, 140, 242, 0.42) 58deg,
    rgba(169, 208, 255, 0.72) 96deg,
    rgba(51, 140, 242, 0.42) 134deg,
    rgba(51, 140, 242, 0) 200deg,
    rgba(51, 140, 242, 0) 360deg);
  /* Leaves only a rim: the middle is masked out so the mouth shows through. */
  -webkit-mask: radial-gradient(ellipse at 50% 50%, transparent 62%, #000 70%, #000 100%);
  mask: radial-gradient(ellipse at 50% 50%, transparent 62%, #000 70%, #000 100%);
  animation: portal-sweep 7s linear infinite;
}

/* Light spilling out of the opening onto the floor. */
.industries__portal-glow {
  background: radial-gradient(ellipse at 50% 50%,
    rgba(107, 178, 255, 0.36) 0%,
    rgba(107, 178, 255, 0.12) 45%,
    rgba(107, 178, 255, 0) 72%);
  filter: blur(10px);
  transform: scale(1.5);
}

@keyframes portal-sweep {
  to { --portal-angle: 360deg; }
}

@media (prefers-reduced-motion: reduce) {
  .industries__portal { display: none; }
  .industries__portal-ring { animation: none; }

  .industries--stage .industries__stage {
    perspective: none;
    overflow: visible;
    padding-block: 0;
  }

  .industries--stage .industry-card {
    transform: none;
    opacity: 1;
    will-change: auto;
  }
}

/* ==========================================================================
   PHONE: CALL-TO-ACTION BUTTONS
   On a phone a pair of buttons wrapped onto two lines at their natural
   widths, so they hugged the left edge at two different lengths and the
   section looked lopsided. Below 480px every group of page actions becomes a
   stack of full-width buttons: centred, equal, and an easy thumb target.
   ========================================================================== */

@media (max-width: 479.98px) {
  .hero__actions,
  .cta-band__actions,
  .journey__foot,
  .section-foot,
  main .cluster:has(> .btn),
  main .text-center:has(> .btn),
  .footer__strip-actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
  }

  .hero__actions > .btn,
  .cta-band__actions > .btn,
  .journey__foot > .btn,
  .section-foot > .btn,
  main .cluster > .btn,
  main .text-center > .btn,
  main .stack--lg > .btn,
  .footer__strip-actions > .btn,
  .catalog-search > .btn,
  .enquiry-form__foot > .btn {
    width: 100%;
    margin: 0;
  }
}

/* Two form buttons side by side share the row equally on a phone, rather
   than sitting at their natural widths against the left edge. */
@media (max-width: 479.98px) {
  .calc__actions { display: flex; gap: var(--space-3); }
  .calc__actions > .btn { flex: 1 1 0; }
}

/* On a phone the certificate seal stands above the text on its own, so it is
   centred rather than left hanging against the card's edge. */
@media (max-width: 719.98px) {
  .iso-feature__seal { margin-inline: auto; }
}

/* ==========================================================================
   ENTRANCES
   The page banner was the one part of every inner page that simply appeared.
   Its breadcrumb, eyebrow, title and lede now rise in one after another, the
   same movement the sections below use as they scroll in. It waits while the
   opening animation is on screen, so it plays when it can actually be seen.

   The short rule before every eyebrow draws itself in as its section
   arrives, which ties the label to the heading it introduces.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  .page-header__inner > * {
    animation: header-rise 720ms var(--ease-out) both;
  }

  .page-header__inner > :nth-child(2) { animation-delay: 90ms; }
  .page-header__inner > :nth-child(3) { animation-delay: 180ms; }
  .page-header__inner > :nth-child(4) { animation-delay: 270ms; }
  .page-header__inner > :nth-child(n+5) { animation-delay: 360ms; }

  html.intro-on .page-header__inner > * { animation-play-state: paused; }

  .page-header .eyebrow::before {
    transform-origin: left center;
    animation: rule-draw 800ms var(--ease-metal) 260ms both;
  }

  html.intro-on .page-header .eyebrow::before { animation-play-state: paused; }

  .reveal .eyebrow::before,
  .reveal.eyebrow::before {
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 760ms var(--ease-metal) 140ms;
  }

  .reveal.is-visible .eyebrow::before,
  .reveal.is-visible.eyebrow::before,
  .no-js .reveal .eyebrow::before { transform: none; }
}

@keyframes header-rise {
  from { opacity: 0; transform: translate3d(0, 18px, 0); }
}

@keyframes rule-draw {
  from { transform: scaleX(0); }
}

/* ---- Email addresses, labelled by desk ----------------------------------
   Two addresses side by side read as a choice with no guidance; a small
   label says which one to write to. */
.footer__email { display: block; }
.footer__email + .footer__email { margin-top: var(--space-2); }

.footer__email-label,
.contact-card__label {
  display: block;
  font-size: 0.6875rem;
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  opacity: 0.7;
}

.contact-card__label + a { display: inline-block; margin-bottom: var(--space-2); }

/* ==========================================================================
   PRODUCT RANGE, FAMILY BY FAMILY
   The unfiltered catalogue, grouped under each category's heading.
   ========================================================================== */

.range-groups { display: flex; flex-direction: column; gap: clamp(var(--space-10), 5vw, var(--space-16)); }

/* Chips that jump to a family, with how many products each holds. */
.range-jump {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding-bottom: var(--space-2);
}

.range-jump__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  background: var(--color-surface-raised);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-foreground);
  text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}

.range-jump__link:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}

.range-jump__count {
  min-width: 24px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--blue-50);
  color: var(--color-accent);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.range-group { scroll-margin-top: calc(var(--navbar-h) + var(--space-6)); }

.range-group__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-6);
  padding-top: var(--space-6);
  margin-bottom: var(--space-6);
  border-top: 1px solid var(--color-border);
}

.range-group__intro { display: flex; gap: var(--space-5); align-items: flex-start; min-width: 0; }

.range-group__index {
  flex: none;
  margin: 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--color-accent);
  padding-top: 0.45em;
}

.range-group__title {
  margin: 0;
  font-size: clamp(var(--text-2xl), 1.2rem + 1.2vw, var(--text-3xl));
  letter-spacing: -0.02em;
}

.range-group__text {
  margin: var(--space-2) 0 0;
  max-width: 62ch;
  color: var(--color-muted-foreground);
  line-height: var(--leading-relaxed);
}

.range-group__meta { flex: none; display: flex; align-items: center; gap: var(--space-4); }

.range-group__count {
  font-size: var(--text-sm);
  color: var(--color-muted-foreground);
  white-space: nowrap;
}

@media (max-width: 719.98px) {
  .range-group__head { flex-direction: column; align-items: stretch; gap: var(--space-4); }
  .range-group__intro { gap: var(--space-3); }
  .range-group__meta { justify-content: space-between; }
  .range-jump { flex-wrap: nowrap; overflow-x: auto; margin-inline: calc(var(--gutter) * -1); padding-inline: var(--gutter); scrollbar-width: none; }
  .range-jump::-webkit-scrollbar { display: none; }
  .range-jump__link { flex: none; }
}

/* Two phone numbers one above the other were too close to tap apart on a
   phone. A few pixels of padding makes each a proper target. */
.footer__contact-item a { display: inline-block; padding-block: 5px; }

/* ==========================================================================
   CATALOGUE: products page, category pages, product pages
   Built by src/services/catalogPage.js. Plain on purpose: the name once, a
   picture, the company text, and the list of every other product beside it.
   ========================================================================== */

/* ---- Cards ----------------------------------------------------------------- */

.cat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-6);
}

.cat-grid--in { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }

.cat-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface-raised, #fff);
  overflow: hidden;
  color: var(--color-foreground);
  text-decoration: none;
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out);
}

.cat-card:hover {
  transform: translateY(-4px);
  border-color: var(--blue-200, #b4cafa);
  box-shadow: var(--shadow-lg);
}

.cat-card__media {
  display: block;
  aspect-ratio: 4 / 3;
  background: var(--color-surface);
  overflow: hidden;
}

.cat-card__media > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}

.cat-card:hover .cat-card__media > img { transform: scale(1.05); }

.cat-blank {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  background: linear-gradient(145deg, var(--color-surface), var(--blue-50));
}

.cat-blank img { width: 72px; height: 72px; opacity: 0.35; filter: grayscale(0.3); }

.cat-card__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-4) var(--space-6);
  text-align: center;
  flex: 1;
}

.cat-card__name {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
}

.cat-card__cta {
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 9px 18px;
  border-radius: var(--radius-pill);
  background: var(--grad-blue, var(--color-primary));
  color: #fff;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.cat-card__cta svg { transition: transform var(--dur-fast) var(--ease-out); }
.cat-card:hover .cat-card__cta svg { transform: translateX(3px); }

.cat-empty {
  padding: var(--space-6);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
  color: var(--color-muted-foreground);
  text-align: center;
}

/* ---- Products page toolbar ------------------------------------------------- */

.cat-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.cat-toolbar__count { margin: 0; color: var(--color-muted-foreground); }
.cat-toolbar__count a { margin-left: var(--space-3); color: var(--color-accent); }

.cat-search { display: flex; gap: var(--space-2); flex: 0 1 420px; }
.cat-search .input { flex: 1; min-width: 0; }

/* ---- Category and product pages ------------------------------------------- */

.cat-head {
  padding-top: calc(var(--navbar-h) + var(--space-10));
  padding-bottom: var(--space-8);
  background: linear-gradient(180deg, var(--blue-50), var(--color-background));
  border-bottom: 1px solid var(--color-border);
}

.cat-crumbs ol { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0 0 var(--space-3); padding: 0; list-style: none; font-size: var(--text-sm); }
.cat-crumbs li + li::before { content: "/"; margin-right: var(--space-2); color: var(--color-muted-foreground); }
.cat-crumbs a { color: var(--color-muted-foreground); text-decoration: none; }
.cat-crumbs a:hover { color: var(--color-accent); }

.cat-head__title {
  margin: 0;
  font-size: clamp(var(--text-2xl), 1.4rem + 1.6vw, var(--text-4xl));
  letter-spacing: -0.02em;
}

.cat-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: var(--space-10);
  padding-block: var(--space-10) var(--space-16);
  align-items: start;
}

.cat-main { min-width: 0; display: flex; flex-direction: column; gap: var(--space-8); }

.cat-figure {
  margin: 0;
  max-width: 640px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface);
  aspect-ratio: 4 / 3;
}

.cat-figure > img { width: 100%; height: 100%; object-fit: cover; }
.cat-figure > .cat-blank img { width: 120px; height: 120px; }

/* The text pasted in the admin panel. */
.cat-content { max-width: 78ch; }
.cat-content h2 { margin: var(--space-8) 0 var(--space-3); font-size: var(--text-2xl); }
.cat-content h3 { margin: var(--space-6) 0 var(--space-3); font-size: var(--text-xl); }
.cat-content h4 { margin: var(--space-5) 0 var(--space-2); font-size: var(--text-lg); }
.cat-content > :first-child { margin-top: 0; }
.cat-content p, .cat-content li { line-height: var(--leading-relaxed); }
.cat-content img { max-width: 100%; height: auto; border-radius: var(--radius-md); }

.cat-table {
  margin: var(--space-5) 0;
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.cat-table table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.cat-table th, .cat-table td { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--color-border); text-align: left; vertical-align: top; }
.cat-table th, .cat-table thead td { background: var(--blue-50); color: var(--color-primary); font-weight: var(--weight-bold); }
.cat-table tr:last-child td { border-bottom: none; }
.cat-table tbody tr:nth-child(even) td { background: var(--color-surface); }
.cat-table td p, .cat-table th p { margin: 0; }

/* ---- The link list beside ------------------------------------------------ */

.cat-side {
  position: sticky;
  top: calc(var(--navbar-h) + var(--space-4));
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.cat-side__box {
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface-raised, #fff);
}

.cat-side__title {
  margin: 0 0 var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: 2px solid var(--color-accent);
  font-size: var(--text-lg);
}

.cat-side__list { margin: 0; padding: 0; list-style: none; max-height: 420px; overflow-y: auto; }

.cat-side__list a {
  position: relative;
  display: block;
  padding: 7px var(--space-2) 7px var(--space-5);
  border-radius: var(--radius-sm);
  color: var(--color-foreground);
  font-size: var(--text-sm);
  text-decoration: none;
}

.cat-side__list a::before {
  content: "";
  position: absolute;
  left: 6px;
  top: 50%;
  width: 5px;
  height: 5px;
  border-top: 1.5px solid currentColor;
  border-right: 1.5px solid currentColor;
  transform: translateY(-50%) rotate(45deg);
  opacity: 0.5;
}

.cat-side__list a:hover { background: var(--blue-50); color: var(--color-accent); }
.cat-side__list a.is-current { background: var(--blue-50); color: var(--color-accent); font-weight: var(--weight-semibold); }

.cat-side__quote { background: linear-gradient(160deg, var(--blue-50), #fff); }
.cat-side__quote p { font-size: var(--text-sm); color: var(--color-muted-foreground); margin: 0 0 var(--space-4); }
.cat-side__quote .btn { width: 100%; margin-top: var(--space-2); }

@media (max-width: 959.98px) {
  .cat-layout { grid-template-columns: 1fr; gap: var(--space-8); }
  .cat-side { position: static; }
}

@media (max-width: 479.98px) {
  .cat-grid, .cat-grid--in { grid-template-columns: 1fr 1fr; gap: var(--space-3); }
  .cat-card__body { padding: var(--space-3) var(--space-2) var(--space-4); }
  .cat-card__name { font-size: var(--text-sm); }
  .cat-card__cta { padding: 6px 12px; font-size: 0.75rem; }
  .cat-search { flex-basis: 100%; }
}

/* ---- Every range with its products, under the range cards ---------------- */
.cat-range { margin-top: var(--space-16); }
.cat-range__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-5); padding-bottom: var(--space-3); border-bottom: 2px solid var(--color-accent); }
.cat-range__title { margin: 0; font-size: clamp(var(--text-xl), 1.1rem + 0.8vw, var(--text-2xl)); }
.cat-range__all { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--color-accent); text-decoration: none; white-space: nowrap; }

.cat-subhead { margin: var(--space-4) 0 0; font-size: var(--text-xl); }
