/* ==========================================================================
   DFR — Components
   Every rule below draws on tokens.css only. No new colours or scales.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  line-height: 1;
  padding: 15px var(--s-7);
  border-radius: var(--r-sm);
  border: 1.5px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur) var(--ease),
              color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              transform var(--dur-fast) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.btn .ms { font-size: 18px; margin-right: -2px; }
.btn:active { transform: translateY(1px); }

/* `white-space: nowrap` above keeps labels on one line, which is right almost
   everywhere — but the three longest ("See the full specification matrix" at
   326px, "See the fabrication capabilities" at 319px, "Inside the fabrication
   centre" at 300px) need a 366px viewport to fit, and pushed the page sideways
   below that. Let them wrap under 380px, which is clear of the 390px reference
   width so nothing at or above it changes. `line-height` has to come off 1 at
   the same time or two wrapped lines would collide. */
@media (max-width: 380px) {
  .btn {
    white-space: normal;
    text-align: center;
    line-height: 1.25;
    max-width: 100%;
    padding-left: var(--s-5);
    padding-right: var(--s-5);
  }
}

.btn--primary {
  background: var(--c-blue);
  color: #fff;
  box-shadow: 0 4px 14px rgba(0, 145, 206, .25);
}
.btn--primary:hover { background: var(--c-blue-hover); color: #fff; box-shadow: 0 6px 20px rgba(0, 145, 206, .34); }

.btn--outline {
  border-color: var(--c-line);
  color: var(--c-ink);
  background: #fff;
}
.btn--outline:hover { border-color: var(--c-blue); color: var(--c-blue); }

.btn--ghost {
  border-color: rgba(255, 255, 255, .55);
  color: #fff;
  background: transparent;
}
.btn--ghost:hover { background: #fff; color: var(--c-blue); border-color: #fff; }

.btn--white { background: #fff; color: var(--c-blue); }
.btn--white:hover { background: var(--c-tint-soft); color: var(--c-blue-hover); }

.btn--sm { padding: 11px var(--s-5); font-size: var(--t-2xs); }
.btn--block { width: 100%; }

/* Inline "read more" arrow link */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: var(--t-2xs);
  text-transform: uppercase;
  letter-spacing: 0.9px;
  color: var(--c-blue);
  line-height: 1;
}
.link-arrow .ms { font-size: 17px; transition: transform var(--dur) var(--ease); }
.link-arrow:hover .ms { transform: translateX(4px); }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--s-4); }

/* --------------------------------------------------------------------------
   2. Header · utility bar · navigation
   -------------------------------------------------------------------------- */
.utilitybar {
  background: var(--c-ink);
  color: rgba(255, 255, 255, .72);
  font-size: var(--t-2xs);
  line-height: 1;
}
.utilitybar__inner {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-7);
  height: 38px;
}
.utilitybar a {
  color: rgba(255, 255, 255, .78);
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}
.utilitybar a:hover { color: #fff; }
.utilitybar .ms { font-size: 16px; color: var(--c-blue); }
.utilitybar__tag {
  margin-right: auto;
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  font-size: var(--t-eyebrow);
  color: rgba(255, 255, 255, .6);
}
@media (max-width: 900px) { .utilitybar { display: none; } }

/* The z-index here MUST outrank .nav-scrim, and that is not obvious.
   `position: sticky` with a z-index makes this header its own stacking layer,
   so the mobile menu inside it cannot rise above the header's own number no
   matter what z-index the menu is given. The scrim is a sibling of the header,
   outside that layer. At the old value (--z-header, 100) the scrim's 199 beat
   the whole header, so on a phone the open menu was covered by the scrim: it
   looked hazy — the scrim is translucent grey with a 2px blur — and every tap
   landed on the scrim instead of the link. The menu was unusable on mobile.
   Keep this above --z-menu, or that bug returns. */
.header {
  position: sticky;
  top: 0;
  z-index: calc(var(--z-menu) + 1);
  background: #fff;
  border-bottom: 1px solid var(--c-line);
  transition: box-shadow var(--dur) var(--ease);
}
.header.is-stuck { box-shadow: var(--sh-header); border-bottom-color: transparent; }

.header__inner {
  display: flex;
  align-items: center;
  gap: var(--s-8);
  height: var(--header-h);
}
.header__logo { flex: none; display: block; }
.header__logo img { height: 44px; width: auto; }

.nav { margin-left: auto; }
.nav__list { display: flex; align-items: center; gap: var(--s-1); }
.nav__item { position: relative; }

.nav__link {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: 0.9375rem;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  color: var(--c-ink);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-sm);
  line-height: 1;
  position: relative;
  transition: color var(--dur-fast) var(--ease);
}
.nav__link .ms { font-size: 18px; opacity: .6; transition: transform var(--dur) var(--ease); }
.nav__link:hover { color: var(--c-blue); }
.nav__link::after {
  content: '';
  position: absolute;
  left: var(--s-4); right: var(--s-4); bottom: -1px;
  height: 3px;
  background: var(--c-blue);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.nav__item:hover > .nav__link::after,
.nav__link[aria-current="page"]::after,
.nav__link.is-active::after { transform: scaleX(1); }
.nav__link[aria-current="page"], .nav__link.is-active { color: var(--c-blue); }
.nav__item:hover > .nav__link .ms { transform: rotate(180deg); }

/* Dropdown (mega) panel */
.nav__panel {
  position: absolute;
  top: calc(100% + 1px);
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  min-width: 640px;
  background: #fff;
  border: 1px solid var(--c-line);
  border-top: 3px solid var(--c-blue);
  border-radius: 0 0 var(--r) var(--r);
  box-shadow: var(--sh-3);
  padding: var(--s-6);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease-out), visibility var(--dur);
  z-index: var(--z-menu);
}
.nav__item:hover > .nav__panel,
.nav__item:focus-within > .nav__panel {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}
.nav__panel-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2); }
.nav__panel-link {
  display: flex;
  gap: var(--s-4);
  padding: var(--s-4);
  border-radius: var(--r-sm);
  transition: background var(--dur-fast) var(--ease);
}
.nav__panel-link:hover { background: var(--c-surface-alt); }
.nav__panel-link .ms {
  font-size: 22px;
  color: var(--c-blue);
  margin-top: 2px;
}
.nav__panel-link h4 {
  font-size: var(--t-h5);
  color: var(--c-ink);
  margin-bottom: 3px;
  letter-spacing: .2px;
  transition: color var(--dur-fast) var(--ease);
}
.nav__panel-link:hover h4 { color: var(--c-blue); }
.nav__panel-link p { font-size: var(--t-2xs); line-height: 1.4; color: var(--c-body); }
.nav__panel-foot {
  margin-top: var(--s-5);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-line-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
}
.nav__panel-foot p { font-size: var(--t-2xs); color: var(--c-body); }

/* Mobile toggle + drawer */
.nav__toggle {
  display: none;
  margin-left: auto;
  width: 44px; height: 44px;
  align-items: center; justify-content: center;
  border-radius: var(--r-sm);
  color: var(--c-ink);
}
.nav__toggle .ms { font-size: 30px; }
.nav__toggle:hover { background: var(--c-surface-alt); color: var(--c-blue); }

