/* ==========================================================================
   AXIOM HYDRAULICS
   Design system stylesheet

   BUILD NOTE FOR THE ELEMENTOR REBUILD
   Every layout in this file uses flexbox only. There is no CSS grid and no
   JavaScript-driven layout anywhere in this project, so each section maps
   directly onto an Elementor flex container. Column widths use either a flex-grow ratio with a pixel
   basis, or a plain percentage where an exact split matters. Both transfer
   directly to Elementor container widths.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */

:root {
  /* Surfaces. Neutral off-black charcoal. Never pure #000, so the page keeps
     depth, and orange stays the only colour anywhere in the system. */
  --ink-900: #0d0d0d;
  --ink-800: #151515;
  --ink-700: #1d1d1d;
  --ink-600: #2b2b2b;
  --ink-500: #3a3a3a;

  --bg-base: var(--ink-900);
  --bg-surface: var(--ink-800);
  --bg-elevated: var(--ink-700);

  /* Accent. One accent, used identically on every page. */
  --orange-500: #e35200;
  --orange-400: #f06120;
  --accent: var(--orange-500);
  --accent-hover: var(--orange-400);
  /* Small orange TEXT needs the brighter tint to clear WCAG AA on charcoal:
     #e35200 measures 4.2:1 at body size, #f06120 measures 5.9:1. The darker
     tone stays in use for fills, where white on it measures 4.5:1. */
  --accent-text: var(--orange-400);
  /* Solid fills carrying white label text need a deeper tone again. White on
     #e35200 measures only 3.84:1, under the 4.5:1 AA floor for button-sized
     text. These two clear it at 4.67:1 and 5.53:1. The brand orange stays in
     use everywhere it sits next to text rather than behind it. */
  --accent-fill: #cc4800;
  --accent-fill-hover: #b84100;

  /* Foreground. Off-white rather than #ffffff, except on orange fills where
     pure white is what carries the button label over the AA threshold. */
  --fg-primary: #fafafa;
  --fg-secondary: #b4b4b4;
  --fg-muted: #8c8c8c;

  /* Borders */
  --border: #2b2b2b;
  --border-strong: #3a3a3a;

  /* Plate for product photography. Pure white, because the manufacturer shots
     are all cut out on white and any off-white plate leaves a visible seam
     around the image. */
  --plate: #ffffff;

  /* Type */
  --font-display: "Barlow Condensed", "Arial Narrow", sans-serif;
  --font-body: "Barlow", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --fs-display: clamp(2.75rem, 7.5vw, 5.25rem);
  --fs-h1: clamp(2.5rem, 6vw, 4.25rem);
  --fs-h2: clamp(1.95rem, 4.2vw, 3.1rem);
  --fs-h3: clamp(1.4rem, 2.6vw, 1.9rem);
  --fs-h4: 1.2rem;
  --fs-body: 1.0625rem;
  --fs-sm: 0.9375rem;
  --fs-xs: 0.8125rem;

  /* Spacing, 8px base grid */
  --s-1: 8px;
  --s-2: 16px;
  --s-3: 24px;
  --s-4: 32px;
  --s-5: 40px;
  --s-6: 48px;
  --s-8: 64px;
  --s-10: 80px;
  --s-section: clamp(72px, 9vw, 120px);

  --container: 1200px;
  --container-wide: 1440px;

  /* Radius. Sharp and industrial. Buttons 2px, cards 4px, nothing rounder. */
  --r-btn: 2px;
  --r-card: 4px;
  --r-tag: 2px;

  /* Shadows. The page is already near-black, so a neutral shadow reads true. */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.55);

  /* Motion */
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --t-fast: 150ms;
  --t-base: 250ms;
  --t-slow: 400ms;

  /* Layers */
  /* Header. Two heights: the resting bar, which carries a logo big enough to
     read the wordmark under the monogram, and the compact bar it settles into
     once the reader has started scrolling. The compact state is what reclaims
     the viewport; the resting state is what carries the brand. */
  --header-h: 96px;
  --header-h-min: 68px;
  --logo-h: 64px;
  --logo-h-min: 46px;

  --z-header: 100;
  --z-menu: 200;
}

/* --------------------------------------------------------------------------
   2. RESET AND BASE
   -------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* clip rather than hidden: hidden on the root would break position: sticky
     on the header. This contains the off-canvas menu when it sits parked
     off-screen to the right. */
  overflow-x: clip;
}

body {
  margin: 0;
  background: var(--bg-base);
  color: var(--fg-secondary);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img,
picture,
video,
svg { max-width: 100%; display: block; }

/* height:auto is load-bearing. The width and height HTML attributes land as
   presentational hints, so an image with width:100% in CSS but no CSS height
   keeps rendering at its raw pixel height and distorts. Every rule below that
   needs an image to fill a frame sets height explicitly and overrides this. */
img { height: auto; }

/* Replaced elements must not stretch on a flex cross axis either. In a column
   flex parent the default stretch makes width:auto resolve to full container
   width, which flattens a logo to its declared height. */
img { align-self: flex-start; }
.card__media img,
.bento__media img,
.tile__media img,
.brand-card__media img,
.hero__media img,
.page-hero__media img,
.cta-band__media img,
.split__media img,
.article__media img { align-self: stretch; }

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  color: var(--fg-primary);
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}

h1 { font-size: var(--fs-h1); font-weight: 800; }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }

/* Title Case sub-headings keep the body typeface so they read as prose
   rather than as another display line. */
h4, h5, h6 {
  font-family: var(--font-body);
  font-size: var(--fs-h4);
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0;
  text-transform: none;
}

p { margin: 0 0 var(--s-3); }
p:last-child { margin-bottom: 0; }

a {
  color: var(--fg-primary);
  text-decoration: none;
  transition: color var(--t-fast) var(--ease);
}

ul, ol { margin: 0 0 var(--s-3); padding-left: 1.25em; }
li { margin-bottom: var(--s-1); }

strong { color: var(--fg-primary); font-weight: 600; }

::selection { background: var(--accent); color: #fff; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--s-2);
  z-index: 999;
  padding: var(--s-2) var(--s-3);
  background: var(--accent);
  color: #fff;
  font-weight: 600;
  border-radius: var(--r-btn);
}
.skip-link:focus { top: var(--s-2); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   3. LAYOUT PRIMITIVES
   All flexbox. Columns use flex-grow ratios with a pixel basis so they wrap
   on their own without percentage math.
   -------------------------------------------------------------------------- */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--s-3);
}
.container--wide { max-width: var(--container-wide); }
.container--narrow { max-width: 820px; }

.section { padding-block: var(--s-section); }
.section--tight { padding-block: clamp(48px, 6vw, 72px); }

/* The brand wall is a single row of logos, so it needs far less room around it
   than a section of content does. Reclaiming that height goes to the hero. */
.section--brandwall { padding-block: clamp(24px, 2.6vw, 34px); }
.section--surface { background: var(--bg-surface); }
.section--elevated { background: var(--bg-elevated); }

/* Hairline rule between two sections that share a background */
.section--divided { border-top: 1px solid var(--border); }

.row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
}
.row--tight { gap: var(--s-3); }
.row--loose { gap: var(--s-6); }
.row--middle { align-items: center; }
.row--stretch { align-items: stretch; }

/* Equal columns that collapse to full width below their basis */
.col { flex: 1 1 300px; min-width: 0; }
/* Asymmetric pairing, roughly 60/40 and 40/60 */
.col--wide { flex: 1.5 1 420px; min-width: 0; }
.col--narrow { flex: 1 1 300px; min-width: 0; }
/* Half and third helpers with a generous basis so they wrap early */
.col--half { flex: 1 1 420px; min-width: 0; }
.col--third { flex: 1 1 280px; min-width: 0; }
.col--quarter { flex: 1 1 210px; min-width: 0; }

