/* site/css/v2.css — v2 additions on top of components.css (v0.12.0).
   Shared by home, products and solutions pages. Tokens only, no new colours. */

/* Secondary button: hairline outline, same metrics as .btn */
.btn--secondary {
  background: transparent;
  color: var(--text-primary);
  box-shadow: inset 0 0 0 1px var(--border-interactive);
}

@media (hover: hover) and (pointer: fine) {
  .btn--secondary:hover {
    color: var(--text-accent);
    box-shadow: inset 0 0 0 1px var(--accent);
  }
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

/* Product card = .plate-card + one line + two actions.
   Actions sit above the heading link's whole-card overlay (z-index 1). */
.product-group + .product-group {
  margin-top: var(--space-9);
}

.product-group-title {
  margin-top: var(--space-6);
}

.plate-gen {
  display: block;
  margin-top: var(--space-1);
  font-family: var(--type-label-font);
  font-size: var(--type-label-size);
  letter-spacing: var(--type-label-tracking);
  text-transform: uppercase;
  color: var(--text-accent);
}

.plate-line {
  margin-top: var(--space-2);
  color: var(--text-secondary);
  font-size: var(--size-sm);
  line-height: var(--type-body-line);
}

.plate-actions {
  position: relative;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: auto;
  padding-top: var(--space-4);
}

/* "What we recover" (W5): bento on desktop, 2-col bento on tablet, swipe
   carousel on phone. Every photo is object-fit: cover inside a sized tile,
   with a set focal point per tile; nothing is ever stretched. */
.recover-grid {
  margin-top: var(--space-6);
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--space-5);
}

.recover-item {
  position: relative;
  min-width: 0;
}

.recover-item figure {
  position: relative;
  height: 100%;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: var(--surface-plate);
}

.recover-item img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
}

/* Focal points per tile (the subject sits in the middle of each crop) */
.recover-item--ceramic img { object-position: 50% 45%; }
.recover-item--strip img { object-position: 50% 40%; }
.recover-item--connpins img { object-position: 50% 40%; }

/* Label: bottom-left on a subtle dark gradient scrim */
.recover-item figure::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 45%;
  background: linear-gradient(0deg, color-mix(in srgb, var(--surface-void) 82%, transparent) 0%, transparent 100%);
  pointer-events: none;
}

.recover-item figcaption {
  position: absolute;
  left: var(--space-4);
  bottom: var(--space-3);
  right: var(--space-4);
  z-index: 1;
  font-family: var(--type-label-font);
  font-size: var(--type-label-size);
  letter-spacing: var(--type-label-tracking);
  text-transform: uppercase;
  color: var(--text-primary);
}

/* Collapsible bento (operator, W6). Desktop and tablet show a top block of
   4 tiles plus a "Show all 12 materials" button; the other 8 sit in
   .recover-more, which opens with a 400ms height + opacity transition.
   Phone keeps one swipe strip with all 12 (the lists use display: contents
   inside the scrolling .recover-track). */
.recover-track {
  position: relative;
}

.recover-section {
  --hdr: 178px; /* two-row sticky header below 1140px */
  scroll-margin-top: var(--hdr);
}

@media (min-width: 1140px) {
  .recover-section {
    --hdr: 65px; /* single-row sticky header */
  }
}

.recover-toggle-row {
  display: flex;
  justify-content: center;
  margin-top: var(--space-5);
}

@media (min-width: 640px) {
  .recover-more {
    display: grid;
    grid-template-rows: 1fr;
    opacity: 1;
    transition: grid-template-rows var(--dur-reveal) var(--ease-out), opacity var(--dur-reveal) var(--ease-out);
  }

  .recover-more > .recover-grid {
    min-height: 0;
    overflow: hidden;
    margin-top: 0;
  }

  .is-collapsed .recover-more {
    grid-template-rows: 0fr;
    opacity: 0;
  }

}

@media (prefers-reduced-motion: reduce) {
  .recover-more,
  .recover-more > .recover-grid {
    transition: none;
  }
}

/* Desktop (>=1024): one screen. With the section top under the sticky
   header, heading + sub + the top block + the button fit in one viewport:
   the section fills exactly 100svh minus the header, and the top block's two
   rows take what is left. 4 columns; rows below via .recover-grid--more. */