@media (max-width: 1080px) {
  .header__inner { gap: var(--s-5); }
  .nav__link { font-size: 0.875rem; padding: var(--s-3) var(--s-3); }
  .btn--sm { padding: 10px var(--s-4); }
}
@media (max-width: 980px) {
  :root { --header-h: var(--header-h-sm); }
  .nav__toggle { display: flex; }
  .header__logo img { height: 38px; }

  .nav {
    position: fixed;
    inset: var(--header-h-sm) 0 0 auto;
    width: min(400px, 88vw);
    background: #fff;
    border-left: 1px solid var(--c-line);
    box-shadow: var(--sh-3);
    padding: var(--s-6) var(--s-6) var(--s-11);
    overflow-y: auto;
    transform: translateX(100%);
    transition: transform var(--dur-slow) var(--ease-out);
    margin-left: 0;
    z-index: var(--z-menu);
  }
  .nav.is-open { transform: translateX(0); }
  .nav__list { flex-direction: column; align-items: stretch; gap: 0; }
  .nav__item { border-bottom: 1px solid var(--c-line-soft); }
  .nav__link {
    padding: var(--s-5) var(--s-1);
    font-size: 1.0625rem;
    justify-content: space-between;
    width: 100%;
  }
  .nav__link::after { display: none; }
  .nav__link .ms { opacity: 1; }

  .nav__panel {
    position: static;
    transform: none;
    min-width: 0;
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    border: 0;
    box-shadow: none;
    padding: 0 0 var(--s-4) var(--s-3);
    border-left: 2px solid var(--c-tint);
    margin-left: var(--s-1);
    display: none;
    border-radius: 0;
  }
  /* These three selectors exist only to beat the desktop rule higher up:
       .nav__item:hover > .nav__panel,
       .nav__item:focus-within > .nav__panel { transform: translateX(-50%) ... }
     which centres the dropdown under its parent on a wide screen. A media
     query adds NO specificity, so that rule (0,3,0) outranks the plain
     `.nav__panel { transform: none }` reset above (0,1,0) and wins even here.
     On a phone, tapping "Products" or "Industries" focuses the item,
     :focus-within matched, and the submenu slid left by half its own width —
     145px on a 390px screen — so it hung off the left edge of the drawer and
     was clipped. Repeating the selectors at equal specificity makes the reset
     stick. If the desktop rule is ever changed, change this one with it. */
  .nav__item:hover > .nav__panel,
  .nav__item:focus-within > .nav__panel,
  .nav__item.is-expanded > .nav__panel {
    transform: none;
  }
  .nav__item.is-expanded > .nav__panel { display: block; }
  .nav__item.is-expanded > .nav__link .ms { transform: rotate(180deg); }
  .nav__panel-grid { grid-template-columns: 1fr; gap: 0; }
  .nav__panel-link { padding: var(--s-3) var(--s-3); }
  .nav__panel-link p { display: none; }
  .nav__panel-foot { display: none; }
}

.nav-scrim {
  position: fixed;
  inset: 0;
  background: rgba(62, 70, 76, .45);
  backdrop-filter: blur(2px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur) var(--ease), visibility var(--dur);
  z-index: calc(var(--z-menu) - 1);
}
.nav-scrim.is-open { opacity: 1; visibility: visible; }
body.nav-locked { overflow: hidden; }

/* --------------------------------------------------------------------------
   3. Home hero (recreates the brochure cover)
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  /* Two layers. The diagonal is the cover's own ground, unchanged. The
     vertical one over it resolves the hero to pure white at its foot.
     Needed since the blue band was removed (10 Aug 2026): the band used to
     cover the hero's bottom edge, and without it the diagonal's tinted end
     met the white page below in a horizontal step — the same class of defect
     as the vertical seam in ROADMAP 2.7, and fixed on the same principle of
     ending on the page's real colour rather than near it. */
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0) 70%, #fff 100%),
    linear-gradient(150deg, #fff 0%, #F7FAFC 45%, var(--c-canvas) 100%);
  overflow: hidden;
  isolation: isolate;
}
.hero__media {
  position: absolute;
  inset: 0 0 0 42%;
  z-index: -1;
  /* The photo fades to TRANSPARENT on its left edge, so the page's own
     background shows through underneath.

     It used to be veiled with an opaque white overlay instead. That veil is
     solid white at its left end, but `.hero` behind it is a blue-tinted
     gradient running to #DDE3EA — so white met blue-grey in a hard vertical
     seam down the full height of the hero, worst in the lower half where the
     page colour has drifted furthest from white.

     A mask cannot mismatch: whatever the page is at that point is exactly
     what shows, at every viewport width, and it survives any later change to
     the hero's background. The stops below are the old veil's alphas
     inverted, so the blend reads as it always did — only the seam is gone.

     A second layer fades the photo's BOTTOM edge out as well. The blue band
     used to sit over it; with the band gone the photo would otherwise stop on
     a hard horizontal line across the page. The two layers are intersected,
     so the photo dissolves on both its left and lower edges. */
  -webkit-mask-image:
    linear-gradient(100deg, rgba(0,0,0,0) 0%, rgba(0,0,0,.08) 22%, rgba(0,0,0,.85) 58%, rgba(0,0,0,1) 78%),
    linear-gradient(180deg, rgba(0,0,0,1) 72%, rgba(0,0,0,0) 100%);
          mask-image:
    linear-gradient(100deg, rgba(0,0,0,0) 0%, rgba(0,0,0,.08) 22%, rgba(0,0,0,.85) 58%, rgba(0,0,0,1) 78%),
    linear-gradient(180deg, rgba(0,0,0,1) 72%, rgba(0,0,0,0) 100%);
  -webkit-mask-composite: source-in;
          mask-composite: intersect;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}
.hero__media img { width: 100%; height: 100%; object-fit: cover; object-position: 40% 50%; }

/* Fallback for anything that cannot mask: restore the old white veil rather
   than leaving a hard-edged rectangle. Keeps the pre-10-Aug-2026 rendering. */