.stack { display: flex; flex-direction: column; }
.stack--1 { gap: var(--s-1); }
.stack--2 { gap: var(--s-2); }
.stack--3 { gap: var(--s-3); }
.stack--4 { gap: var(--s-4); }
.stack--6 { gap: var(--s-6); }

.order-first { order: -1; }

/* Below 900px every asymmetric layout collapses to one column */
@media (max-width: 900px) {
  .row { gap: var(--s-4); }
  .col, .col--wide, .col--narrow, .col--half { flex-basis: 100%; }
  .row--reverse-mobile { flex-direction: column-reverse; }
  .order-first-mobile { order: -1; }
}

/* --------------------------------------------------------------------------
   4. TYPOGRAPHY HELPERS
   -------------------------------------------------------------------------- */

.display {
  font-family: var(--font-display);
  font-size: var(--fs-display);
  font-weight: 800;
  line-height: 0.98;
  letter-spacing: -0.025em;
  text-transform: uppercase;
  color: var(--fg-primary);
  margin: 0;
}

/* Section overline. Rationed deliberately, see the build notes. */
.overline {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-display);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin: 0;
}
.overline::before {
  content: "";
  width: 28px;
  height: 2px;
  background: var(--accent);
  flex: none;
}

.lead {
  font-size: clamp(1.0625rem, 1.6vw, 1.25rem);
  line-height: 1.65;
  color: var(--fg-secondary);
  max-width: 62ch;
}

.body-text { max-width: 65ch; }
.body-text--wide { max-width: 78ch; }

.muted { color: var(--fg-muted); }
.accent-text { color: var(--accent-text); }
.mono {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.02em;
}

.text-center { text-align: center; }
.mx-auto { margin-inline: auto; }

/* Inline link inside prose */
.link {
  color: var(--fg-primary);
  border-bottom: 1px solid var(--accent);
  padding-bottom: 1px;
}
.link:hover { color: var(--accent); }

/* --------------------------------------------------------------------------
   5. BUTTONS
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-1);
  padding: 14px 28px;
  border-radius: var(--r-btn);
  border: 2px solid transparent;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;      /* labels never wrap to a second line */
  cursor: pointer;
  transition: background-color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease),
              transform var(--t-fast) var(--ease);
}

.btn:active { transform: scale(0.98); }

.btn--primary {
  background: var(--accent-fill);
  border-color: var(--accent-fill);
  color: #ffffff;
}
.btn--primary:hover {
  background: var(--accent-fill-hover);
  border-color: var(--accent-fill-hover);
  color: #ffffff;
}

.btn--secondary {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.55);
  color: #ffffff;
}
.btn--secondary:hover {
  background: rgba(255, 255, 255, 0.1);
  border-color: #ffffff;
  color: #ffffff;
}

.btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--fg-secondary);
  padding-inline: 0;
}
.btn--ghost:hover { color: var(--accent); }

.btn--sm { padding: 10px 20px; font-size: var(--fs-xs); }
.btn--block { width: 100%; }

.btn .icon { width: 18px; height: 18px; flex: none; }

/* Arrow link used in place of a full button where a section already has one */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fg-primary);
}
.arrow-link .icon {
  width: 18px; height: 18px;
  transition: transform var(--t-fast) var(--ease);
}
.arrow-link:hover { color: var(--accent); }
.arrow-link:hover .icon { transform: translateX(4px); }

/* --------------------------------------------------------------------------
   6. HEADER AND NAVIGATION
   -------------------------------------------------------------------------- */

/* Fixed rather than sticky. A sticky header is in flow, so shrinking it on
   scroll pulls every following section up by the difference and the page jumps
   under the reader at the exact moment the state changes. Fixed takes it out of
   flow and body carries a constant offset instead, so the bar can change height
   freely and nothing below it moves. */
.header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: var(--z-header);
  height: var(--header-h);
  background: rgba(13, 13, 13, 0.92);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
  transition: height var(--t-base) var(--ease),
              background-color var(--t-base) var(--ease),
              box-shadow var(--t-base) var(--ease);
}

body { padding-top: var(--header-h); }

/* Settled state: a slimmer bar that sits more firmly over the content. */
.header.is-stuck {
  height: var(--header-h-min);
  background: rgba(13, 13, 13, 0.97);
  box-shadow: 0 10px 30px -18px rgba(0, 0, 0, 0.9);
}

/* Compacting while the panel is open would drag the panel's top edge with it,
   so the bar holds its resting height for as long as the menu is showing. */
.header.is-open { height: var(--header-h); }

/* In-page links have to clear the bar, or the heading they target lands
   underneath it. */
[id] { scroll-margin-top: calc(var(--header-h-min) + 20px); }

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  height: 100%;
}

/* The wordmark sits under the monogram in the supplied artwork, so the lockup
   needs real height before the "Axiom Hydraulics" line becomes legible. */
.header__logo { flex: none; display: flex; align-items: center; }
.header__logo img {
  height: var(--logo-h);
  width: auto;
  transition: height var(--t-base) var(--ease);
}
.header.is-stuck .header__logo img { height: var(--logo-h-min); }
.header.is-open .header__logo img { height: var(--logo-h); }

/* A phone has less height to spend, so the resting bar is shorter and the
   compaction is gentler. */
@media (max-width: 900px) {
  :root {
    --header-h: 74px;
    --header-h-min: 62px;
    --logo-h: 48px;
    --logo-h-min: 40px;
  }
}

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

.nav { display: flex; align-items: center; gap: var(--s-4); }

/* Gap flexes so the seven items plus the CTA always hold a single line */
.nav__list {
  display: flex;
  align-items: center;
  gap: clamp(16px, 1.9vw, 30px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.nav__list li { margin: 0; }

.nav__link {
  position: relative;
  display: block;
  padding-block: 6px;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--fg-secondary);
  white-space: nowrap;
}
.nav__link:hover { color: var(--fg-primary); }

.nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0;
  height: 2px;
  background: var(--accent);
  transition: width var(--t-base) var(--ease);
}
.nav__link:hover::after,
.nav__link[aria-current="page"]::after { width: 100%; }
.nav__link[aria-current="page"] { color: var(--fg-primary); }

.header__cta { flex: none; }

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-btn);
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  width: 20px;
  height: 2px;
  margin-inline: auto;
  background: var(--fg-primary);
  transition: transform var(--t-base) var(--ease),
              opacity var(--t-fast) var(--ease);
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Mobile panel */
.mobile-nav {
  position: fixed;
  /* The panel lives inside <header>, and the header carries backdrop-filter,
     which makes it the containing block for fixed descendants. That meant
     bottom:0 resolved against the header box and the panel collapsed to the
     height of its own padding. An explicit height is correct whether the
     containing block is the header or the viewport, and it tracks the header
     token so the two can never disagree. */
  top: var(--header-h); left: 0; right: 0;
  height: calc(100dvh - var(--header-h));
  z-index: var(--z-menu);
  display: flex;
  flex-direction: column;
  padding: var(--s-4) var(--s-3) var(--s-8);
  background: var(--bg-base);
  border-top: 1px solid var(--border);
  overflow-y: auto;
  /* Slides down from behind the header, not in from the right.
     html carries overflow-x: clip so the parked panel cannot create a
     horizontal scrollbar, but that clips the horizontal axis, which is
     exactly where a translateX(100%) panel lives. It was being clipped out
     of existence and never came back. Moving off-canvas onto the Y axis
     sidesteps the clip entirely, and matches how v2 already behaves. */
  transform: translateY(-101%);
  visibility: hidden;
  transition: transform var(--t-slow) var(--ease),
              visibility 0s linear var(--t-slow);
}
.mobile-nav.is-open {
  transform: none;
  visibility: visible;
  transition: transform var(--t-slow) var(--ease), visibility 0s;
}