@media (min-width: 1024px) {
  .recover-section {
    min-height: calc(100svh - var(--hdr));
    padding-block: var(--space-8);
  }

  .recover-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .recover-grid--top {
    --rh: clamp(140px, calc((100svh - var(--hdr) - 414px) / 2), 380px); /* 414 = padding + header block + toggle row + row gap, measured at 1280 */
    grid-template-rows: repeat(2, var(--rh));
  }

  .recover-grid--top .recover-item--ceramic   { grid-column: 1 / 3; grid-row: 1 / 3; }
  .recover-grid--top .recover-item--edge      { grid-column: 3;     grid-row: 1; }
  .recover-grid--top .recover-item--pins      { grid-column: 3;     grid-row: 2; }
  .recover-grid--top .recover-item--terminals { grid-column: 4;     grid-row: 1 / 3; }

  .recover-grid--more {
    padding-top: var(--space-5);
  }

  .recover-item--connpins  { grid-column: 1 / 3; grid-row: 1; }
  .recover-item--flex      { grid-column: 3;     grid-row: 1; aspect-ratio: 1 / 1; }
  .recover-item--strip     { grid-column: 4;     grid-row: 1; aspect-ratio: 1 / 1; }
  .recover-item--tabs      { grid-column: 1;     grid-row: 2; aspect-ratio: 1 / 1; }
  .recover-item--pinsbulk  { grid-column: 2;     grid-row: 2; aspect-ratio: 1 / 1; }
  .recover-item--film      { grid-column: 3 / 5; grid-row: 2; }
  .recover-item--goldlid   { grid-column: 1 / 3; grid-row: 3; aspect-ratio: 2 / 1; }
  .recover-item--blocks    { grid-column: 3 / 5; grid-row: 3; aspect-ratio: 2 / 1; }
}

/* Tablet (640-1023): 2 columns, dense flow. Top block = ceramic (2:1, full
   width) and the tall terminals beside edge + pins. The rest pair up or span
   both columns at 2:1, so there are no orphans. */
@media (min-width: 640px) and (max-width: 1023px) {
  .recover-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-flow: row dense;
    gap: var(--space-4);
  }

  .recover-grid--more {
    padding-top: var(--space-4);
  }

  .recover-item { aspect-ratio: 1 / 1; }

  .recover-item--ceramic,
  .recover-item--connpins,
  .recover-item--film,
  .recover-item--goldlid,
  .recover-item--blocks {
    grid-column: 1 / -1;
    aspect-ratio: 2 / 1;
  }

  .recover-item--terminals {
    grid-row: span 2;
    aspect-ratio: auto;
  }
}

/* Phone: one horizontal scroll-snap strip with all 12, next card peeking */
@media (max-width: 639px) {
  .recover-track {
    margin-top: var(--space-6);
    display: flex;
    gap: var(--space-3);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-inline: 10%;
    scroll-padding-inline: 10%;
    scrollbar-width: none;
    overscroll-behavior-x: contain;
  }

  .recover-track::-webkit-scrollbar {
    display: none;
  }

  .recover-track .recover-grid,
  .recover-track .recover-more {
    display: contents;
  }

  /* Percent of the strip's content box (strip width minus 2 x 10% padding),
     so each card is about 80% of the strip and the next one peeks in. */
  .recover-item {
    flex: 0 0 100%;
    aspect-ratio: 1 / 1;
    scroll-snap-align: center;
  }

  .recover-toggle-row {
    display: none;
  }
}

/* Carousel controls: phone only; arrows only on pointer devices */
.recover-controls {
  display: none;
}

@media (max-width: 639px) {
  .recover-controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    margin-top: var(--space-4);
  }
}

.recover-count {
  min-width: 5ch;
  text-align: center;
  font-family: var(--type-data-font);
  font-size: var(--type-data-size);
  letter-spacing: var(--type-data-tracking);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

.recover-arrow:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.recover-arrow {
  display: none;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-primary);
  box-shadow: inset 0 0 0 1px var(--border-interactive);
  font-size: var(--size-xl);
  line-height: 1;
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .recover-arrow {
    display: inline-block;
  }
}

/* Small print lines: licence line, source line, "Illustration" label */
.fine-print {
  margin-top: var(--space-3);
  font-size: var(--size-xs);
  line-height: var(--type-body-line);
  color: var(--text-secondary);
}

/* Click-to-play video plate */
.video-plate video {
  display: block;
  width: 100%;
  height: auto;
  max-width: 848px;
  background: var(--surface-void);
  border-radius: var(--radius-sm);
}

/* Proof figure on the home page */
.stat-figure--big {
  margin-top: var(--space-5);
  font-size: var(--size-5xl);
  line-height: 1.1;
  color: var(--text-accent);
}

@media (max-width: 640px) {
  .stat-figure--big {
    font-size: var(--size-4xl);
  }
}

/* Home hero without the scroll-film (W4): sized near its content so the
   next section peeks above the fold at 1280x800; type starts higher so the
   still image reads below it. Desktop/tablet only: the phone hero stacks. */