@supports not ((-webkit-mask-image: linear-gradient(#000, #000)) or (mask-image: linear-gradient(#000, #000))) {
  .hero__media::after {
    content: '';
    position: absolute; inset: 0;
    background: linear-gradient(100deg, #fff 0%, rgba(255,255,255,.92) 22%, rgba(255,255,255,.15) 58%, rgba(255,255,255,0) 78%);
  }
}
.hero__inner {
  /* The old bottom value reserved room for the blue band that sat over the
     hero's foot. With the band removed it would leave a large empty gap, so
     it is now balanced against the top instead. */
  padding-block: clamp(64px, 7vw, 132px) clamp(76px, 8.5vw, 148px);
}
/* Constrain the text measure on the CHILDREN, not on .hero__inner itself.
   .hero__inner also carries .container, and a max-width here overrode the
   container's 1240px — leaving a 640px box that `margin-inline: auto` then
   centred in the viewport. The headline started up to 300px right of the
   header logo at desktop widths, which is why the hero read as centred while
   every other block on the page lined up. `.hero__sub` keeps its own
   narrower 30ch measure, declared below this rule so it still wins. */
.hero__inner > * { max-width: 640px; }
.hero__title {
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: var(--t-display);
  line-height: .92;
  letter-spacing: var(--ls-display);
  text-transform: uppercase;
  color: var(--c-ink);
}
.hero__title span { display: block; }
.hero__sub {
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.3125rem);
  line-height: 1.45;
  color: var(--c-body);
  max-width: 30ch;
}
.hero__actions { margin-top: var(--s-9); }

/* The blue wave band that used to close the cover — .hero__band, .hero__wave,
   .hero__marks, .hero__mark and .hero__tagline — was removed on 10 Aug 2026
   along with its rules. Its three product marks are covered by the product
   card grid further down the page, and its "Precision Woven / Performance
   Delivered" tagline still appears as the two pills in the footer. */

@media (max-width: 900px) {
  /* Below 900px the photo goes full-bleed behind the headline and is washed
     out for legibility, rather than sitting beside it. The desktop left-edge
     mask is switched off here — it would fade the wrong edge of a full-width
     photo — and the veil is restored explicitly, including `content`, since
     the desktop rule now only declares it inside an @supports fallback. */
  .hero__media {
    inset: 0;
    opacity: .5;
    -webkit-mask-image: none;
            mask-image: none;
  }
  .hero__media::after {
    content: '';
    position: absolute; inset: 0;
    /* Resolves to solid white at the foot. The blue band used to cover the
       photo's bottom edge here too; ending the veil short of full white
       would leave that edge showing as a faint line against the page. */
    background: linear-gradient(180deg, rgba(255,255,255,.94) 0%, rgba(255,255,255,.86) 55%, #fff 100%);
  }
}

/* --------------------------------------------------------------------------
   4. Page hero (interior pages) — title block left, image right
   -------------------------------------------------------------------------- */
.pagehero {
  background: linear-gradient(160deg, #fff 0%, #F7FAFC 100%);
  border-bottom: 1px solid var(--c-line);
  padding-block: clamp(40px, 5vw, 72px);
}
.pagehero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
  gap: clamp(var(--s-7), 4vw, var(--s-11));
  align-items: center;
}
.pagehero__title {
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: var(--t-h1);
  line-height: .9;
  letter-spacing: var(--ls-display);
  text-transform: uppercase;
  color: var(--c-ink);
}
.pagehero__title span { display: block; }
.pagehero__media {
  position: relative;
  border-radius: var(--r);
  overflow: hidden;
  box-shadow: var(--sh-2);
}
.pagehero__media img {
  width: 100%;
  height: clamp(240px, 26vw, 340px);
  object-fit: cover;
}
/* Frameless variant, for a cut-out with a transparent background rather than a
   photograph. No card: there are no background pixels to contain, so the machine
   sits on the page and blends into it.

   `contain`, not `cover` — the subject is portrait and the box is landscape, so
   `cover` would slice the top and bottom off the machine. The taller height is
   what stops a portrait subject rendering small inside a landscape box.

   This is a deliberate exception to 3.6, made on Rohan's instruction 10 Aug 2026
   for a cut-out specifically; it does not reopen that decision for photographs. */
.pagehero__media--bare {
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
}
.pagehero__media--bare img {
  height: clamp(280px, 32vw, 420px);
  object-fit: contain;
}

/* Ratio-locked variant, for a hero that is a composite of several photographs
   rather than a single one. `.pagehero__media img` pins the height, so between
   roughly 700px and 880px — where the hero column goes full width — the box
   becomes 3.30:1 and a centre crop keeps only 48% of the image height. On one
   photograph that is a tight crop; on a four-panel grid it slices every panel
   through the middle and cuts each machine in half. Locking the box to the
   image's own ratio leaves nothing to crop at any width.
   Used only by products.html. Single-photograph heroes keep the pinned height. */
@supports (aspect-ratio: 16 / 10) {
  .pagehero__media--fit img { height: auto; aspect-ratio: 16 / 10; }
}

.pagehero__stamp {
  position: absolute;
  top: var(--s-4); right: var(--s-5);
  text-align: right;
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: var(--t-h5);
  line-height: 1.05;
  color: var(--c-ink);
  text-transform: uppercase;
  letter-spacing: .3px;
  text-shadow: 0 1px 8px rgba(255,255,255,.85);
}
@media (max-width: 860px) {
  .pagehero__grid { grid-template-columns: minmax(0, 1fr); gap: var(--s-8); }
}

/* Breadcrumb */
.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--t-2xs);
  color: var(--c-muted);
  margin-bottom: var(--s-6);
}
.crumbs a { color: var(--c-muted); }
.crumbs a:hover { color: var(--c-blue); }
.crumbs .ms { font-size: 14px; opacity: .7; }
.crumbs [aria-current] { color: var(--c-ink); font-weight: var(--fw-med); }

/* Anchor sub-nav for long technical pages */
.subnav {
  position: sticky;
  top: var(--header-h);
  z-index: calc(var(--z-header) - 1);
  background: rgba(255, 255, 255, .94);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--c-line);
}
.subnav__list {
  display: flex;
  gap: var(--s-2);
  overflow-x: auto;
  scrollbar-width: none;
}
.subnav__list::-webkit-scrollbar { display: none; }
.subnav__list a {
  display: block;
  white-space: nowrap;
  padding: var(--s-5) var(--s-4);
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: var(--t-2xs);
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--c-body);
  border-bottom: 3px solid transparent;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.subnav__list a:hover { color: var(--c-blue); }
.subnav__list a.is-active { color: var(--c-blue); border-bottom-color: var(--c-blue); }

/* --------------------------------------------------------------------------
   5. Stat band — brand-blue gradient strip (brochure footer motif)
   -------------------------------------------------------------------------- */
.statband { background: var(--grad-blue); color: #fff; }
.statband__grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  padding-block: var(--s-7);
}
.statband__item {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding-inline: var(--s-5);
  border-right: 1px solid rgba(255, 255, 255, .3);
}
.statband__item:first-child { padding-left: 0; }
.statband__item:last-child { border-right: 0; padding-right: 0; }
.statband__item img { height: 44px; width: auto; flex: none; object-fit: contain; }
.statband__kicker {
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: var(--t-eyebrow);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--c-tint-soft);
  display: block;
}
.statband__value {
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: 1.625rem;
  line-height: .95;
  color: #fff;
  text-transform: uppercase;
}
.statband__value small { font-size: 0.875rem; font-weight: var(--fw-bold); }
.statband__value--sm { font-size: 1.125rem; line-height: 1.05; }
.statband__label {
  font-size: var(--t-2xs);
  line-height: 1.3;
  color: var(--c-tint-soft);
  margin-top: 4px;
}
@media (max-width: 1080px) {
  .statband__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-6) 0; }
  .statband__item:nth-child(3n) { border-right: 0; }
  .statband__item:nth-child(3n+1) { padding-left: 0; }
}
@media (max-width: 620px) {
  .statband__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .statband__item { border-right: 0 !important; padding-inline: 0 var(--s-4); }
  .statband__item img { height: 36px; }
}