.mobile-nav__list {
  margin: 0 0 var(--s-6);
  padding: 0;
  list-style: none;
}
.mobile-nav__list li {
  margin: 0;
  border-bottom: 1px solid var(--border);
}
.mobile-nav__link {
  display: block;
  padding: var(--s-3) 0;
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: var(--fg-primary);
}
.mobile-nav__link:hover,
.mobile-nav__link[aria-current="page"] { color: var(--accent); }

.mobile-nav__contact {
  margin-top: auto;
  padding-top: var(--s-4);
  border-top: 1px solid var(--border);
  font-size: var(--fs-sm);
}
.mobile-nav__contact a { color: var(--fg-secondary); display: block; padding-block: 4px; }
.mobile-nav__contact a:hover { color: var(--accent); }

body.nav-open { overflow: hidden; }

@media (max-width: 1080px) {
  .nav { display: none; }
  .header__cta { display: none; }
  .nav-toggle { display: flex; }
}

/* Above the breakpoint the panel should not exist at all, otherwise the
   parked off-canvas element still contributes to document scroll width. */
@media (min-width: 1081px) {
  .mobile-nav { display: none; }
}

/* --------------------------------------------------------------------------
   7. HERO
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: min(796px, 88dvh);
  padding-block: clamp(64px, 8vw, 96px);
  overflow: hidden;
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.75) contrast(1.08);
}

/* Navy scrim rather than a flat black overlay, so the photography keeps its
   colour temperature while the copy stays at AA contrast. */
.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(13, 13, 13, 0.94) 0%, rgba(13, 13, 13, 0.82) 45%, rgba(13, 13, 13, 0.5) 100%),
    linear-gradient(180deg, rgba(13, 13, 13, 0.55) 0%, rgba(13, 13, 13, 0.25) 40%, rgba(13, 13, 13, 0.8) 100%);
}

.hero__inner { position: relative; z-index: 1; width: 100%; }
.hero__content { max-width: 780px; }

.hero__title { margin-bottom: var(--s-3); }
.hero__sub {
  font-size: clamp(1.0625rem, 1.7vw, 1.3125rem);
  line-height: 1.6;
  color: var(--fg-secondary);
  max-width: 56ch;
  margin-bottom: var(--s-5);
}
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s-2); }

/* Compact banner for interior pages */
.page-hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: clamp(300px, 42vh, 420px);
  padding-block: clamp(48px, 6vw, 72px);
  border-bottom: 1px solid var(--border);
  overflow: hidden;
}
.page-hero__media { position: absolute; inset: 0; z-index: 0; }
.page-hero__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: saturate(0.7) contrast(1.05);
}
.page-hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(13, 13, 13, 0.78) 0%, rgba(13, 13, 13, 0.9) 100%);
}
.page-hero__inner { position: relative; z-index: 1; width: 100%; }
.page-hero__title { margin-block: var(--s-2) var(--s-3); }
.page-hero__sub {
  font-size: clamp(1rem, 1.5vw, 1.1875rem);
  color: var(--fg-secondary);
  max-width: 60ch;
  margin: 0;
}

/* Breadcrumb */
.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-1);
  margin: 0 0 var(--s-2);
  padding: 0;
  list-style: none;
  font-size: var(--fs-xs);
  color: var(--fg-muted);
}
.breadcrumb li { margin: 0; display: flex; align-items: center; gap: var(--s-1); }
.breadcrumb li + li::before { content: "/"; color: var(--fg-muted); opacity: 0.6; }
.breadcrumb a { color: var(--fg-muted); }
.breadcrumb a:hover { color: var(--accent); }

/* --------------------------------------------------------------------------
   8. SECTION HEADERS
   -------------------------------------------------------------------------- */

.section-head { max-width: 760px; margin-bottom: var(--s-6); }
.section-head .overline { margin-bottom: var(--s-2); }
.section-head h2 { margin-bottom: var(--s-3); }
.section-head p { color: var(--fg-secondary); margin: 0; }
.section-head--center { margin-inline: auto; text-align: center; }
.section-head--center .overline { justify-content: center; }

/* --------------------------------------------------------------------------
   9. CARDS
   -------------------------------------------------------------------------- */

.card {
  display: flex;
  flex-direction: column;
  padding: var(--s-3);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  transition: transform var(--t-base) var(--ease),
              border-color var(--t-base) var(--ease),
              box-shadow var(--t-base) var(--ease);
}
.card__title { margin-bottom: var(--s-2); }
.card__body { color: var(--fg-secondary); font-size: var(--fs-sm); margin: 0; }
.card__foot { margin-top: auto; padding-top: var(--s-3); }

a.card:hover,
.card--interactive:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-md);
}

/* Accent rule across the top, used sparingly */
.card--accent { border-top: 3px solid var(--accent); }

/* Card with a photograph at the top */
.card--media { padding: 0; overflow: hidden; }
.card--media .card__media { position: relative; aspect-ratio: 16 / 10; overflow: hidden; }
.card--media .card__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: saturate(0.75) contrast(1.05);
  transition: transform var(--t-slow) var(--ease);
}
a.card--media:hover .card__media img { transform: scale(1.04); }
.card--media .card__inner { display: flex; flex-direction: column; flex: 1; padding: var(--s-3); }

/* Icon box. Maps to the Elementor icon-box widget. */
.icon-box { display: flex; flex-direction: column; gap: var(--s-2); }
.icon-box__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-card);
  color: var(--accent);
  flex: none;
}
.icon-box__icon .icon { width: 24px; height: 24px; }
.icon-box__title { margin: 0; }
.icon-box__body { font-size: var(--fs-sm); color: var(--fg-secondary); margin: 0; }

/* Numbered process step */
.step { display: flex; gap: var(--s-3); align-items: flex-start; }
.step__num {
  flex: none;
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--accent);
  border-radius: var(--r-card);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--accent);
}
.step__title { margin: 0 0 var(--s-1); }
.step__body { margin: 0; font-size: var(--fs-sm); color: var(--fg-secondary); }

/* --------------------------------------------------------------------------
   10. BENTO
   Cell count always matches the content count. No filler tiles.
   -------------------------------------------------------------------------- */

.bento { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.bento__cell {
  display: flex;
  flex-direction: column;
  position: relative;
  flex: 1 1 300px;
  min-height: 260px;
  padding: var(--s-4);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  overflow: hidden;
  transition: border-color var(--t-base) var(--ease),
              transform var(--t-base) var(--ease);
}
/* Fixed fractions rather than grow ratios, so four cells resolve to a
   deliberate 60/40 then 50/50 rhythm instead of wrapping 3 + 1 and orphaning
   the last tile. These percentages transfer straight to Elementor container
   widths. Gap is --s-3 (24px), so each cell gives back half of it. */
.bento__cell--lead { flex: 0 0 calc(60% - 12px); min-height: 420px; }
.bento__cell--sm   { flex: 0 0 calc(40% - 12px); }
.bento__cell--half { flex: 0 0 calc(50% - 12px); }
.bento__cell--wide { flex: 0 0 calc(100%); }

@media (max-width: 900px) {
  .bento__cell--lead,
  .bento__cell--sm,
  .bento__cell--half { flex-basis: 100%; min-height: 300px; }
}
a.bento__cell:hover { transform: translateY(-2px); border-color: var(--border-strong); }

/* Photographic bento cell */
.bento__cell--media { padding: 0; }
.bento__cell--media .bento__media { position: absolute; inset: 0; z-index: 0; }
.bento__cell--media .bento__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: saturate(0.7) contrast(1.08);
  transition: transform var(--t-slow) var(--ease);
}
.bento__cell--media .bento__media::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(13, 13, 13, 0.45) 0%, rgba(13, 13, 13, 0.92) 78%);
}
a.bento__cell--media:hover .bento__media img { transform: scale(1.05); }
.bento__cell--media .bento__inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: var(--s-4);
}