@media (min-width: 641px) {
  /* Machine inside the header container (operator rule). From 641px the
     hero uses hero-machine-*.webp: the still trimmed to the machine's
     bounding box plus 2% each side (2728x1033 at 2x). .hero-media has the
     header content width (min(100%, grid-max) minus 2 x space-5), and the
     image renders at 104% of it with -2% margin, so the machine itself runs
     from the logo's left edge to the Talk-to-us button's right edge. Height
     follows the image ratio (height: auto, never stretched). The media sits
     under the text and overlaps it by 0.165 x container width (about 42%
     of the image height), as before. Text unchanged. */
  .hero {
    flex-direction: column;
    height: auto;
    min-height: 0;
  }

  .hero .hero-inner {
    order: 1;
    padding-bottom: 0;
  }

  .hero-media {
    --hero-wc: calc(min(100%, var(--grid-max)) - 2 * var(--space-5));
    order: 2;
    position: relative;
    inset: auto;
    width: var(--hero-wc);
    margin: calc(-0.165 * min(100vw, var(--grid-max))) auto 0;
    /* soft edges: 6% sides, a short top fade above the pipes, and the
       existing fade only below the base (base sits at 93% of the image) */
    -webkit-mask-image:
      linear-gradient(to right, transparent 0%, #000 6%, #000 94%, transparent 100%),
      linear-gradient(to bottom, transparent 0%, #000 5%, #000 93%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image:
      linear-gradient(to right, transparent 0%, #000 6%, #000 94%, transparent 100%),
      linear-gradient(to bottom, transparent 0%, #000 5%, #000 93%, transparent 100%);
    mask-composite: intersect;
  }

  .hero-media img {
    display: block;
    width: 104%;
    max-width: none;
    height: auto;
    margin-left: -2%;
    object-fit: contain;
  }

  /* The image is now tight to the machine: no top scrim; the left scrim
     only dims the upper part, where the text overlaps. */
  .hero-scrim--top {
    display: none;
  }

  .hero-scrim--left {
    inset: 0 0 45% 0;
  }

  .hero .hero-inner {
    padding-top: clamp(var(--space-8), 9vh, var(--space-10));
  }
}

@media (max-width: 640px) {
  .hero-media {
    height: 30vh;
  }
}

/* Stop .hero-type .btn doubling the row gap. */

.hero-type .btn-row .btn {
  margin-top: 0;
}

/* Product photo stage: every product photo (cards and detail heroes) sits on
   the same pure white panel, 4:5, centred. The padding is baked into the
   photos, so the stage adds none. The image is never drawn wider than its
   native canvas (--native-w, set inline per image). */
.plate-photo {
  height: auto;
  aspect-ratio: 4 / 5;
  background: var(--stage-product);
  border-radius: var(--radius-sm);
  position: relative;
  min-height: 0;
  overflow: hidden;
  display: grid;
  place-items: center;
}

.plate-photo .plate-photo-img {
  display: block;
  width: 100%;
  max-width: min(100%, var(--native-w, 100%));
  height: auto;
  object-fit: contain;
}

/* W4: four-column link grid (8 cards = 4x2), 2 columns below 1024px.
   Complete borders: the grid draws top/left, every card draws right/bottom. */
.quick-link-grid--4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.quick-link-grid--5 {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}

.quick-link-grid--4,
.quick-link-grid--5 {
  border-top: 1px solid var(--quick-link-border);
  border-left: 1px solid var(--quick-link-border);
}

.quick-link-grid--4 .quick-link,
.quick-link-grid--5 .quick-link {
  border-top: 0;
  border-left: 0;
  border-right: 1px solid var(--quick-link-border);
  border-bottom: 1px solid var(--quick-link-border);
}

@media (max-width: 1023px) {
  .quick-link-grid--4,
  .quick-link-grid--5 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* 5 tiles in 2 columns: the last one spans the row, so no orphan */
  .quick-link-grid--5 > :last-child {
    grid-column: 1 / -1;
  }
}

/* Card thumbnail (solutions hub): 16:10, cover, flush to the card edges */
.quick-link--thumb {
  padding-top: 0;
}

.quick-link-thumb {
  display: block;
  width: calc(100% + 2 * var(--space-4));
  max-width: none;
  height: auto;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  margin: 0 calc(-1 * var(--space-4)) var(--space-2);
  background: var(--surface-plate);
}

/* Compact page hero (solutions hub): no big band above or below the H1 */
.page-hero--compact {
  padding-top: var(--space-7);
  padding-bottom: var(--space-5);
}

.section--tight-top {
  padding-top: var(--space-5);
}

/* W4: product card buttons. Side by side, equal width; they stack only when
   the card itself is narrow, the same way in every card. */
.plate-card {
  container-type: inline-size;
}

.plate-actions .btn {
  flex: 1 1 0;
  max-width: 12rem;
  text-align: center;
  white-space: nowrap;
}

/* Slightly tighter side padding so both fit in a four-up analyzer card */
.plate-actions .btn {
  padding-inline: var(--space-3);
}

@container (max-width: 215px) {
  .plate-actions {
    flex-direction: column;
  }
}

/* W4: phone header nav row. One even row, 44px targets, no wrapping. */
@media (max-width: 640px) {
  .primary-nav ul {
    display: flex;
    flex-wrap: nowrap;
    justify-content: space-between;
    column-gap: var(--space-2);
  }

  .primary-nav .nav-link {
    letter-spacing: 0.06em;
    min-height: 44px;
  }
}

/* Assessment: what to include in the request email (no form backend) */
.assess-checklist {
  margin-top: var(--space-3);
  padding-left: var(--space-5);
  max-width: 64ch;
  color: var(--text-primary);
  line-height: var(--type-body-line);
}

.assess-checklist li + li {
  margin-top: var(--space-2);
}

.contact-address .mono {
  user-select: all;
}

/* ===== Spacing around media plates and h2s (interior pages) ===== */
.media-plate {
  margin-block: var(--space-6) var(--space-8);
}

.section-content > * + h2,
.section-content > * + .h2 {
  margin-top: var(--space-9);
}

.section-content > .eyebrow-row + h2,
.section-content > .eyebrow-row + .h2 {
  margin-top: 0;
}

/* Never draw a media-plate image wider than its real file (1x).
   The cap is the widest derivative on disk, set inline as --native-w. */
.media-plate img {
  max-width: min(100%, var(--native-w, 100%));
  margin-inline: auto;
}

/* Industries: drop the legacy 12-column rule lines drawn on .section-grid. */
main:has(#semiconductor) .section-grid {
  background-image: none;
}

/* ===== B3/B7: home hero scrim and "Illustration" tag ===== */
@media (min-width: 641px) {
  /* The mask moves from the media box to the image itself (same fade, in
     image-box percentages) so the tag can sit at the corner, unfaded. */
  .hero-media {
    -webkit-mask-image: none;
    mask-image: none;
  }

  .hero-media img {
    -webkit-mask-image:
      linear-gradient(to right, transparent 1.92%, #000 7.69%, #000 92.31%, transparent 98.08%),
      linear-gradient(to bottom, transparent 0%, #000 5%, #000 93%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image:
      linear-gradient(to right, transparent 1.92%, #000 7.69%, #000 92.31%, transparent 98.08%),
      linear-gradient(to bottom, transparent 0%, #000 5%, #000 93%, transparent 100%);
    mask-composite: intersect;
  }

}

/* Left scrim behind the text only, at mid widths where the type overlaps
   the image: between the image and the type. */
@media (min-width: 641px) and (max-width: 1279px) {
  .hero-media::before {
    content: "";
    position: absolute;
    inset: 0 0 45% 0;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(90deg, var(--surface-page) 35%, transparent 65%);
  }
}

.hero-tag {
  position: absolute;
  bottom: var(--space-3);
  right: var(--space-3);
  z-index: 3;
  font-family: var(--type-label-font);
  font-size: var(--type-label-size);
  letter-spacing: var(--type-label-tracking);
  text-transform: uppercase;
  color: var(--text-secondary);
}

/* ===== B4: accent discipline (footer) ===== */
.footer-grid a {
  color: var(--text-primary);
}

.footer-grid a:hover,
.footer-grid a:focus-visible {
  color: var(--accent-hover);
}

/* ===== B2: 44px touch targets on phones (header excluded) ===== */
@media (max-width: 639px) {
  /* a link that stands alone in its own paragraph */
  .tap-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  main .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
  }

  .plate-name a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  .footer-grid dd {
    margin-bottom: 0;
  }

  .footer-grid a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  .breadcrumb a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

@media (max-width: 639px) {
  .breadcrumb a {
    min-width: 44px;
  }
}

@media (max-width: 639px) {
  main dd > a,
  .text-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* ===== v3 13.2: "Illustration" tag on generated stream images ===== */
.media-plate {
  position: relative;
}

.plate-tag {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  z-index: 1;
  padding: var(--space-1) var(--space-2);
  background: var(--surface-page);
  font-family: var(--type-label-font);
  font-size: var(--type-label-size);
  letter-spacing: var(--type-label-tracking);
  text-transform: uppercase;
  color: var(--text-secondary);
}

/* ===== v3 13.6: skip link shows above the sticky header ===== */
.skip-link:focus {
  z-index: 1000;
  color: var(--text-primary);
  border: 1px solid var(--accent);
}

/* ===== v3 12: portrait site video, true 9:16, never stretched ===== */
.video-plate--portrait {
  display: grid;
  grid-template-columns: 340px minmax(0, 1fr);
  gap: var(--space-8);
  align-items: center;
}

.video-plate--portrait video {
  width: 100%;
  height: auto;
  aspect-ratio: 480 / 848;
  object-fit: contain;
}

.video-plate--portrait {
  align-items: start;
}

.video-plate--portrait figcaption {
  max-width: 44ch;
}

.video-side .body-copy {
  margin-top: var(--space-3);
}

.video-facts {
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-2);
  font-size: var(--size-sm);
  line-height: var(--type-body-line);
  color: var(--text-secondary);
}

.video-facts li {
  position: relative;
  padding-left: var(--space-5);
}

.video-facts li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.8em;
  width: 12px;
  height: 2px;
  background: var(--accent);
}

.video-facts a {
  color: var(--text-primary);
}

@media (max-width: 639px) {
  .video-plate--portrait {
    grid-template-columns: 1fr;
    gap: var(--space-5);
    justify-items: center;
  }

  .video-plate--portrait video {
    width: auto;
    height: 360px;
  }
}

/* ===== v3 1: hero fills exactly one screen under the header =====
   The hero is 100svh minus the sticky header. The machine frame takes the
   space left under the text (plus the existing overlap) and is sized from
   that box with container units: full width (logo-left to button-right,
   104% with the 2% trim each side) when it fits, otherwise scaled down by
   height and centred. Ratio is fixed by aspect-ratio, so it never stretches
   and its base always stays inside the hero. */
:root {
  --hdr-h: 178px; /* two-row sticky header */
}

@media (min-width: 1140px) {
  :root {
    --hdr-h: 65px; /* one-row sticky header */
  }
}

.hero-frame {
  position: relative;
  height: 100%;
}

@media (min-width: 641px) {
  .hero {
    height: calc(100svh - var(--hdr-h));
    min-height: 480px;
  }

  .hero .hero-inner {
    flex: none;
  }

  .hero-media {
    flex: 1 1 0;
    min-height: 0;
    container-type: size;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .hero-frame {
    flex: none;
    width: min(104cqw, 100cqh * 2728 / 1033);
    height: auto;
    aspect-ratio: 2728 / 1033;
  }

  .hero-media img {
    width: 100%;
    height: 100%;
    margin-left: 0;
  }
}

@media (min-width: 641px) {
  .hero-media::before {
    content: none;
  }

  .hero-frame::before {
    content: "";
    position: absolute;
    inset: 0 0 45% 0;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(90deg, var(--surface-page) 35%, transparent 65%);
  }
}

/* ===== v3 5: compact recovery machine cards =====
   Machine stage height = 1.3 x the analyzer stage height at the same width,
   capped at 420px; width follows the 4:5 stage. The analyzer grid is
   auto-fit minmax(240px, 1fr) with --plate-padding each side, so its stage
   height is derived here from the product group's width (container units,
   resolved on the grid by @property). Desktop: image left, text right. */
@property --mach-h {
  syntax: "<length>";
  inherits: true;
  initial-value: 420px;
}

.product-group,
.section-inner:has(> .plate-grid--machines) {
  container-type: inline-size;
  container-name: machines;
}

.plate-grid--machines {
  /* one analyzer per row on phones */
  --mach-h: min(420px, 1.3 * 1.25 * (100cqw - 2 * var(--plate-padding)));
}

@container (min-width: 504px) {
  .plate-grid--machines {
    --mach-h: min(420px, 1.3 * 1.25 * ((100cqw - var(--space-5)) / 2 - 2 * var(--plate-padding)));
  }
}

@container (min-width: 768px) {
  .plate-grid--machines {
    --mach-h: min(420px, 1.3 * 1.25 * ((100cqw - 2 * var(--space-5)) / 3 - 2 * var(--plate-padding)));
  }
}

@container (min-width: 1032px) {
  .plate-grid--machines {
    --mach-h: min(420px, 1.3 * 1.25 * ((100cqw - 3 * var(--space-5)) / 4 - 2 * var(--plate-padding)));
  }
}

.plate-grid--machines .plate-photo {
  width: min(100%, var(--mach-h) * 0.8);
  height: auto;
  aspect-ratio: 4 / 5;
  margin-inline: auto;
}

/* side by side once each card has room for the stage plus a text column
   (queried on the product group, since a card cannot query itself) */
@container machines (min-width: 1100px) {
  .plate-grid--machines .plate-card {
    display: grid;
    grid-template-columns: calc(var(--mach-h) * 0.8) minmax(0, 1fr);
    grid-template-rows: auto auto auto 1fr;
    column-gap: var(--space-6);
    align-items: start;
  }

  .plate-grid--machines .plate-photo {
    grid-column: 1;
    grid-row: 1 / 5;
    width: 100%;
    margin: 0;
  }

  .plate-grid--machines .plate-name,
  .plate-grid--machines .plate-line,
  .plate-grid--machines .plate-actions {
    grid-column: 2;
  }

  .plate-grid--machines .plate-name {
    grid-row: 1;
    margin-top: 0;
  }

  .plate-grid--machines .plate-line {
    grid-row: 2;
  }

  .plate-grid--machines .plate-actions {
    grid-row: 3;
    align-self: start;
    margin-top: 0;
    padding-top: var(--space-5);
  }
}

/* ===== v3 1 (phone): same structure as desktop, text first, machine below =====
   One screen under the 64px header. The trimmed machine still runs the
   container width (16px gutters) when it fits, otherwise it scales down by
   height; soft fade on the sides and bottom; tag inside, bottom-right. */
@media (max-width: 639px) {
  :root {
    --hdr-h: 64px; /* one-row phone header */
  }
}

@media (max-width: 640px) {
  .hero {
    flex-direction: column;
    height: calc(100svh - var(--hdr-h));
    min-height: 0;
  }

  .hero .hero-inner {
    order: 1;
    flex: none;
    padding-block: var(--space-5) 0;
  }

  .hero-h1 {
    margin-top: var(--space-2);
  }

  .hero-sub {
    margin-top: var(--space-3);
  }

  .hero-type .btn-row {
    margin-top: var(--space-5);
    gap: var(--space-2);
  }

  .hero-media {
    order: 2;
    position: relative;
    inset: auto;
    flex: 1 1 0;
    min-height: 0;
    height: auto;
    width: calc(100% - 2 * var(--space-4));
    margin: 0 auto;
    container-type: size;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .hero-frame {
    flex: none;
    width: min(104cqw, 100cqh * 2728 / 1033);
    height: auto;
    aspect-ratio: 2728 / 1033;
  }

  .hero-media img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    -webkit-mask-image:
      linear-gradient(to right, transparent 0%, #000 8%, #000 92%, transparent 100%),
      linear-gradient(to bottom, transparent 0%, #000 14%, #000 88%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image:
      linear-gradient(to right, transparent 0%, #000 8%, #000 92%, transparent 100%),
      linear-gradient(to bottom, transparent 0%, #000 14%, #000 88%, transparent 100%);
    mask-composite: intersect;
  }

  .hero-scrim--top,
  .hero-scrim--left {
    display: none;
  }

  .hero-tag {
    bottom: 0;
    right: 0;
    padding: 2px var(--space-1);
    background: var(--surface-page);
    font-size: var(--size-xs);
  }

  /* Wordmark beside the mark on the 390 first screen */
  .site-header .brand {
    gap: var(--space-2);
  }

  .site-header .brand img {
    height: 32px;
  }

  .site-header .brand-word {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip: auto;
    font-size: var(--size-sm);
  }

  .header-cta {
    padding-inline: 10px;
    letter-spacing: 0.08em;
  }
}

/* ===== v3 2: recover header, text left and four points right ===== */
.recover-points {
  display: grid;
  gap: var(--space-3);
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
}

.recover-points li {
  position: relative;
  padding-left: var(--space-5);
  font-size: var(--size-sm);
  line-height: var(--type-body-line);
  color: var(--text-primary);
}

.recover-points li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.8em;
  width: 12px;
  height: 2px;
  background: var(--accent);
}

@media (min-width: 1024px) {
  .recover-head {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: var(--space-8);
    align-items: start;
  }

  .recover-points {
    margin-top: 0;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--space-6);
  }
}

@media (max-width: 639px) {
  .recover-section {
    padding-top: var(--space-6);
  }
}

/* ===== v3 3/4: home section subs, solution cards with line icons ===== */
.section-content > .h2 + .body-copy {
  margin-top: var(--space-3);
  max-width: 64ch;
  color: var(--text-primary);
}

.sol-card .sol-icon {
  margin-bottom: var(--space-2);
}

/* ===== v3 7: proof bars (a real table, styled as horizontal bars) ===== */
.proof-chart {
  margin-top: var(--space-6);
  max-width: 760px;
}

.proof-table {
  width: 100%;
  border-collapse: collapse;
}

.proof-table th[scope="row"] {
  width: 5.5rem;
  padding: var(--space-2) var(--space-3) var(--space-2) 0;
  text-align: left;
  font-family: var(--type-label-font);
  font-size: var(--type-label-size);
  letter-spacing: var(--type-label-tracking);
  text-transform: uppercase;
  font-weight: 400;
  color: var(--text-secondary);
  white-space: nowrap;
}

.proof-table td {
  padding: var(--space-2) 0;
}

/* Bar width is the value's share of the track; --p (0 to 1) is the grow
   progress, 1 by default so the chart is final without JS. The label rides at
   the bar's moving end. */
.proof-track {
  --bar: calc(var(--v) / 280.79 * (100cqw - 8rem));
  --p: 1;
  container-type: inline-size;
  position: relative;
  display: block;
  height: 20px;
}

.proof-bar {
  display: block;
  width: var(--bar);
  height: 20px;
  background: var(--border-interactive);
  border-radius: 1px;
  transform: scaleX(var(--p));
  transform-origin: left;
  overflow: hidden;
}

.proof-val {
  position: absolute;
  top: 50%;
  left: calc(var(--bar) + var(--space-3));
  transform: translate(calc(var(--bar) * (var(--p) - 1)), -50%);
  font-size: var(--size-sm);
  color: var(--text-secondary);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* One soft sheen across the gold bar after it lands */
.proof-sheen .is-top .proof-bar::after {
  content: "";
  display: block;
  height: 100%;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.35) 50%, transparent 70%);
  transform: translateX(-100%);
  animation: proof-sheen 450ms ease-out 1 forwards;
}

@keyframes proof-sheen {
  to { transform: translateX(100%); }
}

.proof-table .is-top .proof-bar {
  background: var(--accent);
}

.proof-table .is-top .proof-val,
.proof-table .is-top th[scope="row"] {
  color: var(--text-primary);
}

.proof-chart + .fine-print {
  margin-top: var(--space-2);
}

/* Hero: the outline button keeps a solid ground where it overlaps the wireframe */
.hero-type .btn--secondary {
  background: var(--surface-page);
}

/* ===== v3 13.5: header. One row from 960px; hides on scroll down under 1280px ===== */
@media (max-width: 1279px) {
  .site-header {
    transition: transform 200ms ease;
  }

  .site-header.is-hidden {
    transform: translateY(-100%);
  }
}

@media (max-width: 1279px) and (prefers-reduced-motion: reduce) {
  .site-header {
    transition: none;
  }
}

@media (min-width: 960px) and (max-width: 1139px) {
  :root {
    --hdr-h: 65px;
  }

  .recover-section {
    --hdr: 65px;
  }

  .header-inner {
    flex-wrap: nowrap;
    height: var(--header-height);
    padding-block: 0;
  }

  .primary-nav {
    order: 2;
    flex-basis: auto;
    width: auto;
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
  }

  .primary-nav ul {
    flex-wrap: nowrap;
    column-gap: var(--space-5);
    padding-block: 0;
  }

  .header-cta {
    order: 3;
  }
}

/* 13.13: the menu button shows a close mark while the sheet is open */
@media (max-width: 639px) {
  .nav-toggle[aria-expanded="true"] .nav-toggle-icon {
    background: transparent;
  }

  .nav-toggle[aria-expanded="true"] .nav-toggle-icon::before {
    top: 0;
    transform: rotate(45deg);
  }

  .nav-toggle[aria-expanded="true"] .nav-toggle-icon::after {
    top: 0;
    transform: rotate(-45deg);
  }
}

/* ===== v3 13.9: a product cut-out as a card thumbnail (white stage, contained) ===== */
.quick-link-thumb--product {
  object-fit: contain;
  background: var(--stage-product);
}

/* ===== v3 13.10: on phones the H2 sits one scale step under the H1 ===== */
@media (max-width: 640px) {
  .h2,
  .m3-title {
    font-size: var(--size-xl);
  }
}

/* ===== v3 13.13: hero "Illustration" tag on its own small ground, so it
   never sits on the wireframe lines (640 to 800 and up) ===== */
.hero-tag {
  bottom: 0;
  right: 0;
  padding: 2px var(--space-2);
  background: var(--surface-page);
}

/* v0.15.3: the frame is 104% of the gutter-width media box (2% bleed each side,
   faded to transparent), so pull the tag in to the gutter edge. */
@media (min-width: 768px) {
  .hero-tag {
    right: max(0px, calc((100% - 100cqw) / 2));
  }
}

.recover-track:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 4px;
}

/* ===== v0.15 additions ===== */

/* Footer on phones: link groups in two columns, legal rows as one block */
@media (max-width: 639px) {
  .footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--space-4);
    row-gap: var(--space-5);
  }

  .footer-credentials {
    margin-top: var(--space-4);
    padding-block: var(--space-4);
  }

  .footer-credentials dl {
    gap: var(--space-3) var(--space-5);
  }

  .site-footer {
    padding-block: var(--space-7);
  }

  .footer-legal + .footer-legal {
    margin-top: var(--space-1);
    padding-top: 0;
    border-top: 0;
  }
}

/* Detail pages (machines, solutions): about 40% less section padding on desktop */
@media (min-width: 1024px) {
  main:has(.pdp-hero, .sol-hero):not(:has(form)) .section-content {
    padding-block: 20px 14px;
  }

  main:has(.pdp-hero, .sol-hero):not(:has(form)) .section-content > * + h2,
  main:has(.pdp-hero, .sol-hero):not(:has(form)) .section-content > * + .h2 {
    margin-top: var(--space-7);
  }

  main:has(.pdp-hero, .sol-hero):not(:has(form)) .media-plate {
    margin-block: var(--space-5) var(--space-6);
  }

  main:has(.pdp-hero, .sol-hero):not(:has(form)) .page-hero {
    padding-top: var(--space-8);
    padding-bottom: var(--space-6);
  }
}

/* Amber dash marker, drawn by the shared header script over the old "+" text */
.chain-step-num--dash::before {
  content: "";
  display: block;
  width: 12px;
  height: 2px;
  margin-top: 0.8em;
  background: var(--accent);
}

/* Industries: sections without a rail keep the same 8-column measure as the
   ones with a rail, so the images do not change width from section to section. */
@media (min-width: 641px) {
  main:has(#semiconductor) .section-grid:not(:has(.spec-rail)) .section-content {
    grid-column: 1 / 9;
  }
}

/* Narrow phones (400px and under): keep the full wordmark, a 44px CTA and the menu button on one row */
@media (max-width: 400px) {
  .site-header .brand-word {
    font-size: 11px;
    letter-spacing: 0.01em;
  }

  .header-cta {
    padding-inline: 8px;
    font-size: 11px;
    letter-spacing: 0.02em;
  }

  .nav-toggle {
    flex-shrink: 0;
  }
}

/* Home hero at tablet widths: the frame is width-limited, so a full-screen
   hero left a blank band under the illustration. Cap the hero to the
   illustration's own height; phones and wide screens are unchanged. */
@media (min-width: 641px) and (max-width: 1023px) {
  .hero {
    height: min(calc(100svh - var(--hdr-h)), 94vw);
  }

  .hero-media {
    align-items: flex-end;
  }
}

/* Section rhythm: assessment and case studies stacked 96px section padding on
   top of the 32px content padding around one or two lines of copy. Use the
   detail-page rhythm instead. */
@media (min-width: 1024px) {
  main:has(#questions-heading, #batch-heading) .section:not(.cta-band) {
    padding-block: var(--space-8);
  }
}

/* Solution pages on phones: hero to first paragraph was about 100px */
@media (max-width: 639px) {
  main:has(.sol-hero) .section:not(.cta-band) {
    padding-block: var(--space-7);
  }

  main:has(.sol-hero) .section:not(.cta-band) .section-content {
    padding-top: 0;
  }
}

/* v0.15.2: solution detail pages — image capped to the width of the home
   FJ1000 / FJ1500 card photos at 1440 (336px), left-aligned with the text. */
.media-plate--sol {
  max-width: 336px;
  margin-inline: 0;
}

/* contact enquiry form: land below the sticky header when linked as #enquiry */
#enquiry {
  scroll-margin-top: 80px;
}

/* hub card with an "Illustration" tag: tag sits on the photo's top-right corner */
.quick-link--thumb {
  position: relative;
}

.quick-link--thumb .plate-tag {
  top: var(--space-3);
  right: var(--space-3);
}

/* v0.15.2: solution detail pages — text left, image right (>= 1024px).
   Stacked below that, with the image straight after the first paragraph.
   "What you get", the list and the CTA sit after .sol-split and stay full width. */
.sol-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "first" "fig" "rest";
}

.sol-split > .body-copy:first-child { grid-area: first; }
.sol-split > .media-plate--sol { grid-area: fig; margin-top: var(--space-4); }
.sol-split-rest { grid-area: rest; }

@media (min-width: 1024px) {
  .sol-split {
    grid-template-columns: minmax(0, 1fr) 336px;
    grid-template-rows: auto 1fr;
    grid-template-areas: "first fig" "rest fig";
    column-gap: var(--space-8);
  }

  .sol-split > .media-plate--sol {
    margin-top: var(--space-4); /* same as the first paragraph, so the tops line up */
    align-self: start;
    position: sticky;
    top: calc(var(--hdr-h) + var(--space-6));
  }
}

/* hero tag now names the picture: wraps right-aligned on narrow screens, never truncated */
.hero-tag {
  max-width: calc(100% - var(--space-4));
  text-align: right;
  line-height: 1.3;
}

/* v0.15.2: no hero picture below 768px. The <picture> in index.html also swaps
   the image for a 1x1 placeholder there, so it is never downloaded. The hero is
   as tall as its text, then the normal section rhythm follows. */
@media (max-width: 767px) {
  .hero {
    flex-direction: column;
    height: auto;
    min-height: 0;
  }

  .hero-media {
    display: none;
  }

  .hero .hero-inner {
    padding-block: var(--space-5) var(--space-6);
  }
}

/* v0.15.2: solution detail pages, desktop: first body block sits one normal
   section rhythm under the hero rule (was about 135px). */
@media (min-width: 768px) {
  main:has(.sol-split) > .section:has(.sol-split) {
    padding-top: var(--space-5);
  }
}

/* v0.15.3: solution detail pages at tablet widths get the same hero-to-text
   rhythm as desktop (the 1024+ "detail pages" block above does not reach them). */
@media (min-width: 768px) and (max-width: 1023px) {
  main:has(.sol-hero):not(:has(form)) .section-content {
    padding-block: 20px 14px;
  }

  main:has(.sol-hero):not(:has(form)) .page-hero {
    padding-top: var(--space-8);
    padding-bottom: var(--space-6);
  }
}

/* v0.15.3: solution detail pages, text column fills the left side; line length
   is capped on the text blocks, and the image top lines up with the first paragraph. */
@media (min-width: 1024px) {
  .sol-split > .body-copy,
  .sol-split-rest > .body-copy {
    max-width: 68ch;
  }

  main .section-content .sol-split > .media-plate--sol {
    margin-top: var(--space-4);
  }
}

/* v0.15.3: footer on phones, Contact group spans both columns so the email
   address sits on one line (no mid-word break). */
@media (max-width: 639px) {
  .footer-grid > div:last-child {
    grid-column: 1 / -1;
  }
}