/* On-blue tile strip (icon over label over description) */
.tileband { background: var(--grad-blue); color: #fff; }
.tileband--deep { background: var(--grad-blue-deep); }
.tileband__head {
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: clamp(1.25rem, 1.05rem + 0.9vw, 1.75rem);
  text-transform: uppercase;
  letter-spacing: .3px;
  line-height: 1.05;
  color: #fff;
  margin-bottom: var(--s-7);
}
.tileband__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--s-7) var(--s-6);
}
.tile { text-align: center; color: #fff; }
.tile__icon {
  height: 46px;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: var(--s-4);
}
.tile__icon img { height: 44px; width: auto; object-fit: contain; }
.tile__icon .ms { font-size: 38px; color: #fff; }
.tile h4 {
  color: #fff;
  font-size: var(--t-xs);
  letter-spacing: .6px;
  line-height: 1.2;
  margin-bottom: var(--s-2);
}
.tile p { font-size: var(--t-2xs); line-height: 1.4; color: var(--c-tint-soft); }

/* Split variant: heading left, tiles right (brochure pages 3, 9) */
.tileband__split {
  display: grid;
  grid-template-columns: minmax(220px, 300px) minmax(0, 1fr);
  gap: clamp(var(--s-6), 4vw, var(--s-10));
  align-items: center;
}
.tileband__split > .tileband__head { margin-bottom: 0; }
/* In the split layout the heading eats the left column, leaving the grid a width
   that auto-fit resolves to four columns — so the common six-tile band wrapped
   4 + 2 with a hole at the end of the second row. Pin it to three so six tiles
   sit 3 + 3, and three sit in a single row.
   Held down to 561px because the 4 + 2 wrap reappeared in the tablet range once
   the split collapsed to one column. Below that, auto-fit gives two columns and
   six tiles sit 2 + 2 + 2, which is already even. */
@media (min-width: 561px) {
  .tileband__split .tileband__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 860px) {
  .tileband__split { grid-template-columns: minmax(0, 1fr); }
  .tileband__split > .tileband__head { margin-bottom: var(--s-2); }
}

/* --------------------------------------------------------------------------
   6. Cards
   -------------------------------------------------------------------------- */
.card {
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: var(--r);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: border-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
.card--flat { box-shadow: none; }
.card--tint { background: var(--c-surface-alt); border-color: transparent; }
a.card:hover, .card--link:hover {
  border-color: var(--c-tint);
  box-shadow: var(--sh-2);
  transform: translateY(-3px);
}
.card__media { position: relative; overflow: hidden; background: var(--c-surface-alt); }
.card__media img {
  width: 100%;
  height: 208px;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}
.card__media--tall img { height: 250px; }
.card__media--short img { height: 158px; }
/* The four Products page product-line cards carry photographs already cut to the
   1.60:1 house ratio. Fixing the box height instead of its ratio made the box
   2.26:1 on desktop, so object-fit had to crop 132px off the top and bottom of
   every one — which is what clipped the top of the filter press. Giving the box
   the image's own ratio leaves nothing to crop, at any width.
   Layered over --tall, which stays as the fallback if aspect-ratio is missing. */
@supports (aspect-ratio: 16 / 10) {
  .card__media--fit img { height: auto; aspect-ratio: 16 / 10; }
}
/* The antistatic page's Yarn & Fabric Options cards present each sample as a
   disc. The images carry both the circle and the white around it, so the box is
   square and untinted — object-fit is left with nothing to crop, and the disc
   stays round at every width.
   Layered over --short, which stays as the fallback if aspect-ratio is missing. */
.card__media--circle { background: #fff; }
@supports (aspect-ratio: 1 / 1) {
  .card__media--circle img { height: auto; aspect-ratio: 1 / 1; }
}
a.card:hover .card__media img, .card--link:hover .card__media img { transform: scale(1.045); }
.card__tag {
  position: absolute;
  top: var(--s-3); left: var(--s-3);
  background: var(--c-blue);
  color: #fff;
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: var(--t-eyebrow);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  padding: 6px var(--s-3);
  border-radius: var(--r-xs);
  line-height: 1;
}
.card__body {
  padding: var(--s-6);
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: var(--s-3);
}
.card__body > .link-arrow { margin-top: auto; padding-top: var(--s-2); }
.card__title { color: var(--c-ink); transition: color var(--dur-fast) var(--ease); }
a.card:hover .card__title, .card--link:hover .card__title { color: var(--c-blue); }
.card__text { font-size: var(--t-sm); line-height: 1.55; color: var(--c-body); }

/* Icon card: circular icon well, centred */
.icard {
  background: var(--c-surface-alt);
  border: 1px solid transparent;
  border-radius: var(--r);
  padding: var(--s-7) var(--s-6);
  text-align: center;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.icard:hover { background: #fff; border-color: var(--c-tint); transform: translateY(-3px); box-shadow: var(--sh-2); }
.icard__well {
  width: 62px; height: 62px;
  border-radius: 50%;
  background: #fff;
  border: 1px solid var(--c-line);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto var(--s-5);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.icard__well .ms { font-size: 28px; color: var(--c-blue); }
.icard__well img { width: 34px; height: auto; object-fit: contain; }
/* The four "How We Engineer It" icons are illustrations rather than line icons,
   and their subjects are landscape, so at the default 34px they read as specks
   in a 62px well. 46px fills it without crowding the 1px rim. */
.icard__well--art img { width: 46px; }
.icard:hover .icard__well { border-color: var(--c-tint); background: var(--c-tint-soft); }
.icard h3, .icard h4 { color: var(--c-ink); margin-bottom: var(--s-3); }
.icard .rule { margin: 0 auto var(--s-4); }

/* Compact horizontal icon + text block */
.ftr {
  display: flex;
  gap: var(--s-4);
  align-items: flex-start;
}
.ftr__icon {
  flex: none;
  width: 46px; height: 46px;
  border-radius: 50%;
  background: var(--c-tint-soft);
  display: flex; align-items: center; justify-content: center;
}
.ftr__icon .ms { font-size: 24px; color: var(--c-blue); }
.ftr__icon img { width: 26px; height: auto; }
.ftr h4 { color: var(--c-ink); margin-bottom: var(--s-2); }
.ftr p { font-size: var(--t-sm); line-height: 1.5; }
.ftr--on-blue .ftr__icon { background: rgba(255, 255, 255, .16); }
.ftr--on-blue .ftr__icon .ms { color: #fff; }
.ftr--on-blue h4 { color: #fff; }
.ftr--on-blue p { color: var(--c-tint-soft); }

/* --------------------------------------------------------------------------
   7. Lists
   -------------------------------------------------------------------------- */
.checks { display: flex; flex-direction: column; gap: var(--s-3); }
.checks li {
  display: flex;
  gap: var(--s-3);
  font-size: var(--t-sm);
  line-height: 1.45;
  color: var(--c-body);
}
.checks .ms { font-size: 18px; color: var(--c-blue); flex: none; margin-top: 1px; }
.checks--on-blue li { color: var(--c-tint-soft); }
.checks--on-blue .ms { color: #fff; }
.checks--tight li { font-size: var(--t-2xs); gap: var(--s-2); }
.checks--tight .ms { font-size: 16px; }

.chevs { display: flex; flex-direction: column; gap: var(--s-2); }
.chevs li {
  display: flex;
  gap: var(--s-2);
  font-size: var(--t-sm);
  line-height: 1.45;
  color: var(--c-body);
}
.chevs .ms { font-size: 17px; color: var(--c-blue); flex: none; margin-top: 1px; }

/* Key-benefits panel that sits inside capability cards */
.keybenefits {
  background: var(--c-surface-alt);
  border-left: 3px solid var(--c-blue);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  padding: var(--s-5);
}
.keybenefits__label {
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: var(--t-eyebrow);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--c-blue);
  display: block;
  margin-bottom: var(--s-3);
}

/* --------------------------------------------------------------------------
   8. Process stepper (brochure page 2)
   -------------------------------------------------------------------------- */
.steps { border-top: 1px solid var(--c-line-soft); }
.step {
  display: grid;
  grid-template-columns: 62px 96px 84px minmax(150px, 200px) minmax(0, 1fr);
  align-items: center;
  gap: var(--s-4);
  padding-block: var(--s-5);
  border-bottom: 1px solid var(--c-line-soft);
  transition: background var(--dur) var(--ease);
}
.step:hover { background: var(--c-surface-alt); }
.step__num {
  position: relative;
  align-self: stretch;
  display: flex; align-items: center; justify-content: center;
}
.step__num b {
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--c-blue-deep);
  box-shadow: 0 0 0 5px #fff;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: 1rem;
  color: #fff;
  position: relative;
  z-index: 1;
}
.step__num::before {
  content: '';
  position: absolute;
  left: 50%; top: 0; bottom: 0;
  width: 2px;
  background: var(--c-tint);
  transform: translateX(-50%);
}
.step:first-child .step__num::before { top: 50%; }
.step:last-child .step__num::before { bottom: 50%; }
.step__photo {
  width: 86px; height: 86px;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: var(--ring);
  justify-self: center;
}
.step__icon { display: flex; align-items: center; justify-content: center; }
.step__icon img { width: 68px; height: auto; object-fit: contain; }
.step__title {
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: 1.25rem;
  color: var(--c-blue);
  text-transform: uppercase;
  letter-spacing: .3px;
  line-height: 1.02;
}
.step__text {
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--c-body);
  border-left: 1px solid var(--c-line);
  padding-left: var(--s-5);
}
@media (max-width: 980px) {
  .step { grid-template-columns: 54px 76px minmax(0, 1fr); gap: var(--s-4); }
  .step__icon { display: none; }
  .step__photo { width: 68px; height: 68px; }
  .step__title { grid-column: 3; font-size: 1.125rem; }
  .step__text { grid-column: 3; border-left: 0; padding-left: 0; margin-top: var(--s-2); }
}

/* Numbered section marker used to open a technical block */
.marker {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  margin-bottom: var(--s-6);
}
.marker__num {
  width: 34px; height: 34px;
  flex: none;
  border-radius: var(--r-sm);
  background: var(--c-blue);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: 1.0625rem;
  line-height: 1;
}
.marker h2, .marker h3 { line-height: 1; }
.marker p {
  font-size: var(--t-sm);
  color: var(--c-body);
  border-left: 1px solid var(--c-line);
  padding-left: var(--s-4);
  line-height: 1.4;
}
@media (max-width: 720px) {
  .marker { flex-wrap: wrap; }
  .marker p { border-left: 0; padding-left: 0; flex-basis: 100%; }
}

/* --------------------------------------------------------------------------
   9. Rating dots + spec table
   -------------------------------------------------------------------------- */
.dots { display: inline-flex; gap: 5px; align-items: center; }
.dots i {
  width: 9px; height: 9px;
  border-radius: 50%;
  display: inline-block;
  background: var(--c-blue);
}
.dots i.off { background: transparent; border: 1.5px solid var(--c-dot-empty); }
.dots--white i { background: #fff; }
.dots--white i.off { background: transparent; border-color: rgba(255,255,255,.5); }

.rate { display: flex; flex-direction: column; gap: var(--s-3); }
.rate__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-4);
}
.rate__row span { font-size: var(--t-2xs); color: var(--c-body); line-height: 1.25; }

.tablewrap {
  overflow-x: auto;
  border: 1px solid var(--c-line);
  border-radius: var(--r);
  background: #fff;
  -webkit-overflow-scrolling: touch;
}
.spec {
  width: 100%;
  border-collapse: collapse;
  min-width: 660px;
}
.spec thead th {
  background: var(--c-blue);
  color: #fff;
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  text-align: center;
  padding: var(--s-4) var(--s-4);
  white-space: nowrap;
}
.spec thead th:first-child { text-align: left; }
.spec thead .ms { font-size: 17px; vertical-align: -3px; margin-right: 5px; }
.spec tbody tr { border-top: 1px solid var(--c-line); }
.spec tbody tr:nth-child(even) { background: #FAFCFD; }
.spec tbody tr:hover { background: var(--c-tint-soft); }
.spec td {
  padding: var(--s-4);
  text-align: center;
  border-left: 1px solid var(--c-line);
  font-size: var(--t-sm);
}
.spec td:first-child {
  text-align: left;
  border-left: 0;
  font-weight: var(--fw-semi);
  font-size: var(--t-xs);
  color: var(--c-ink);
  white-space: nowrap;
}
.spec td:first-child .ms { font-size: 17px; color: var(--c-blue); vertical-align: -3px; margin-right: 6px; }
.spec .spec__val {
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: 1.0625rem;
  color: var(--c-blue);
  text-transform: uppercase;
}
.spec tfoot td { background: var(--c-surface-alt); }
.spec .dots { justify-content: center; }

.tablenote {
  display: flex;
  gap: var(--s-3);
  align-items: flex-start;
  margin-top: var(--s-4);
  font-size: var(--t-2xs);
  font-style: italic;
  color: var(--c-muted);
}
.tablenote .ms { font-size: 16px; color: var(--c-blue); font-style: normal; }
.scrollhint {
  display: none;
  font-size: var(--t-2xs);
  color: var(--c-muted);
  margin-bottom: var(--s-3);
}
@media (max-width: 760px) { .scrollhint { display: block; } }

/* --------------------------------------------------------------------------
   10. Process chain (arrow flow)
   -------------------------------------------------------------------------- */
.chain {
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  gap: var(--s-3);
  justify-content: center;
}
.chain__node {
  flex: 1 1 150px;
  min-width: 140px;
  text-align: center;
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: var(--r);
  padding: var(--s-5) var(--s-4);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.chain__node:hover { border-color: var(--c-tint); box-shadow: var(--sh-1); }
.chain__node--active { background: var(--c-blue); border-color: var(--c-blue); }
.chain__dot {
  width: 48px; height: 48px;
  border-radius: 50%;
  background: var(--c-tint-soft);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto var(--s-3);
}
.chain__dot .ms { font-size: 24px; color: var(--c-blue); }
.chain__node h4 {
  font-size: var(--t-2xs);
  letter-spacing: .5px;
  line-height: 1.2;
  color: var(--c-ink);
  margin-bottom: var(--s-2);
}
.chain__node p { font-size: 0.75rem; line-height: 1.35; color: var(--c-body); }

/* The active node paints itself brand blue, so its heading, copy and icon all
   have to flip to white. These overrides MUST stay below the .chain__node and
   .chain__dot rules above: each pair carries identical specificity, so order is
   the only thing deciding the winner. Declared above them — as they were — the
   base dark ink won instead, and the blue tile rendered near-black text on blue
   at about 2.7:1, which is what made it unreadable. */
.chain__node--active .chain__dot { background: rgba(255,255,255,.2); }
.chain__node--active h4 { color: #fff; }
.chain__node--active p { color: var(--c-tint-soft); }
.chain__node--active .chain__dot .ms { color: #fff; }
.chain__arrow {
  display: flex;
  align-items: center;
  color: var(--c-tint);
  flex: none;
}
.chain__arrow .ms { font-size: 26px; }
@media (max-width: 720px) {
  .chain__arrow { transform: rotate(90deg); width: 100%; justify-content: center; }
  .chain__node { flex-basis: 100%; }
}

/* Simple horizontal pill flow (compact variant) */
.flowline {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-3);
  justify-content: center;
}
.flowline__step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
  min-width: 96px;
}
.flowline__step .ms { font-size: 26px; color: var(--c-blue); }
.flowline__ring {
  width: 62px; height: 62px;
  border-radius: 50%;
  border: 1px solid var(--c-line);
  background: #fff;
  display: flex; align-items: center; justify-content: center;
}
.flowline__step b {
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: var(--t-eyebrow);
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--c-ink);
  text-align: center;
  line-height: 1.2;
}
.flowline > .ms { color: var(--c-tint); font-size: 24px; }

/* Industries page — the five-panel process strip and the labels under it.
   The strip's dividers are slanted and its panels are deliberately unequal:
   measured at the panel midline they run 408/465/472/428/399 of the image's
   2172px width. Giving the label columns those same proportions puts each
   label on its own panel's centre, and because the columns are proportional
   the alignment holds at every width rather than only at desktop.
   The rings sit on a connector line drawn between the first and last of them,
   which is what carries the left-to-right reading now that the arrows are gone. */
.procstrip__img { display: block; width: 100%; height: auto; border-radius: var(--r); }
.procstrip__steps {
  position: relative;
  display: grid;
  grid-template-columns: 408fr 465fr 472fr 428fr 399fr;
  margin-top: var(--s-5);
}
.procstrip__steps::before {
  content: "";
  position: absolute;
  left: 9.39%;            /* centre of the first column  */
  right: 9.18%;           /* centre of the last column   */
  top: 31px;              /* half the 62px ring          */
  height: 1px;
  background: var(--c-line);
}
.procstrip__step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
  text-align: center;
}
.procstrip__step .flowline__ring { position: relative; z-index: 1; }
.procstrip__step .ms { font-size: 26px; color: var(--c-blue); }
.procstrip__step b {
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: var(--t-eyebrow);
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--c-ink);
  line-height: 1.2;
}
.procstrip__text {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.procstrip__note {
  font-size: var(--t-2xs);
  color: var(--c-muted);
  max-width: 20ch;
  line-height: 1.35;
}
@media (max-width: 860px) {
  /* Columns are too narrow for a 62px ring here; shrink it and pull the
     connector up to match its new centre. */
  .procstrip__step .flowline__ring { width: 44px; height: 44px; }
  .procstrip__step .ms { font-size: 20px; }
  .procstrip__steps::before { top: 22px; }
  .procstrip__note { display: none; }
}
@media (max-width: 620px) {
  /* The strip is only ~90px tall by now, so aligning to it buys nothing.
     Fall back to a wrapped list and drop the connector. */
  .procstrip__steps {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s-5) var(--s-6);
  }
  .procstrip__steps::before { display: none; }
  .procstrip__step { min-width: 84px; }
}

/* --------------------------------------------------------------------------
   11. Media / split blocks
   -------------------------------------------------------------------------- */
.split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(var(--s-7), 5vw, var(--s-11));
  align-items: center;
}
.split--wide-l { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
.split--wide-r { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }
.split__media { border-radius: var(--r); overflow: hidden; box-shadow: var(--sh-2); }
.split__media img { width: 100%; height: clamp(260px, 30vw, 420px); object-fit: cover; }

/* Shorter media for a split whose text is deliberately brief. The Industries
   intro is a heading and one sentence — about 217px against a 420px image, which
   is what made that section read as "biggest picture, least writing". Cropping
   the width instead is not an option there: the montage is five photographs, and
   narrowing the box clips the outer two. */
.split__media--compact img { height: clamp(240px, 25vw, 330px); }

/* Two photographs stacked beside a long benefit list on the iron ore page. They
   carried an inline height:240px, which pins the height but not the shape: the
   box is 532x240 (2.22:1) at desktop, but at 860px the split collapses to one
   column and the same box becomes ~812x240 (3.38:1), where `cover` throws away
   half the picture. Locking the ratio lets the box get shorter as it narrows
   instead of wider, so both photographs hold their framing at every width, and
   both files are built to 1.9:1 to leave nothing to crop. */
@supports (aspect-ratio: 1) {
  .split__media--ratio img { height: auto; aspect-ratio: 1.9; }
}

/* A cut-out product shot rather than a photograph — a machine on a transparent
   background, running edge to edge with no margin of its own.

   This one drops the card entirely: no frame, no tint, no shadow. There are no
   background pixels to contain, so the machine simply sits on the page. That is
   the deliberate exception to the framed treatment used everywhere else, and it
   is what lets the machine be shown larger — with no frame to fill, every pixel
   of the box goes to the subject rather than to margin.

   `cover` cannot be used on one of these. The box is not a fixed shape: it runs
   1.20:1 at desktop widths but 2.72:1 at 768px, where the split collapses to one
   column and the media goes full width against a floor of 260px. Any single crop
   that suits one of those slices the machine in the other — and the file has
   only ~30px of side margin to give. `contain` sizes to whichever edge binds, so
   the machine is whole at every width.

   The height floor matters: with `contain` the image shrinks if the box is too
   short, so 240px keeps it from collapsing in the stacked tablet range. */
.split__media--bare {
  background: none;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
}

/* `--bare` also carries the global-reach globe, which is a *diagram* rather than
   a photograph — nine region labels are baked into its pixels. It needs the same
   two things a cut-out needs, for a different reason: no frame, because it has a
   transparent background; and `contain`, because at 768px this box becomes
   707x260 (2.72:1) and `cover` would keep 59% of the height, cutting "NORTH
   AMERICA" down to "AMERICA" and losing "EUROPE" entirely.

   An earlier `--diagram` variant painted a #F7F8FB panel behind an opaque
   version of the same artwork. It was removed on 10 Aug 2026 when Rohan supplied
   the globe with a transparent background, which makes the panel unnecessary —
   see ROADMAP 2.17. */
.split__media--bare img {
  height: clamp(240px, 24vw, 340px);
  object-fit: contain;
}
@media (max-width: 860px) {
  .split, .split--wide-l, .split--wide-r { grid-template-columns: minmax(0, 1fr); }
  .split--rev-m .split__media { order: -1; }
}

/* --------------------------------------------------------------------------
   Application list — an index of industries, each with what we actually do for
   it. Replaces a grid of seven one-word cards (10 Aug 2026, ROADMAP 2.20).

   Seven is prime, so a card grid orphaned a row at nearly every width: 5 + 2 at
   desktop, 3 + 3 + 1 on tablet. Rows in two columns cannot orphan — the shorter
   column simply ends — which is why this is a list and not a grid of cards.

   Column flow, not row flow: with `grid-auto-flow: column` the first column
   takes items 1-4 and the second 5-7, so each column is a continuous run of
   dividers. Filling row-wise instead would leave a gap in the middle of the
   last row with a divider hanging over nothing.
   -------------------------------------------------------------------------- */
.applist {
  display: grid;
  grid-template-rows: repeat(4, auto);
  grid-auto-flow: column;
  column-gap: clamp(var(--s-8), 5vw, var(--s-11));
  list-style: none;
  margin: 0;
  padding: 0;
}
.applist__item {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  padding-block: clamp(var(--s-4), 1.6vw, var(--s-5));
  border-top: 1px solid var(--c-line);
  text-decoration: none;
  transition: border-color var(--dur) var(--ease);
}
.applist__icon {
  width: 40px; height: 40px;
  flex: none;
  border-radius: 50%;
  background: #fff;
  border: 1px solid var(--c-line);
  display: flex; align-items: center; justify-content: center;
  color: var(--c-blue);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.applist__icon .ms { font-size: 21px; }
.applist__name {
  display: block;
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: .6px;
  color: var(--c-ink);
  transition: color var(--dur) var(--ease);
}
.applist__desc {
  display: block;
  font-size: var(--t-2xs);
  line-height: 1.4;
  color: var(--c-body);
  margin-top: 3px;
}
/* The arrow is held in reserve and only appears on hover, so seven of them do
   not compete for attention in the resting state — which is the fault the card
   grid had. Space is reserved either way so nothing shifts. */
.applist__go {
  margin-left: auto;
  flex: none;
  color: var(--c-blue);
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.applist__go .ms { font-size: 20px; display: block; }
.applist__item:hover,
.applist__item:focus-visible { border-color: var(--c-tint); }
.applist__item:hover .applist__name,
.applist__item:focus-visible .applist__name { color: var(--c-blue); }
.applist__item:hover .applist__icon,
.applist__item:focus-visible .applist__icon { background: var(--c-tint-soft); border-color: var(--c-tint); }
.applist__item:hover .applist__go,
.applist__item:focus-visible .applist__go { opacity: 1; transform: none; }

/* Seven items over two columns leaves the second column a row short, and that
   gap sat in the bottom-right corner reading as unfinished. The "all industries"
   link takes the cell, which squares the block off at 4 + 4 and gives the list a
   terminus instead of a hole. It keeps its arrow at rest — it is a destination,
   not one of the seven. */
.applist__item--cta .applist__icon { background: var(--c-blue); border-color: var(--c-blue); color: #fff; }
.applist__item--cta .applist__name { color: var(--c-blue); }
.applist__item--cta .applist__go { opacity: 1; transform: none; }
.applist__item--cta:hover .applist__icon { background: var(--c-blue-hover); border-color: var(--c-blue-hover); }
.applist__item--cta:hover .applist__go { transform: translateX(4px); }

@media (max-width: 720px) {
  .applist { grid-template-rows: none; grid-auto-flow: row; }
}

/* Framed figure with caption */
.figure { border-radius: var(--r); overflow: hidden; border: 1px solid var(--c-line); background: #fff; }
.figure img { width: 100%; height: 190px; object-fit: cover; }
/* Ratio-locked variant for the filter press compatibility grid. The pinned
   190px height makes the box anything from 1.08:1 to 2.35:1 as the grid reflows
   4 -> 2 -> 1 columns, and a centre crop at the wide end cuts the tops and
   bottoms off the plates. 1.42:1 is exactly what the box already measures at
   desktop (270x190), so desktop rendering is unchanged, and all four images are
   built to that ratio with the plate at 92% of height — so nothing is cropped at
   any width and the four plates read at the same scale.
   Not applied to the antistatic page's three figures, whose weave close-ups are
   built to 2:1 — what the box already measures at desktop (381x190) — and whose
   repeating texture survives a crop at any other width. */
@supports (aspect-ratio: 1) {
  .figure--fit img { height: auto; aspect-ratio: 1.42; }
}
.figure figcaption {
  padding: var(--s-4);
  text-align: center;
}
.figure figcaption b {
  display: block;
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: var(--t-h5);
  color: var(--c-ink);
  text-transform: uppercase;
  letter-spacing: .3px;
}
.figure figcaption span { font-size: var(--t-2xs); color: var(--c-muted); }

/* Weave / swatch card with blue title strip */
.swatch { border: 1px solid var(--c-line); border-radius: var(--r); overflow: hidden; background: #fff; display: flex; flex-direction: column; }
.swatch__head {
  background: var(--c-blue);
  color: #fff;
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: .7px;
  text-align: center;
  padding: var(--s-3);
  line-height: 1;
}
.swatch__img { width: 100%; height: 116px; object-fit: cover; }
.swatch__ph {
  height: 116px;
  display: flex; align-items: center; justify-content: center;
  background: var(--c-surface-alt);
}
.swatch__ph .ms { font-size: 42px; color: var(--c-blue); }
.swatch__body { padding: var(--s-4); flex: 1; }

/* Circular ringed photo (brochure motif) */
.circphoto {
  width: 86px; height: 86px;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: var(--ring);
}

/* Partner card (page 12) */
.partner { border: 1px solid var(--c-line); border-radius: var(--r); overflow: hidden; background: #fff; transition: box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.partner:hover { box-shadow: var(--sh-2); border-color: var(--c-tint); }
.partner__head {
  padding: var(--s-4) var(--s-4) var(--s-3);
  border-bottom: 1px solid var(--c-line-soft);
}
.partner__name {
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: var(--t-h5);
  color: var(--c-ink);
  text-transform: uppercase;
  letter-spacing: .4px;
  line-height: 1;
}
/* Fixed-height brand slot. Partner logos arrive at every imaginable aspect
   ratio; capping the box and letting each mark scale inside it keeps five of
   them optically level across the row, and holds the same space on a card
   still showing its wordmark instead. 34px carries a two-line mark like
   Textest's without shrinking its second line past legibility. */
.partner__brand {
  display: flex;
  align-items: center;
  height: 48px;
}
/* Partner logos come in shapes that fight each other: Dornier and JUKI are
   long single-line wordmarks near 7:1, Fepatex is an emblem stacked over its
   name at 1.3:1. Sizing them all to one rule makes the wide ones bellow and
   the stacked one vanish, so each shape gets its own ceiling while the slot
   itself stays a fixed 48px — that keeps every card's photo on the same line.
   Sizes are tuned so the marks carry roughly equal optical weight, not equal
   dimensions. */
.partner__logo {
  display: block;
  width: auto;
  height: auto;
  max-width: 78%;
  max-height: 36px;
  object-fit: contain;
  object-position: left center;
}
.partner__logo--wide    { max-height: 24px; }                   /* long wordmark */
.partner__logo--stacked { max-height: 48px; max-width: 62%; }   /* emblem over name */

/* A stacked mark relaid horizontally: emblem left, wordmark right. The
   wordmark is set to about a third of the emblem's height, which is the
   proportion a designed horizontal lockup normally uses, and both are centred
   on the same line. */
.partner__brand--lockup { gap: 9px; }
.partner__logo-mark { display: block; width: auto; height: 42px; }
.partner__logo-word { display: block; width: auto; height: 14px; }
/* Prabhat's wordmark is two lines — the name over a "Since 1968" tagline — so
   the single-line 14px ceiling would put the tagline under 5px. 22px carries
   both lines and still sits inside the 48px slot. */
.partner__logo-word--two-line { height: 22px; }
.partner__country {
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 1.1px;
  color: var(--c-muted);
  margin-top: 7px;
  display: flex;
  align-items: center;
  gap: 7px;
}
/* The ring keeps a flag's white areas from bleeding into the white card —
   without it Japan's flag reads as a lone red dot. It must be an OUTER
   shadow: an inset one paints beneath replaced content like an <svg>, so it
   is hidden by the flag's own white field, which is exactly the case it
   exists to fix. */
.flag {
  flex: none;
  width: 20px;
  height: 14px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(15, 23, 32, .18);
}
/* Direct child only — the card photo. An unscoped `.partner img` also caught
   the logo in the head and stretched it to the photo's 132px cover box. */
.partner > img { width: 100%; height: 132px; object-fit: cover; }
.partner__body { padding: var(--s-4); }
.partner__body h4 { color: var(--c-blue); font-size: var(--t-xs); letter-spacing: .4px; margin-bottom: var(--s-2); line-height: 1.15; }
.partner__body p { font-size: var(--t-2xs); line-height: 1.45; }

/* --------------------------------------------------------------------------
   12. Callout / quote / note
   -------------------------------------------------------------------------- */
.callout {
  background: var(--c-surface-alt);
  border-radius: var(--r);
  padding: clamp(var(--s-6), 3vw, var(--s-9));
}
.callout--blue { background: var(--grad-blue); color: #fff; }
.callout--blue h2, .callout--blue h3, .callout--blue h4 { color: #fff; }
.callout--blue p { color: var(--c-tint-soft); }
.callout--outline { background: #fff; border: 1px solid var(--c-line); }

/* Filter press page, "Size Is Never a Limitation". Three columns, each a plate
   photograph beside its size figure. This was inline-styled on the element,
   which meant no media query could override it — the layout is defined here so
   it can be made responsive. */
.sizerange {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: clamp(var(--s-5), 4vw, var(--s-9));
  align-items: center;
}
/* The columns fit down to 680px; below that they are too narrow to hold image
   and figure side by side, so the contents spill out of the callout and, under
   480px, push the whole page sideways. Stack the three blocks instead. */
@media (max-width: 680px) {
  .sizerange {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
  }
  .sizerange > * { min-width: 0; }
  .sizerange img { max-width: 100%; height: auto; }
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  background: var(--c-tint-soft);
  color: var(--c-blue);
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: var(--t-eyebrow);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  padding: 7px var(--s-4);
  border-radius: var(--r-pill);
  line-height: 1;
}
.pill .ms { font-size: 15px; }
.pill--solid { background: var(--c-blue); color: #fff; }
.pill--outline { background: transparent; border: 1px solid var(--c-line); color: var(--c-body); }
.pill-row { display: flex; flex-wrap: wrap; gap: var(--s-3); }

/* Test-method chip used on the Quality page */
.method {
  border-left: 1px solid var(--c-line);
  padding-left: var(--s-5);
}
.method__label {
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 1.1px;
  color: var(--c-muted);
  display: block;
  margin-bottom: 5px;
}
.method__value {
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: var(--t-h5);
  color: var(--c-blue);
  line-height: 1.2;
}
.method__value small { font-family: var(--f-body); font-weight: var(--fw-reg); font-size: var(--t-2xs); color: var(--c-body); display: block; }

/* Lab test row (Quality page) */
.testrow {
  display: grid;
  grid-template-columns: 168px 92px minmax(0, 1fr) 210px;
  align-items: center;
  gap: var(--s-6);
  padding-block: var(--s-6);
  border-bottom: 1px solid var(--c-line-soft);
}
.testrow:first-child { border-top: 1px solid var(--c-line-soft); }
.testrow__img { width: 100%; height: 104px; object-fit: cover; border-radius: var(--r); border: 1px solid var(--c-line); }
.testrow__icon { text-align: center; }
.testrow__icon img { width: 76px; height: auto; margin-inline: auto; object-fit: contain; }
.testrow h3 { color: var(--c-blue); font-size: var(--t-h3); margin-bottom: var(--s-2); }
.testrow p { font-size: var(--t-sm); line-height: 1.5; }
@media (max-width: 980px) {
  .testrow { grid-template-columns: 132px minmax(0, 1fr); gap: var(--s-5); }
  .testrow__icon { display: none; }
  .testrow .method { grid-column: 2; border-left: 0; padding-left: 0; padding-top: var(--s-3); }
}
@media (max-width: 560px) {
  .testrow { grid-template-columns: minmax(0, 1fr); }
  .testrow__img { height: 170px; }
  .testrow .method { grid-column: 1; }
}

/* --------------------------------------------------------------------------
   13. CTA band + footer
   -------------------------------------------------------------------------- */
.ctaband {
  background: var(--grad-blue);
  color: #fff;
  position: relative;
  overflow: hidden;
}
.ctaband::after {
  content: '';
  position: absolute;
  right: -80px; top: -120px;
  width: 460px; height: 460px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .07);
}
.ctaband__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--s-9);
  align-items: center;
  padding-block: clamp(44px, 5vw, 72px);
  position: relative;
  z-index: 1;
}
.ctaband h2 { color: #fff; margin-bottom: var(--s-4); }
.ctaband p { color: var(--c-tint-soft); max-width: 56ch; font-size: var(--t-lead); }
@media (max-width: 860px) { .ctaband__inner { grid-template-columns: minmax(0, 1fr); gap: var(--s-7); } }

.footer { background: var(--c-ink); color: rgba(255, 255, 255, .68); }
.footer__top {
  display: grid;
  grid-template-columns: minmax(240px, 1.25fr) repeat(3, minmax(0, 1fr));
  gap: clamp(var(--s-7), 4vw, var(--s-10));
  padding-block: clamp(var(--s-9), 5vw, var(--s-12)) var(--s-10);
}
.footer__logo img { height: 48px; width: auto; margin-bottom: var(--s-5); }
.footer p { font-size: var(--t-xs); line-height: 1.6; }
.footer h4 {
  color: #fff;
  font-size: var(--t-xs);
  letter-spacing: 1.2px;
  margin-bottom: var(--s-5);
}
.footer__links { display: flex; flex-direction: column; gap: var(--s-3); }
.footer__links a { color: rgba(255, 255, 255, .68); font-size: var(--t-xs); }
.footer__links a:hover { color: #fff; }
.footer__addr {
  display: flex;
  gap: var(--s-3);
  font-size: var(--t-xs);
  line-height: 1.55;
}
.footer__addr + .footer__addr { margin-top: var(--s-5); }
.footer__addr .ms { font-size: 18px; color: var(--c-blue); flex: none; margin-top: 2px; }
.footer__addr b {
  display: block;
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  color: #fff;
  text-transform: uppercase;
  letter-spacing: .8px;
  font-size: var(--t-2xs);
  margin-bottom: 3px;
}
.footer__bottom {
  border-top: 1px solid rgba(255, 255, 255, .12);
  padding-block: var(--s-6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4) var(--s-7);
  align-items: center;
  justify-content: space-between;
  font-size: var(--t-2xs);
}
.footer__bottom a { color: rgba(255, 255, 255, .68); }
.footer__bottom a:hover { color: #fff; }
@media (max-width: 900px) {
  .footer__top { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .footer__top { grid-template-columns: minmax(0, 1fr); gap: var(--s-8); }
}

/* --------------------------------------------------------------------------
   14. Forms
   -------------------------------------------------------------------------- */
.form { display: grid; gap: var(--s-5); }
.form__row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-5); }
@media (max-width: 620px) { .form__row { grid-template-columns: minmax(0, 1fr); } }

.field { display: flex; flex-direction: column; gap: var(--s-2); }
.field > label {
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: var(--t-2xs);
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--c-ink);
}
.field > label .req { color: var(--c-blue); }
.field input,
.field select,
.field textarea {
  width: 100%;
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: var(--r-sm);
  padding: 13px var(--s-4);
  font-size: var(--t-sm);
  font-family: var(--f-body);
  color: var(--c-ink);
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.field textarea { resize: vertical; min-height: 148px; line-height: 1.55; }
.field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1 1l6 6 6-6' fill='none' stroke='%235C6670' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--s-4) center;
  padding-right: var(--s-9);
  cursor: pointer;
}
.field input::placeholder, .field textarea::placeholder { color: #A9B3BD; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--c-blue);
  box-shadow: 0 0 0 3px rgba(0, 145, 206, .14);
}
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"], .field select[aria-invalid="true"] {
  border-color: #C0392B;
  box-shadow: 0 0 0 3px rgba(192, 57, 43, .1);
}
.field__error {
  font-size: var(--t-2xs);
  color: #C0392B;
  display: none;
}
.field__error.is-shown { display: block; }
.field__hint { font-size: var(--t-2xs); color: var(--c-muted); }

.form__consent {
  display: flex;
  gap: var(--s-3);
  align-items: flex-start;
  font-size: var(--t-2xs);
  line-height: 1.5;
  color: var(--c-body);
}
.form__consent input { width: 17px; height: 17px; margin-top: 2px; accent-color: var(--c-blue); flex: none; }

.form__status {
  display: none;
  gap: var(--s-3);
  align-items: flex-start;
  padding: var(--s-5);
  border-radius: var(--r-sm);
  font-size: var(--t-sm);
  line-height: 1.5;
}
.form__status.is-shown { display: flex; }
.form__status .ms { font-size: 22px; flex: none; }
.form__status--ok { background: var(--c-tint-soft); color: var(--c-blue-deep); border-left: 3px solid var(--c-blue); }
.form__status--ok .ms { color: var(--c-blue); }
.form__status--err { background: #FDF1EF; color: #98362A; border-left: 3px solid #C0392B; }
.form__status--err .ms { color: #C0392B; }

.hp { position: absolute; left: -9999px; opacity: 0; height: 0; width: 0; }

.btn[aria-busy="true"] { pointer-events: none; opacity: .72; }
.btn__spin {
  display: none;
  width: 15px; height: 15px;
  border: 2px solid rgba(255,255,255,.4);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
.btn[aria-busy="true"] .btn__spin { display: block; }
.btn[aria-busy="true"] .btn__label { opacity: .8; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Contact detail card */
.contactcard {
  background: var(--c-surface-alt);
  border-radius: var(--r);
  padding: var(--s-7);
}
.contactcard + .contactcard { margin-top: var(--s-5); }
.contactcard__head {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-4);
}
.contactcard__head .ms { font-size: 20px; color: var(--c-blue); }
.contactcard__head b {
  font-family: var(--f-display);
  font-weight: var(--fw-black);
  font-size: var(--t-h5);
  color: var(--c-ink);
  text-transform: uppercase;
  letter-spacing: .5px;
}
.contactcard address { font-style: normal; font-size: var(--t-sm); line-height: 1.6; }

.mapframe {
  border: 0;
  width: 100%;
  height: 380px;
  display: block;
  filter: grayscale(.25);
}

/* --------------------------------------------------------------------------
   15. Reveal-on-scroll
   -------------------------------------------------------------------------- */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity .6s var(--ease-out), transform .6s var(--ease-out); }
.reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; } }

/* Back to top */
.totop {
  position: fixed;
  right: var(--s-6); bottom: var(--s-6);
  width: 46px; height: 46px;
  border-radius: 50%;
  background: var(--c-blue);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--sh-2);
  opacity: 0; visibility: hidden;
  transform: translateY(10px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), visibility var(--dur), background var(--dur) var(--ease);
  z-index: calc(var(--z-header) - 2);
}
.totop.is-shown { opacity: 1; visibility: visible; transform: none; }
.totop:hover { background: var(--c-blue-hover); color: #fff; }
.totop .ms { font-size: 24px; }

/* --------------------------------------------------------------------------
   16. Print
   -------------------------------------------------------------------------- */
@media print {
  .header, .utilitybar, .subnav, .ctaband, .totop, .nav-scrim, .footer__links { display: none !important; }
  body { background: #fff; }
  .reveal { opacity: 1; transform: none; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 10px; color: #666; }
}