.bento__content { display: flex; flex-direction: column; flex: 1; }
.bento__title { margin-bottom: var(--s-2); }
.bento__body { font-size: var(--fs-sm); color: var(--fg-secondary); margin: 0; }
.bento__foot { margin-top: auto; padding-top: var(--s-4); }

/* --------------------------------------------------------------------------
   11. SPLIT SECTION
   -------------------------------------------------------------------------- */

.split { display: flex; flex-wrap: wrap; align-items: center; gap: clamp(32px, 5vw, 72px); }
.split__media { flex: 1 1 440px; min-width: 0; position: relative; }
/* Same plate treatment where a brand page shows the part full size. */
.split__media--plate {
  background: var(--plate);
  border-radius: var(--r-card);
  overflow: hidden;
}
.split__media--plate img {
  aspect-ratio: 4 / 3;
  object-fit: contain;
  padding: clamp(20px, 3.5vw, 44px);
  border-radius: 0;
}

.split__media img {
  width: 100%;
  border-radius: var(--r-card);
  filter: saturate(0.78) contrast(1.05);
}
.split__content { flex: 1 1 400px; min-width: 0; }
.split__content h2 { margin-bottom: var(--s-3); }

/* Small figure pinned to the corner of a split image */
.split__badge {
  position: absolute;
  right: calc(-1 * var(--s-3));
  bottom: calc(-1 * var(--s-3));
  padding: var(--s-3) var(--s-4);
  background: var(--accent-fill);
  border-radius: var(--r-card);
  max-width: 240px;
}
.split__badge .figure__value { color: #fff; }
.split__badge .figure__label { color: rgba(255, 255, 255, 0.9); }

@media (max-width: 900px) {
  .split__badge { position: static; margin-top: var(--s-3); max-width: none; }
}

/* --------------------------------------------------------------------------
   12. FIGURES
   Only verified numbers appear on this site. Nothing invented.
   -------------------------------------------------------------------------- */

.figures {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
}
.figure { flex: 1 1 200px; min-width: 0; padding-top: var(--s-3); border-top: 2px solid var(--accent); }
.figure__value {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 4.5vw, 3.25rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--fg-primary);
}
.figure__label {
  display: block;
  margin-top: var(--s-1);
  font-size: var(--fs-sm);
  color: var(--fg-secondary);
}

/* --------------------------------------------------------------------------
   13. BRAND LOGO WALL
   Logos only. No category labels underneath.
   -------------------------------------------------------------------------- */

/* Eight logos of differing aspect ratios. Fixed fractional widths give a
   deliberate 4 + 4 at desktop and 2 + 2 + 2 + 2 on mobile, instead of the
   ragged orphan row that auto-width flex items produce. */
.logo-wall {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--s-4);
}
.logo-wall__item {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 calc(25% - var(--s-4));
  padding: var(--s-2);
}
.logo-wall__item img {
  height: clamp(28px, 3.2vw, 40px);
  width: auto;
  max-width: 100%;
  object-fit: contain;
  opacity: 0.72;
  filter: brightness(0) invert(1);
  transition: opacity var(--t-base) var(--ease);
}
.logo-wall__item:hover img { opacity: 1; }

@media (max-width: 700px) {
  .logo-wall__item { flex-basis: calc(50% - var(--s-4)); }
}

/* --------------------------------------------------------------------------
   14. BRAND CARDS
   -------------------------------------------------------------------------- */

.brand-card {
  display: flex;
  flex-direction: column;
  flex: 1 1 280px;
  min-width: 0;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  overflow: hidden;
  transition: transform var(--t-base) var(--ease),
              border-color var(--t-base) var(--ease),
              box-shadow var(--t-base) var(--ease);
}
.brand-card:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-md);
}
.brand-card__media {
  position: relative;
  aspect-ratio: 1 / 1;
  /* Manufacturer product photography is shot on white. Rather than let a white
     rectangle punch a hole in a dark page, it sits on a deliberate light plate
     with even padding, the way a spec sheet presents a part. */
  background: var(--plate);
  overflow: hidden;
}
.brand-card__media img {
  width: 100%; height: 100%;
  object-fit: contain;
  padding: var(--s-4);
  transition: transform var(--t-slow) var(--ease);
}
.brand-card:hover .brand-card__media img { transform: scale(1.04); }

.brand-card__inner {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: var(--s-3);
  border-top: 1px solid var(--border);
}
/* align-self matters here. In a column flex parent the default stretch makes
   width:auto resolve to the full container width, which flattens the logo to
   its declared height and destroys the aspect ratio. */
.brand-card__logo {
  height: 26px;
  width: auto;
  max-width: 70%;
  object-fit: contain;
  object-position: left center;
  align-self: flex-start;
  margin-bottom: var(--s-2);
  filter: brightness(0) invert(1);
  opacity: 0.9;
}
.brand-card__name {
  font-family: var(--font-display);
  font-size: 1.375rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: var(--fg-primary);
  margin: 0 0 var(--s-1);
}
.brand-card__desc { font-size: var(--fs-sm); color: var(--fg-secondary); margin: 0; }
.brand-card__foot { margin-top: auto; padding-top: var(--s-3); }

/* --------------------------------------------------------------------------
   15. INDUSTRY TILES
   -------------------------------------------------------------------------- */

.tile {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  flex: 1 1 260px;
  min-width: 0;
  min-height: 340px;
  padding: var(--s-4);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  overflow: hidden;
}
.tile__media { position: absolute; inset: 0; z-index: 0; }
.tile__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: saturate(0.65) contrast(1.1);
  transition: transform var(--t-slow) var(--ease);
}
.tile__media::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(13, 13, 13, 0.35) 0%, rgba(13, 13, 13, 0.92) 75%);
  transition: background var(--t-base) var(--ease);
}
.tile:hover .tile__media img { transform: scale(1.06); }
.tile__inner { position: relative; z-index: 1; }
.tile__title {
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--fg-primary);
  margin: 0 0 var(--s-1);
}
.tile__body { font-size: var(--fs-sm); color: var(--fg-secondary); margin: 0; }
.tile__inner .arrow-link { margin-top: var(--s-3); }

/* --------------------------------------------------------------------------
   16. ACCORDION
   Maps to the Elementor accordion widget.
   -------------------------------------------------------------------------- */

.accordion { border-top: 1px solid var(--border); }
.accordion__item { border-bottom: 1px solid var(--border); }
.accordion__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  width: 100%;
  padding: var(--s-3) 0;
  background: transparent;
  border: 0;
  color: var(--fg-primary);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: color var(--t-fast) var(--ease);
}
.accordion__trigger:hover { color: var(--accent); }
.accordion__icon {
  flex: none;
  width: 20px; height: 20px;
  color: var(--accent);
  transition: transform var(--t-base) var(--ease);
}
.accordion__trigger[aria-expanded="true"] .accordion__icon { transform: rotate(45deg); }
.accordion__panel { display: none; padding-bottom: var(--s-3); }
.accordion__panel.is-open { display: block; }
.accordion__panel p { font-size: var(--fs-sm); color: var(--fg-secondary); }

/* --------------------------------------------------------------------------
   17. PRODUCT RANGE LIST
   Used where a brand has a long product range. Chunked into columns rather
   than one long hairline-separated list.
   -------------------------------------------------------------------------- */

.range { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.range__item {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex: 1 1 260px;
  min-width: 0;
  padding: var(--s-2) var(--s-3);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  font-size: var(--fs-sm);
  color: var(--fg-secondary);
}
.range__item .icon { width: 16px; height: 16px; color: var(--accent); flex: none; }

/* --------------------------------------------------------------------------
   18. RESOURCE / DOWNLOAD ROW
   -------------------------------------------------------------------------- */

.download {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex: 1 1 340px;
  min-width: 0;
  padding: var(--s-3);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  transition: transform var(--t-base) var(--ease),
              border-color var(--t-base) var(--ease);
}
.download:hover { transform: translateY(-2px); border-color: var(--accent); }
.download__icon {
  flex: none;
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-card);
  color: var(--accent);
}
.download__icon .icon { width: 22px; height: 22px; }
.download__text { min-width: 0; }
.download__title {
  display: block;
  font-weight: 600;
  color: var(--fg-primary);
  font-size: var(--fs-body);
  line-height: 1.3;
}
.download__meta {
  display: block;
  margin-top: 2px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--fg-muted);
  text-transform: uppercase;
}
.download__arrow { margin-left: auto; flex: none; color: var(--accent); }
.download__arrow .icon { width: 20px; height: 20px; }

/* --------------------------------------------------------------------------
   19. ARTICLE CARDS
   -------------------------------------------------------------------------- */

.article {
  display: flex;
  flex-direction: column;
  flex: 1 1 300px;
  min-width: 0;
  padding: var(--s-4);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent);
  border-radius: var(--r-card);
  transition: transform var(--t-base) var(--ease),
              box-shadow var(--t-base) var(--ease);
}
.article:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.article__title {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1.1;
  color: var(--fg-primary);
  margin: 0 0 var(--s-2);
}
.article__excerpt { font-size: var(--fs-sm); color: var(--fg-secondary); margin: 0; }
.article__foot { margin-top: auto; padding-top: var(--s-4); }

/* --------------------------------------------------------------------------
   20. CTA BAND
   -------------------------------------------------------------------------- */

.cta-band {
  position: relative;
  padding-block: clamp(64px, 8vw, 104px);
  overflow: hidden;
  border-top: 1px solid var(--border);
}
.cta-band__media { position: absolute; inset: 0; z-index: 0; }
.cta-band__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: saturate(0.5) contrast(1.1);
}
.cta-band__media::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(13, 13, 13, 0.95) 0%, rgba(13, 13, 13, 0.86) 60%, rgba(13, 13, 13, 0.7) 100%);
}
.cta-band__inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
}
.cta-band__text { flex: 1 1 480px; min-width: 0; }
.cta-band__text h2 { margin-bottom: var(--s-2); }
.cta-band__text p { color: var(--fg-secondary); margin: 0; max-width: 52ch; }
.cta-band__actions { flex: none; display: flex; flex-wrap: wrap; gap: var(--s-2); }

/* --------------------------------------------------------------------------
   21. FORMS
   Labels sit above inputs, helper text below. Never a placeholder as a label.
   -------------------------------------------------------------------------- */

.form { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.field { display: flex; flex-direction: column; gap: var(--s-1); flex: 1 1 260px; min-width: 0; }
.field--full { flex-basis: 100%; }

.field__label {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--fg-primary);
}
.field__label .req { color: var(--accent); }

.field__input,
.field__select,
.field__textarea {
  width: 100%;
  padding: 12px 14px;
  background: var(--ink-900);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-btn);
  color: var(--fg-primary);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.5;
  transition: border-color var(--t-fast) var(--ease),
              box-shadow var(--t-fast) var(--ease);
}
.field__textarea { min-height: 140px; resize: vertical; }

/* Placeholder passes AA against the ink-900 field background */
.field__input::placeholder,
.field__textarea::placeholder { color: #8c8c8c; opacity: 1; }

.field__input:focus,
.field__select:focus,
.field__textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(227, 82, 0, 0.25);
}

.field__select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b4b4b4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 18px;
  padding-right: 40px;
}

.field__help { font-size: var(--fs-xs); color: var(--fg-muted); }
.field__error { font-size: var(--fs-xs); color: #ff8a5c; display: none; }
.field.has-error .field__input,
.field.has-error .field__select,
.field.has-error .field__textarea { border-color: #ff8a5c; }
.field.has-error .field__error { display: block; }

.form__foot { flex-basis: 100%; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); }

.form-status {
  flex-basis: 100%;
  display: none;
  padding: var(--s-3);
  border-radius: var(--r-card);
  font-size: var(--fs-sm);
}
.form-status.is-visible { display: block; }
/* In-flight state, so the visitor is not left staring at a disabled button
   wondering whether anything happened. */
.form-status--info {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border-strong);
  color: var(--fg-secondary);
}
.form-status--success {
  background: rgba(227, 82, 0, 0.12);
  border: 1px solid var(--accent);
  color: var(--fg-primary);
}
.form-status--error {
  background: rgba(255, 138, 92, 0.1);
  border: 1px solid #ff8a5c;
  color: var(--fg-primary);
}

/* --------------------------------------------------------------------------
   22. CONTACT BLOCKS
   -------------------------------------------------------------------------- */

.contact-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  flex: 1 1 280px;
  min-width: 0;
  padding: var(--s-4);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent);
  border-radius: var(--r-card);
}
.contact-card__label {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--fg-primary);
  margin: 0;
}
.contact-card__row { display: flex; align-items: center; gap: var(--s-2); font-size: var(--fs-body); }
.contact-card__row .icon { width: 18px; height: 18px; color: var(--accent); flex: none; }
.contact-card__row a { color: var(--fg-secondary); }
.contact-card__row a:hover { color: var(--accent); }

.map-embed {
  width: 100%;
  aspect-ratio: 16 / 9;
  min-height: 320px;
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--bg-elevated);
}
.map-embed iframe { width: 100%; height: 100%; border: 0; display: block; filter: grayscale(1) invert(0.92) contrast(0.88); }

/* --------------------------------------------------------------------------
   23. FOOTER
   -------------------------------------------------------------------------- */

.footer {
  background: var(--ink-800);
  border-top: 1px solid var(--border);
  padding-top: var(--s-10);
}
.footer__top { display: flex; flex-wrap: wrap; gap: var(--s-6); padding-bottom: var(--s-8); }
.footer__brand { flex: 1.4 1 300px; min-width: 0; }
.footer__logo img { height: 64px; width: auto; margin-bottom: var(--s-3); }
.footer__tagline { font-size: var(--fs-sm); color: var(--fg-secondary); max-width: 38ch; margin: 0 0 var(--s-3); }

.footer__col { flex: 1 1 190px; min-width: 0; }
.footer__heading {
  font-family: var(--font-display);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-primary);
  margin: 0 0 var(--s-3);
}
.footer__list { margin: 0; padding: 0; list-style: none; }
.footer__list li { margin-bottom: var(--s-1); }
.footer__list a { font-size: var(--fs-sm); color: var(--fg-secondary); }
.footer__list a:hover { color: var(--accent); }

.footer__address { font-size: var(--fs-sm); color: var(--fg-secondary); font-style: normal; }
.footer__address a { color: var(--fg-secondary); }
.footer__address a:hover { color: var(--accent); }

.socials { display: flex; gap: var(--s-2); margin-top: var(--s-3); }
.socials a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-card);
  color: var(--fg-secondary);
  transition: color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease);
}
.socials a:hover { color: var(--accent); border-color: var(--accent); }
.socials .icon { width: 18px; height: 18px; }

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  padding-block: var(--s-3);
  border-top: 1px solid var(--border);
  font-size: var(--fs-xs);
  color: var(--fg-muted);
}
.footer__bottom a { color: var(--fg-muted); }
.footer__bottom a:hover { color: var(--accent); }
.footer__legal { display: flex; flex-wrap: wrap; gap: var(--s-3); }

/* --------------------------------------------------------------------------
   24. 404
   -------------------------------------------------------------------------- */

.notfound {
  display: flex;
  align-items: center;
  min-height: 70dvh;
  padding-block: var(--s-10);
}
.notfound__code {
  font-family: var(--font-display);
  font-size: clamp(5rem, 18vw, 12rem);
  font-weight: 800;
  line-height: 0.85;
  letter-spacing: -0.04em;
  color: var(--accent);
  margin: 0 0 var(--s-3);
}

/* --------------------------------------------------------------------------
   25. PROSE (privacy policy and other long-form pages)
   -------------------------------------------------------------------------- */

.prose { max-width: 76ch; }
.prose h2 { font-size: clamp(1.5rem, 3vw, 2rem); margin: var(--s-6) 0 var(--s-2); }
.prose h3 {
  font-family: var(--font-body);
  font-size: 1.125rem;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
  color: var(--fg-primary);
  margin: var(--s-5) 0 var(--s-2);
}
.prose h2:first-child,
.prose h3:first-child { margin-top: 0; }
.prose ul { padding-left: 1.25em; }
.prose li { color: var(--fg-secondary); }
.prose a { color: var(--fg-primary); border-bottom: 1px solid var(--accent); }
.prose a:hover { color: var(--accent); }

.meta-block {
  padding: var(--s-3);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-card);
  font-size: var(--fs-sm);
  margin-bottom: var(--s-6);
}
.meta-block p { margin-bottom: var(--s-1); }

/* --------------------------------------------------------------------------
   26. SCROLL REVEAL
   Driven by IntersectionObserver in main.js. Never a scroll event listener.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .reveal {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity var(--t-slow) var(--ease),
                transform var(--t-slow) var(--ease);
  }
  .reveal.is-visible { opacity: 1; transform: none; }
  .reveal[data-delay="1"] { transition-delay: 80ms; }
  .reveal[data-delay="2"] { transition-delay: 160ms; }
  .reveal[data-delay="3"] { transition-delay: 240ms; }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   27. PRINT
   -------------------------------------------------------------------------- */

@media print {
  .header, .footer, .cta-band, .nav-toggle, .mobile-nav { display: none !important; }
  body { background: #fff; color: #000; }
  h1, h2, h3, h4 { color: #000; }
}

/* ==========================================================================
   28. MOTION LAYER
   DESIGN_VARIANCE 8 / MOTION_INTENSITY 8

   WORDPRESS NOTE
   Everything below is presentation and motion only. No layout depends on it.
   Ship this block plus the matching section of main.js as a small mu-plugin
   or via Elementor > Custom Code, and the Elementor containers underneath
   stay completely standard. Strip it and the site still works, just static.

   Every effect animates transform, opacity or clip-path only, and every one
   collapses under prefers-reduced-motion at the end of this section.
   ========================================================================== */

/* --- 28.1 Film grain -------------------------------------------------------
   Fixed and pointer-events:none so it never repaints on scroll. Applied to
   body::after, which means no page markup has to change. */

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 300;
  pointer-events: none;
  opacity: 0.04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* --- 28.2 Headline word reveal ---------------------------------------------
   main.js wraps each word of [data-split] in .w > span. The outer span is the
   mask, the inner one travels. Uppercase display type has no descenders, so
   the mask never clips a glyph. */

.w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: 0.06em;   /* reserve for the apostrophe and comma tails */
  margin-bottom: -0.06em;
}
.w > span {
  display: inline-block;
  will-change: transform;
}

@media (prefers-reduced-motion: no-preference) {
  [data-split].is-armed .w > span {
    transform: translateY(105%) rotate(2deg);
  }
  [data-split].is-revealed .w > span {
    transform: none;
    transition: transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
    transition-delay: calc(var(--i, 0) * 55ms);
  }
}

/* --- 28.3 Scroll reveal variants ------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .reveal {
    opacity: 0;
    transform: translateY(28px);
    transition: opacity 800ms cubic-bezier(0.16, 1, 0.3, 1),
                transform 800ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .reveal.is-visible { opacity: 1; transform: none; }

  /* Wipe. Used on photography so images arrive rather than fade. */
  .reveal--mask {
    opacity: 1;
    transform: none;
    clip-path: inset(0 0 100% 0);
    transition: clip-path 1000ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .reveal--mask.is-visible { clip-path: inset(0 0 0 0); }
  .reveal--mask img {
    transform: scale(1.12);
    transition: transform 1400ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .reveal--mask.is-visible img { transform: scale(1); }

  .reveal--left  { transform: translateX(-32px); }
  .reveal--right { transform: translateX(32px); }
  .reveal--scale { transform: scale(0.94); }

  /* Auto-stagger: main.js stamps --i on each child of [data-stagger] */
  [data-stagger] > .reveal { transition-delay: calc(var(--i, 0) * 90ms); }

  .reveal[data-delay="1"] { transition-delay: 90ms; }
  .reveal[data-delay="2"] { transition-delay: 180ms; }
  .reveal[data-delay="3"] { transition-delay: 270ms; }
}

/* --- 28.4 Parallax ---------------------------------------------------------
   main.js writes --py while the element is in view. Driven by an
   IntersectionObserver-gated rAF loop, never a scroll event listener. */

.hero__media img,
.page-hero__media img,
.cta-band__media img {
  will-change: transform;
  transform: translate3d(0, var(--py, 0px), 0) scale(1.14);
}

/* --- 28.5 Cursor spotlight on interactive surfaces ------------------------- */

.bento__cell,
.tile,
.brand-card,
.article,
.download,
.card {
  --mx: 50%;
  --my: 50%;
}

.bento__cell::before,
.tile::before,
.article::before,
.card--interactive::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(520px circle at var(--mx) var(--my),
              rgba(227, 82, 0, 0.16), transparent 42%);
  transition: opacity var(--t-base) var(--ease);
}
.bento__cell:hover::before,
.tile:hover::before,
.article:hover::before,
.card--interactive:hover::before { opacity: 1; }

/* Keep content above the glow */
.bento__inner,
.bento__content,
.tile__inner { position: relative; z-index: 2; }
.article > * { position: relative; z-index: 2; }

/* --- 28.6 Pointer tilt -----------------------------------------------------
   Subtle. Four degrees maximum, so it reads as material rather than as a toy. */

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .tilt {
    transform: perspective(900px)
               rotateX(calc(var(--ty, 0) * -3.5deg))
               rotateY(calc(var(--tx, 0) * 3.5deg))
               translateY(var(--lift, 0px));
    transform-style: preserve-3d;
    transition: transform 420ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .tilt.is-tilting { transition: transform 90ms linear; }
}

/* --- 28.7 Buttons: directional sweep + magnetic pull ----------------------- */

.btn { position: relative; overflow: hidden; isolation: isolate; }

.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  transform: scaleX(0);
  transform-origin: var(--origin, left) center;
  transition: transform 420ms cubic-bezier(0.16, 1, 0.3, 1);
}
.btn--primary::before { background: var(--accent-fill-hover); }
.btn--secondary::before { background: rgba(255, 255, 255, 0.14); }
.btn--primary:hover::before,
.btn--secondary:hover::before { transform: scaleX(1); }

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .btn--magnetic {
    transform: translate3d(var(--bx, 0px), var(--by, 0px), 0);
    transition: transform 500ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .btn--magnetic.is-pulling { transition: transform 120ms linear; }
}

/* --- 28.8 Logo marquee -----------------------------------------------------
   One marquee per page. main.js clones the track for a seamless loop. */

.marquee {
  position: relative;
  overflow: hidden;
  /* fade the ends so logos enter and leave rather than being cut */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee__track {
  display: flex;
  align-items: center;
  gap: clamp(40px, 6vw, 96px);
  width: max-content;
  padding-block: var(--s-2);
}
.marquee__item { flex: none; display: flex; align-items: center; }
.marquee__item img {
  height: clamp(28px, 3vw, 38px);
  width: auto;
  opacity: 0.6;
  filter: brightness(0) invert(1);
  transition: opacity var(--t-base) var(--ease);
}
.marquee__item:hover img { opacity: 1; }

@media (prefers-reduced-motion: no-preference) {
  .marquee.is-running .marquee__track {
    animation: marquee var(--speed, 46s) linear infinite;
  }
  .marquee:hover .marquee__track { animation-play-state: paused; }
}
@keyframes marquee {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* --- 28.9 Counters --------------------------------------------------------- */

.figure__value { font-variant-numeric: tabular-nums; }

/* --- 28.10 Accent rule draw-in --------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .overline::before {
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 700ms cubic-bezier(0.16, 1, 0.3, 1) 200ms;
  }
  .reveal.is-visible .overline::before,
  .is-visible > .overline::before,
  .hero.is-loaded .overline::before { transform: scaleX(1); }

  .figure {
    background-image: linear-gradient(var(--accent), var(--accent));
    background-repeat: no-repeat;
    background-position: top left;
    background-size: 0 2px;
    border-top-color: transparent;
    transition: background-size 800ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .figure.is-visible { background-size: 100% 2px; }
}

/* --- 28.11 Hero entrance ---------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .hero__sub,
  .hero__actions,
  .hero .overline {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 800ms cubic-bezier(0.16, 1, 0.3, 1),
                transform 800ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .hero.is-loaded .overline     { opacity: 1; transform: none; transition-delay: 120ms; }
  .hero.is-loaded .hero__sub    { opacity: 1; transform: none; transition-delay: 620ms; }
  .hero.is-loaded .hero__actions{ opacity: 1; transform: none; transition-delay: 740ms; }
}

/* --- 28.12 Reduced motion: hard stop --------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  body::after { display: none; }
  .w, .w > span { overflow: visible; transform: none !important; }
  .reveal,
  .reveal--mask,
  .reveal--left,
  .reveal--right,
  .reveal--scale {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }
  .reveal--mask img { transform: none !important; }
  .hero__media img,
  .page-hero__media img,
  .cta-band__media img { transform: scale(1.02) !important; }
  .hero .overline,
  .hero__sub,
  .hero__actions { opacity: 1 !important; transform: none !important; }
  .marquee__track { animation: none !important; }
  .tilt, .btn--magnetic { transform: none !important; }
  .overline::before { transform: scaleX(1) !important; }
  .figure { background-size: 100% 2px !important; border-top-color: var(--accent) !important; }
}

/* --------------------------------------------------------------------------
   29. BRAND MARK
   A manufacturer logo shown inline on a dark section. The supplied artwork is
   dark-on-transparent, so without knocking it to white it disappears into the
   page. Same treatment as the logo wall, so the two always match.
   -------------------------------------------------------------------------- */

.brand-mark {
  height: 30px;
  width: auto;
  max-width: 190px;
  object-fit: contain;
  object-position: left center;
  align-self: flex-start;
  margin-bottom: var(--s-3);
  filter: brightness(0) invert(1);
  opacity: 0.85;
}

/* --------------------------------------------------------------------------
   30. REVEAL FAIL-OPEN
   The reveal styles hide content until an observer says otherwise, which means
   a failed or suspended IntersectionObserver leaves a section permanently
   blank. main.js only adds .has-reveal once it is actually able to run the
   observers, so with no JavaScript, a JS error, or a stalled observer the page
   renders fully visible instead of empty. Content is never gated on animation.
   -------------------------------------------------------------------------- */

html:not(.has-reveal) .reveal,
html:not(.has-reveal) .reveal--mask,
html:not(.has-reveal) .reveal--left,
html:not(.has-reveal) .reveal--right,
html:not(.has-reveal) .reveal--scale {
  opacity: 1 !important;
  transform: none !important;
  clip-path: none !important;
}
html:not(.has-reveal) .reveal--mask img { transform: none !important; }
html:not(.has-reveal) .hero .overline,
html:not(.has-reveal) .hero__sub,
html:not(.has-reveal) .hero__actions { opacity: 1 !important; transform: none !important; }
html:not(.has-reveal) .figure { background-size: 100% 2px !important; border-top-color: var(--accent) !important; }

/* ==========================================================================
   31. V3 HERO TREATMENT
   The v1 layout and lockup are kept exactly as they are. What changes is the
   hero: v2's flow field and heat bloom are brought across, so the page opens
   with the fluid-under-pressure idea and then settles into v1's structure.
   ========================================================================== */

:root {
  /* Two lifted stops so the bloom has somewhere to glow above the brand orange */
  --heat-0: #ffc48a;
  --heat-1: #ff7a18;
}

/* Radial heat. Pressure concentrating, not a decorative gradient. Sized
   against the viewport so it stays a glow on a phone rather than a wash. */
.bloom {
  position: absolute;
  pointer-events: none;
  border-radius: 50%;
  filter: blur(72px);
  opacity: 0.4;
  background: radial-gradient(circle, var(--accent) 0%, rgba(227, 82, 0, 0.26) 42%, transparent 70%);
}
.bloom--md   { width: clamp(330px, 46vw, 620px); aspect-ratio: 1; }
.bloom--lg   { width: clamp(460px, 66vw, 980px); aspect-ratio: 1; filter: blur(110px); opacity: 0.32; }
.bloom--core { background: radial-gradient(circle, var(--heat-0) 0%, var(--heat-1) 30%, transparent 68%); }

/* The canvas sits over the photograph and under the copy */
.hero__canvas { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.hero__canvas canvas { width: 100%; height: 100%; display: block; }
.hero .container { z-index: 2; }

/* Cooled back so the flow lines and the bloom carry the colour */
.hero__media img { filter: grayscale(0.92) contrast(1.2) brightness(0.5); }
.hero__media::after {
  background:
    radial-gradient(110% 90% at 10% 92%, rgba(227, 82, 0, 0.2) 0%, transparent 56%),
    linear-gradient(90deg, rgba(13, 13, 13, 0.92) 0%, rgba(13, 13, 13, 0.72) 48%, rgba(13, 13, 13, 0.42) 100%),
    linear-gradient(180deg, rgba(13, 13, 13, 0.5) 0%, rgba(13, 13, 13, 0.2) 38%, rgba(13, 13, 13, 0.88) 100%);
}

/* One phrase per page in heat, same rule as v2. Solid, never a clipped
   gradient, which fails on any inline element spanning two lines. */
.hot { color: var(--heat-1); }

/* --------------------------------------------------------------------------
   32. BRAND GRID
   Nine brands, so a three-column grid divides perfectly into three clean rows
   with no orphan. A two-column arrangement leaves one card stranded and, at
   this card width, opens up the large gaps that made the grid look unfinished.
   Below 720px it drops straight to a single column rather than passing through
   a two-up, which would reintroduce the orphan on the narrowest screens.
   -------------------------------------------------------------------------- */

.brand-card { flex: 0 0 calc((100% - 2 * var(--s-4)) / 3); }

@media (max-width: 720px) {
  .brand-card { flex-basis: 100%; }
}

/* ==========================================================================
   33. V4
   ========================================================================== */

/* --- Hero circuit ---------------------------------------------------------
   The hero subject is drawn, not photographed: a canvas fills the section and
   an isometric manifold assembles inside it. No image request, no decode, and
   it composes to whatever box it is given, so the same code carries a wide
   desktop hero and a tall phone one.

   Line art is far lighter over the ground than the photograph it replaced, so
   the scrim can back off and let the drawing read while the lockup still holds
   contrast. The drawing is deliberately weighted right of the copy column. --- */

.hero__circuit {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
.hero__circuit canvas { display: block; width: 100%; height: 100%; }

.hero__circuit::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 100% at 6% 94%, rgba(227, 82, 0, 0.16) 0%, transparent 58%),
    linear-gradient(90deg,
      rgba(13, 13, 13, 0.62) 0%,
      rgba(13, 13, 13, 0.42) 32%,
      rgba(13, 13, 13, 0.12) 58%,
      rgba(13, 13, 13, 0) 78%,
      rgba(13, 13, 13, 0) 100%),
    linear-gradient(180deg,
      rgba(13, 13, 13, 0.30) 0%,
      rgba(13, 13, 13, 0) 34%,
      rgba(13, 13, 13, 0.42) 100%);
}

/* A portrait hero has no room beside the lockup, so the circuit takes the top
   and the copy sits under it on ground dark enough to hold AA. */
@media (max-width: 900px) {
  .hero { align-items: flex-end; }
  .hero__circuit { inset: 0 0 34% 0; }
  .hero__circuit::after {
    inset: 0 0 -52% 0;
    background:
      radial-gradient(130% 60% at 12% 98%, rgba(227, 82, 0, 0.16) 0%, transparent 62%),
      linear-gradient(180deg,
        rgba(13, 13, 13, 0.24) 0%,
        rgba(13, 13, 13, 0.04) 26%,
        rgba(13, 13, 13, 0.62) 52%,
        rgba(13, 13, 13, 0.92) 68%,
        #0d0d0d 78%,
        #0d0d0d 100%);
  }
}

/* --- Drafted rules --------------------------------------------------------
   The hero says the same thing the company does: fluid moves through the
   channels you cut for it. The site is already full of hairlines, so rather
   than laying new artwork over the photography, the rules it already has
   become the channels. A divider draws itself left to right the first time it
   is reached, and the rule above the footer carries a slow pressure the whole
   time it is on screen.

   One line each, never a mesh. Nothing sits over an image, no copy moves, and
   the whole effect is two pseudo-elements.
   --------------------------------------------------------------------------- */

.section--divided {
  position: relative;
  border-top-color: transparent;    /* keeps the 1px box, hands the ink to ::before */
}
.section--divided::before {
  content: "";
  position: absolute;
  top: -1px; left: 0; right: 0;
  height: 1px;
  background: var(--border);
  transform-origin: left;
}

.footer { position: relative; }
.footer::before {
  content: "";
  position: absolute;
  top: -1px; left: 0; right: 0;
  height: 1px;
  pointer-events: none;
  background-image: linear-gradient(90deg,
    rgba(255, 168, 92, 0) 40%,
    rgba(255, 178, 110, 0.85) 50%,
    rgba(255, 168, 92, 0) 60%);
  background-size: 240% 100%;
  background-repeat: no-repeat;
  background-position: -140% 0;
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .section--divided::before {
    transform: scaleX(0);
    transition: transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .section--divided.is-ruled::before { transform: scaleX(1); }

  .footer.is-flowing::before {
    opacity: 1;
    animation: trace-pressure 9s linear infinite;
  }
}

@keyframes trace-pressure {
  from { background-position: -140% 0; }
  to   { background-position: 240% 0; }
}

/* --- Process flow line ----------------------------------------------------
   The one place on the site where motion carries information rather than
   character: the route from an enquiry to a running system is a sequence, and
   the connector makes that sequence visible. Each segment draws downward as
   its step reveals, so the line assembles in reading order, and a slow
   pressure travels it while the section is on screen, which is the same idea
   as the hero galleries at a whisper.

   The segment hangs off .step rather than off the badge so it spans whatever
   height the body copy happens to take, and it stops before the last step
   because there is nothing after Support to flow into.
   --------------------------------------------------------------------------- */

.stack--flow { position: relative; }
.stack--flow .step { position: relative; }

.stack--flow .step::after {
  content: "";
  position: absolute;
  left: 21px;                       /* centre of the 44px step badge */
  top: 52px;                        /* clear of the badge */
  bottom: calc(-1 * var(--s-6) - 4px);
  width: 1px;
  background-color: var(--border-strong);
  background-image: linear-gradient(180deg,
    transparent 0%,
    rgba(255, 150, 70, 0) 38%,
    rgba(255, 168, 92, 0.85) 50%,
    rgba(255, 150, 70, 0) 62%,
    transparent 100%);
  background-size: 100% 260%;
  background-repeat: no-repeat;
  background-position: 0 -160%;
  transform: scaleY(0);
  transform-origin: top;
}
.stack--flow .step:last-child::after { content: none; }

@media (prefers-reduced-motion: no-preference) {
  .stack--flow .step::after {
    transition: transform 620ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .stack--flow .step.is-visible::after { transform: scaleY(1); }
  /* Pressure only runs once the route is drawn and only while it is being
     looked at; the class comes off the moment the section leaves. */
  .stack--flow.is-flowing .step.is-visible::after {
    animation: flow-pressure 4.2s linear infinite;
  }
  .stack--flow.is-flowing .step:nth-child(2)::after { animation-delay: 0.22s; }
  .stack--flow.is-flowing .step:nth-child(3)::after { animation-delay: 0.44s; }
  .stack--flow.is-flowing .step:nth-child(4)::after { animation-delay: 0.66s; }
}

@media (prefers-reduced-motion: reduce) {
  /* The connector still has to exist, because it is what shows the sequence.
     It simply arrives without drawing itself and nothing travels it. */
  .stack--flow .step::after { transform: scaleY(1); background-image: none; }
}

@keyframes flow-pressure {
  from { background-position: 0 -160%; }
  to   { background-position: 0 260%; }
}

/* Fail open. Both of these resting states hide a line that carries meaning:
   the connector shows the sequence and the divider separates two sections. If
   the scripts never run, the same gate the reveal system uses hands both back
   at full size rather than leaving the page missing its rules. */
html:not(.has-reveal) .stack--flow .step::after { transform: scaleY(1); }
html:not(.has-reveal) .section--divided::before { transform: none; }

/* --- Industry tiles -------------------------------------------------------
   Titles sat at different heights because the bodies run to two or three
   lines and the content is bottom-aligned, so Industrial rode higher than the
   rest. Reserving three lines squares every title across the row. */

.tile__body {
  /* Every description is padded to the height of the longest one, so the four
     titles sit on one line. Nothing is clamped, so no copy is ever cut off;
     the shorter descriptions simply carry a little air beneath them. */
  min-height: 8.5em;
}
@media (max-width: 1080px) {
  .tile__body { min-height: 0; }
}

/* --- Product plate --------------------------------------------------------
   Manufacturer product shots arrive cut out on white. A white plate keeps
   them consistent instead of each one punching its own hole in the page. */

.plate-media {
  background: var(--plate);
  border-radius: var(--r-card);
  overflow: hidden;
}
.plate-media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  padding: clamp(20px, 3.5vw, 48px);
}

/* ===================== 34. SPEC LIST (brand model cards) ===================== */
.spec-list{
  list-style:none;
  margin:var(--s-3) 0 0;
  padding:0;
  display:flex;
  flex-direction:column;
  border-top:1px solid var(--border);
}
.spec-list li{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:var(--s-2);
  padding:0.55rem 0;
  border-bottom:1px solid var(--border);
}
.spec-list li span{
  font-family:var(--font-mono);
  font-size:0.6875rem;
  letter-spacing:0.08em;
  text-transform:uppercase;
  color:var(--fg-muted);
  flex:0 0 auto;
}
.spec-list li strong{
  font-weight:600;
  font-size:0.875rem;
  color:var(--fg-primary);
  text-align:right;
}

/* ===================== 35. CLOSING TAGLINE ===================== */
.tagline-mark{
  margin-top:var(--s-5);
  padding-top:var(--s-3);
  border-top:2px solid var(--accent);
  display:inline-block;
  font-family:var(--font-display);
  font-size:var(--fs-h4);
  line-height:1.15;
  letter-spacing:0.01em;
  text-transform:uppercase;
  color:var(--fg-primary);
}

/* Honeypot field: removed from view and from the tab order without using
   display:none, which some bots detect and skip. */
.field--trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
