/* ==========================================================================
   Union Enterprises — Westerville, OH CNC Machine Shop
   Design system: "The Dimensioned Print"
   Vanilla CSS. No frameworks, no build step.
   --------------------------------------------------------------------------
   Palette derived from the shop floor: graphite/cast iron surfaces, machined
   steel greys, and safety amber (the colour of CNC enclosure warning striping).
   Signature device: the dimension line — a hairline rule with extension ticks
   and a monospace callout, used ONLY where a real measured value exists.
   ========================================================================== */

/* ---------- 1. Tokens ---------- */
:root {
  /* Colour */
  --ink:        #101317;
  --ink-2:      #191E24;
  --ink-3:      #232A31;
  --steel:      #626C76;
  --steel-2:    #98A2AC;
  --line:       #D7DCE0;
  --line-dark:  #333B43;
  --paper:      #EEF1F3;
  --paper-2:    #F7F8F9;
  --surface:    #FFFFFF;
  --amber:      #F5A200;
  --amber-dk:   #C27F00;
  --amber-soft: #FFF4DE;

  /* Type */
  --display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --body:    "IBM Plex Sans", "Segoe UI", Arial, sans-serif;
  --mono:    "IBM Plex Mono", "SFMono-Regular", Consolas, monospace;

  /* Metrics */
  --wrap: 1240px;
  --gut: clamp(1.15rem, 4vw, 2.5rem);
  --head-h: 80px;
  --chamfer: 10px;
  /* Utility bar + header. main.js measures the real value and overwrites this,
     since the utility bar wraps to two or three lines on narrow screens. */
  --chrome-h: 112px;

  /* Motion */
  --ease: cubic-bezier(.2, .7, .3, 1);
}

/* Typed so the broken edge can be animated rather than snapped.
   Browsers without @property still get the size change, just instantly. */
@property --chamfer {
  syntax: "<length>";
  inherits: true;
  initial-value: 10px;
}

/* ---------- 2. Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--surface);
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.68;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* height: auto is what makes width/height attributes safe. Without it, max-width
   shrinks the width to fit its column while the height attribute is still
   honoured literally, and the image stretches vertically. Every rule that wants
   a real height (.hero__bg, .page-head__bg, .scard__img, .icard__img, .gal,
   .brand, .site-foot .logo) is class-qualified and outranks this. */
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
button { font: inherit; }

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.015em;
  margin: 0 0 .55em;
  text-wrap: balance;
}
h1 { font-size: clamp(2.15rem, 5.4vw, 3.9rem); text-transform: uppercase; letter-spacing: -0.01em; }
h2 { font-size: clamp(1.6rem, 3.1vw, 2.35rem); }
h3 { font-size: clamp(1.12rem, 1.8vw, 1.35rem); letter-spacing: 0; }
h4 { font-size: 1rem; letter-spacing: 0; }
p  { margin: 0 0 1.15em; }

::selection { background: var(--amber); color: var(--ink); }

:focus-visible {
  outline: 3px solid var(--amber);
  outline-offset: 2px;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--amber); color: var(--ink);
  padding: .8rem 1.2rem; font: 700 .82rem/1 var(--mono); text-decoration: none;
}
.skip:focus { left: 8px; top: 8px; }

/* ---------- 3. Layout helpers ---------- */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gut); }

.band { padding-block: clamp(3.4rem, 7vw, 6rem); }
.band--tight { padding-block: clamp(2.4rem, 4.5vw, 3.6rem); }
.band--paper { background: var(--paper); }

/* Photographic background for bands that would otherwise be flat white.
   These are shot high-key against blown-out white with the subject in one part
   of the frame, so the falloff is real light rather than a white gradient laid
   over a normal photo — that faked version always read as a picture behind
   frosted glass. Each asset is levelled at build time until its empty frame
   measures a true 255, otherwise a 250-ish edge shows as a faint panel against
   the section.

   background-size is never `cover`: cover crops into the faded margins and
   reintroduces a hard edge. Whatever area the image does not cover is plain
   --surface, which is exactly what the images fade to. */
.band--tex {
  background-color: var(--surface);
  background-repeat: no-repeat;
}
/* Image per section, sized and placed to miss that section's content. Named for
   the slot, not the picture, so swapping the photo never means renaming a class.
   These live here rather than in an inline custom property because url() inside
   a custom property resolves against the stylesheet, not the page — the bug
   that made the first page-head attempt fetch nothing.

   --caps runs full width: that band has a short heading and a genuinely empty
   top right, so the swarf can bleed off the edge at full size. --whyus cannot;
   it is two columns with the tick list on the right, so the bar stock is sized
   down and anchored to the bottom edge, under everything else. */
.band--tex--caps {
  background-image: url("../img/bg-capabilities.jpg");
  background-size: 100% auto;
  background-position: center top;
}
/* The asset is cropped just below the bundle at build time. Uncropped it
   carried 20% pure white under the stock, and anchoring `bottom` then held the
   bars that far clear of the section edge instead of resting on it. */
.band--tex--whyus {
  background-image: url("../img/bg-whyus.jpg");
  background-size: 66% auto;
  background-position: right bottom;
}
/* Also cropped flush to the subject, so `bottom` seats it on the section edge. */
.band--tex--story {
  background-image: url("../img/bg-about-story.jpg");
  background-size: 100% auto;
  background-position: right bottom;
}
/* No colour override needed here: these backgrounds leave the copy zone at a
   measured 255, so --steel keeps its full 5.35:1. The earlier darkened variant
   existed to survive a full-bleed texture and is gone with it. */
.band--dark { background: var(--ink); color: var(--paper); }
.band--dark h2, .band--dark h3 { color: #fff; }
/* Photograph behind a dark band. Must come after .band--dark, whose `background`
   shorthand would otherwise reset background-image to none.

   Both assets are shot extremely low-key — the machine picked out by a single
   work lamp with everything else falling to black — then screened onto #101317
   at build time. Screen rather than a level remap: it pins pure black to exactly
   the band colour while preserving the blue cast in the shadows, which a neutral
   remap would flatten to grey. The render is multiplied to 0.75 first, so the
   lamp reads as a light source instead of a hotspot competing with the heading.

   A normally exposed photo cannot work here: the band is #101317, and anything
   with broad mid-tones reads as a lighter rectangle pasted onto it. */
.band--machine {
  background-size: 68% auto;
  background-position: right top;
  background-repeat: no-repeat;
}
.band--machine--envelopes { background-image: url("../img/bg-envelopes.jpg"); }
.band--machine--oneroof   { background-image: url("../img/bg-oneroof.jpg"); }

/* Eyebrow: monospace section marker with an amber tick */
.eyebrow {
  display: inline-flex; align-items: center; gap: .6rem;
  font: 600 .715rem/1 var(--mono);
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--steel); margin: 0 0 1.15rem;
}
.eyebrow::before {
  content: ""; width: 22px; height: 3px; background: var(--amber); flex: none;
}
.band--dark .eyebrow { color: var(--steel-2); }

.lede { font-size: clamp(1.02rem, 1.5vw, 1.17rem); color: var(--steel); max-width: 62ch; }
.band--dark .lede { color: var(--steel-2); }

/* ---------- 4. Signature: the dimension line ---------- */
.dim {
  display: flex; align-items: center; gap: .7rem;
  font: 600 .72rem/1 var(--mono); letter-spacing: .04em;
  color: var(--steel); margin-top: .7rem;
}
.dim .rule { flex: 1 1 auto; height: 1px; background: var(--line); position: relative; min-width: 20px; }
.dim .rule::before, .dim .rule::after {
  content: ""; position: absolute; top: -4px; width: 1px; height: 9px; background: var(--line);
}
.dim .rule::before { left: 0; }
.dim .rule::after  { right: 0; }
.dim .val { flex: none; color: var(--ink); white-space: nowrap; }
.dim .tag { flex: none; color: var(--steel); }

.band--dark .dim .rule, .band--dark .dim .rule::before, .band--dark .dim .rule::after { background: var(--line-dark); }
.band--dark .dim .val { color: var(--amber); }
.band--dark .dim { color: var(--steel-2); }

/* ---------- 5. Buttons (chamfered — a machinist's broken edge) ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  padding: .92rem 1.55rem;
  font: 700 .78rem/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  text-decoration: none; border: 0; cursor: pointer;
  background: var(--amber); color: var(--ink);
  clip-path: polygon(var(--chamfer) 0, 100% 0, 100% calc(100% - var(--chamfer)), calc(100% - var(--chamfer)) 100%, 0 100%, 0 var(--chamfer));
  transition: background .18s var(--ease), transform .18s var(--ease);
}
.btn:hover { background: #FFB627; transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

/* Ghost button. The chamfer is a clip-path, and an inset box-shadow only draws
   along the element's four rectangular edges — so both diagonal cuts came out
   bare and the top-left and bottom-right corners read as gaps. (Invisible on
   hover, where the fill goes solid and covers the whole clipped shape.)

   The two gradients paint the missing 2px along each diagonal. In a
   chamfer-sized corner box, the cut runs exactly corner to corner, so it sits
   at the 50% mark of a 135deg (or 315deg) gradient across that box — paint the
   line colour from 0 to 50%+2px and clip-path discards everything before the
   cut, leaving a 2px band measured perpendicular to it, matching the straight
   edges. --ghost-line drives both the shadow and the gradients so a context
   only has to override one value. */
.btn--ghost {
  --ghost-line: var(--ink);
  background-color: transparent;
  background-image:
    linear-gradient(135deg, var(--ghost-line) 0, var(--ghost-line) calc(50% + 2px), transparent calc(50% + 2px)),
    linear-gradient(315deg, var(--ghost-line) 0, var(--ghost-line) calc(50% + 2px), transparent calc(50% + 2px));
  background-size: var(--chamfer) var(--chamfer);
  background-position: left top, right bottom;
  background-repeat: no-repeat;
  color: var(--ink);
  box-shadow: inset 0 0 0 2px var(--ghost-line);
}
.btn--ghost:hover { background: var(--ink); color: #fff; }
.band--dark .btn--ghost { --ghost-line: rgba(255,255,255,.35); color: #fff; }
.band--dark .btn--ghost:hover { background: #fff; color: var(--ink); }

.btn--block { width: 100%; }
.btn--sm { padding: .7rem 1.15rem; font-size: .72rem; --chamfer: 8px; }

/* ---------- 6. Header ---------- */
.utility {
  background: var(--ink-2); color: var(--steel-2);
  font: 500 .72rem/1 var(--mono); letter-spacing: .04em;
  border-bottom: 1px solid var(--line-dark);
}
.utility__in { display: flex; flex-wrap: wrap; gap: .5rem 1.6rem; align-items: center; padding-block: .6rem; }
.utility a { color: var(--steel-2); text-decoration: none; }
.utility a:hover { color: var(--amber); }
.utility .push { margin-left: auto; color: var(--amber); }

.site-head {
  position: sticky; top: 0; z-index: 60;
  background: var(--ink); color: #fff;
  border-bottom: 1px solid var(--line-dark);
}
.site-head__in { display: flex; align-items: center; gap: 1.4rem; height: var(--head-h); }

.brand { display: flex; align-items: center; flex: none; text-decoration: none; }
.brand img { height: 48px; width: auto; }

.nav { margin-left: auto; display: flex; align-items: center; gap: .2rem; }
.nav a, .nav .drop__btn {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .62rem .78rem;
  font: 600 .82rem/1 var(--body); letter-spacing: .06em; text-transform: uppercase;
  color: #C9D0D7; text-decoration: none; background: none; border: 0; cursor: pointer;
  white-space: nowrap;
  transition: color .15s var(--ease);
}
.nav a:hover, .nav .drop__btn:hover { color: var(--amber); }
.nav a[aria-current="page"] { color: #fff; box-shadow: inset 0 -3px 0 var(--amber); }

.drop { position: relative; }
.drop__btn svg { width: 9px; height: 9px; transition: transform .2s var(--ease); }
.drop[data-open="true"] .drop__btn svg { transform: rotate(180deg); }
.drop__menu {
  position: absolute; top: calc(100% + 8px); left: 0; min-width: 268px;
  background: var(--ink-2); border: 1px solid var(--line-dark);
  padding: .45rem; margin: 0; list-style: none;
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity .18s var(--ease), transform .18s var(--ease), visibility .18s;
  box-shadow: 0 22px 44px rgba(0,0,0,.42);
}
.drop[data-open="true"] .drop__menu { opacity: 1; visibility: visible; transform: translateY(0); }
.drop__menu a { display: block; width: 100%; padding: .7rem .8rem; letter-spacing: .06em; }
.drop__menu a:hover { background: var(--ink-3); color: var(--amber); }

/* Header CTA: rests at the lit amber the other buttons only reach on hover, so
   it reads as the primary action before you touch it. Hover therefore cannot
   reuse the lift-and-lighten — it inverts to white and opens the broken edge.
   Qualified with .nav a because the plain .nav a rule (0,1,1) outranks .btn
   (0,1,0) and would otherwise paint this label nav-grey on amber. */
.nav a.head-cta {
  flex: none; margin-left: .5rem;
  font: 700 .78rem/1 var(--body); letter-spacing: .08em;
  background: #FFB627; color: var(--ink);
  transition: background .18s var(--ease), color .18s var(--ease), --chamfer .18s var(--ease);
}
.nav a.head-cta:hover,
.nav a.head-cta:focus-visible {
  background: #fff; color: var(--ink); transform: none; --chamfer: 16px;
}

.burger {
  display: none; flex: none; margin-left: auto;
  width: 44px; height: 44px; background: none; border: 1px solid var(--line-dark);
  color: #fff; cursor: pointer; align-items: center; justify-content: center;
}
.burger span { display: block; width: 20px; height: 2px; background: currentColor; position: relative; }
.burger span::before, .burger span::after { content: ""; position: absolute; left: 0; width: 20px; height: 2px; background: currentColor; }
.burger span::before { top: -6px; }
.burger span::after { top: 6px; }

/* ---------- 7. Hero ---------- */
/* The hero fills whatever is left of the viewport once the utility bar and the
   header have taken their share, so the three together are exactly one screen.
   min-height, not height: on narrow screens the stacked form is taller than a
   phone screen and must be allowed to grow. */
.hero {
  position: relative; background: var(--ink); color: #fff; overflow: hidden;
  padding-block: clamp(1.6rem, 3vw, 2.6rem);
  display: flex; align-items: center;
  min-height: calc(100vh - var(--chrome-h));
}
@supports (height: 100svh) {
  .hero { min-height: calc(100svh - var(--chrome-h)); }
}
.hero__bg { position: absolute; inset: 0; }
.hero__bg img,
.hero__bg video { width: 100%; height: 100%; object-fit: cover; }
/* The footage runs at full strength; legibility comes from a scrim that is
   dense only where the copy sits and clears away to the right, where the
   opaque quote card is doing the covering anyway. Measured against the frame:
   ~30% of the pixels behind the headline are brighter than 34% grey (polished
   bar stock and the coolant pour), so the left end has to stay heavy. */
.hero__bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg,
    rgba(16,19,23,.90) 0%,
    rgba(16,19,23,.76) 34%,
    rgba(16,19,23,.58) 52%,
    rgba(16,19,23,.24) 72%,
    rgba(16,19,23,.10) 100%);
}
.hero__in {
  position: relative; z-index: 2;
  display: grid; grid-template-columns: 1.06fr .94fr; gap: clamp(1.6rem, 3vw, 3rem); align-items: center;
}
/* A soft local scrim carried by the glyphs themselves. Invisible as an effect,
   but it buys the contrast that lets the overlay above stay light enough to
   read as video rather than as a dark panel. */
.hero .eyebrow,
.hero h1,
.hero__lede,
.hero__proof li { text-shadow: 0 1px 16px rgba(8, 10, 12, .85); }

.hero h1 { color: #fff; margin-bottom: .45em; font-size: clamp(1.85rem, 3.4vw, 2.8rem); }
.hero h1 .amber { color: var(--amber); }
.hero__lede { color: #DCE2E8; font-size: clamp(.95rem, 1.15vw, 1.04rem); max-width: 52ch; margin-bottom: 0; }

.hero__proof { list-style: none; margin: 1.4rem 0 0; padding: 0; display: grid; gap: .05rem; }
.hero__proof li {
  display: flex; align-items: baseline; gap: .85rem;
  padding: .5rem 0; border-top: 1px solid var(--line-dark);
  font: 500 .83rem/1.4 var(--body); color: #DCE2E8;
}
.hero__proof li:last-child { border-bottom: 1px solid var(--line-dark); }
.hero__proof b { font: 700 .78rem/1 var(--mono); color: var(--amber); flex: none; min-width: 72px; letter-spacing: .02em; }

/* ---------- 8. Quote form card ---------- */
.qcard {
  background: var(--surface); color: var(--ink);
  box-shadow: 0 26px 60px rgba(0,0,0,.4);
  clip-path: polygon(18px 0, 100% 0, 100% calc(100% - 18px), calc(100% - 18px) 100%, 0 100%, 0 18px);
}
.qcard__head { background: var(--ink-2); color: #fff; padding: 1.05rem 1.5rem; }
.qcard__head strong { display: block; font: 800 1.02rem/1.2 var(--display); text-transform: uppercase; letter-spacing: .01em; }
.qcard__head span { display: block; font: 500 .715rem/1.5 var(--mono); color: var(--steel-2); letter-spacing: .05em; margin-top: .2rem; }
.qcard__body { padding: 1.5rem; }

/* Sidebar variant — the primary conversion path on every service page, and as a
   white card on a white column it read as just another panel. Inverted to the
   dark shell with an amber header so it carries against the page instead of
   sitting in it. Everything below re-tunes the form for a dark ground: the base
   field styles assume a light card and would leave unreadable inputs.
   Selectors are qualified with .field so they outrank the (0,1,1) base rules. */
.qcard--side {
  background: var(--ink);
  border: 0;
  box-shadow: 0 20px 48px rgba(16,19,23,.26);
}
.qcard--side .qcard__head { background: var(--amber); }
.qcard--side .qcard__head strong { color: var(--ink); }
.qcard--side .qcard__head span { color: rgba(16,19,23,.74); }

.qcard--side .field label { color: var(--steel-2); }
.qcard--side .field .req { color: var(--ink); background: var(--amber); padding: 0 .28em; }
.qcard--side .field input,
.qcard--side .field textarea,
.qcard--side .field select {
  background-color: var(--ink-2); border-color: var(--line-dark); color: #fff;
}
/* background-color, not background: the shorthand would wipe the select arrow */
.qcard--side .field select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%2398A2AC' stroke-width='1.8'/></svg>");
}
.qcard--side .field input::placeholder,
.qcard--side .field textarea::placeholder { color: var(--steel); }
.qcard--side .field input:focus,
.qcard--side .field textarea:focus,
.qcard--side .field select:focus {
  background-color: var(--ink-3); border-color: var(--amber);
  box-shadow: 0 0 0 3px rgba(245,162,0,.26);
}
.qcard--side .field input[aria-invalid="true"],
.qcard--side .field textarea[aria-invalid="true"] {
  border-color: #E4614F; background-color: #2A1C1A;
}
.qcard--side .form-note { color: var(--steel-2); }
.qcard--side .form-note a { color: #fff; }
.qcard--side .form-status {
  background: rgba(245,162,0,.15); border-left-color: var(--amber); color: #fff;
}

/* Hero variant — the tallest thing in the hero, so it sets the height the whole
   section has to fit into. Trimmed here only; sidebar cards keep their spacing. */
.qcard--hero .qcard__head { padding: .85rem 1.3rem; }
.qcard--hero .qcard__body { padding: 1.15rem 1.3rem 1.3rem; }
.qcard--hero .field { margin-bottom: .7rem; }
.qcard--hero .field textarea { min-height: 62px; }
.qcard--hero .form-note { margin-top: .7rem; }

/* ---------- 9. Forms ---------- */
.field { margin-bottom: .92rem; }
.field label {
  display: block; margin-bottom: .35rem;
  font: 600 .69rem/1 var(--mono); letter-spacing: .11em; text-transform: uppercase; color: var(--steel);
}
.field .req { color: var(--amber-dk); }
.field input, .field select, .field textarea {
  width: 100%; padding: .72rem .82rem;
  font: 400 .93rem/1.4 var(--body); color: var(--ink);
  background: var(--paper-2); border: 1px solid var(--line); border-radius: 2px;
  transition: border-color .15s var(--ease), background .15s var(--ease);
}
.field textarea { min-height: 96px; resize: vertical; }
.field select { appearance: none; background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%23626C76' stroke-width='1.8'/></svg>"); background-repeat: no-repeat; background-position: right .8rem center; background-size: 11px; padding-right: 2.2rem; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--amber); background: #fff; outline: none; box-shadow: 0 0 0 3px rgba(245,162,0,.18); }
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"] { border-color: #C0392B; background: #FDF3F2; }

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem; }

.form-note { font: 500 .715rem/1.55 var(--mono); color: var(--steel); margin: .85rem 0 0; letter-spacing: .01em; }
.form-note a { color: var(--ink); }

.form-status { display: none; padding: 1rem 1.1rem; background: var(--amber-soft); border-left: 3px solid var(--amber); font-size: .9rem; margin-bottom: 1rem; }
.form-status[data-show="true"] { display: block; }

/* ---------- 10. Spec bar ---------- */
.specbar { background: var(--ink-2); color: #fff; }
.specbar__grid { display: grid; grid-template-columns: repeat(4, 1fr); }
.specbar__item { padding: 1.6rem 1.4rem; border-left: 1px solid var(--line-dark); }
.specbar__item:first-child { border-left: 0; padding-left: 0; }
.specbar__n { font: 800 clamp(1.5rem, 2.6vw, 2.1rem)/1 var(--display); color: var(--amber); display: block; }
.specbar__l { font: 500 .715rem/1.5 var(--mono); letter-spacing: .09em; text-transform: uppercase; color: var(--steel-2); margin-top: .5rem; display: block; }

/* ---------- 11. Cards / grids ---------- */
.grid { display: grid; gap: 1.6rem; }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }

.scard {
  background: var(--surface); border: 1px solid var(--line); border-radius: 2px;
  display: flex; flex-direction: column; text-decoration: none; overflow: hidden;
  transition: border-color .2s var(--ease), transform .2s var(--ease), box-shadow .2s var(--ease);
}
.scard:hover { border-color: var(--ink); transform: translateY(-3px); box-shadow: 0 16px 34px rgba(16,19,23,.12); }
.scard__img { aspect-ratio: 16 / 10; overflow: hidden; background: var(--ink-3); }
.scard__img img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s var(--ease); }
.scard:hover .scard__img img { transform: scale(1.05); }
.scard__body { padding: 1.3rem 1.35rem 1.5rem; flex: 1; display: flex; flex-direction: column; }
.scard__body h3 { margin-bottom: .45rem; }
.scard__body p { font-size: .92rem; color: var(--steel); margin-bottom: 1rem; }
.scard__more { margin-top: auto; font: 700 .72rem/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--ink); display: inline-flex; align-items: center; gap: .45rem; }
.scard:hover .scard__more { color: var(--amber-dk); }
.scard__more::after { content: "→"; transition: transform .2s var(--ease); }
.scard:hover .scard__more::after { transform: translateX(4px); }

/* Industry card — same 16/10 image box as .scard, but not a link, so it gets
   no hover lift and no border; the photo carries it and the copy stays plain. */
.icard__img {
  aspect-ratio: 16 / 10; overflow: hidden; background: var(--ink-3);
  border-radius: 2px; margin-bottom: 1.1rem;
}
.icard__img img { width: 100%; height: 100%; object-fit: cover; }
.icard h3 { margin-bottom: .45rem; }

/* Machine spec card — carries the dimension line */
.mcard { background: var(--surface); border: 1px solid var(--line); border-radius: 2px; padding: 1.25rem 1.3rem 1.35rem; }
.mcard h4 { font-family: var(--display); font-size: 1.02rem; margin-bottom: .15rem; }
.mcard .qty { font: 600 .69rem/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--amber-dk); }
.band--dark .mcard { background: var(--ink-2); border-color: var(--line-dark); }
.band--dark .mcard h4 { color: #fff; }

/* Plain feature list */
.ticks { list-style: none; margin: 0; padding: 0; display: grid; gap: .1rem; }
.ticks li { position: relative; padding: .62rem 0 .62rem 1.75rem; border-bottom: 1px solid var(--line); font-size: .96rem; }
.ticks li::before { content: ""; position: absolute; left: 0; top: 1.15em; width: 9px; height: 9px; background: var(--amber); clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%); }
.band--dark .ticks li { border-bottom-color: var(--line-dark); }

/* ---------- 12. Inner page shell + sidebar ---------- */
/* Each page supplies its own banner photo and its own scrim weight as inline
   custom properties, because the set splits in two: the wide shop interiors
   are roughly twice as bright as the close-up process shots. One shared scrim
   would either wash the copy out or bury the darker photos entirely. */
.page-head {
  background-color: var(--ink);
  color: #fff; padding-block: clamp(2.6rem, 5vw, 4.2rem);
  position: relative; overflow: hidden;
}
/* Carried as a real <img>, not a CSS background: a url() inside a custom
   property resolves against the stylesheet (assets/css/), not the page, so the
   background-image form silently pointed at assets/css/assets/img/ and fetched
   nothing. An <img> also lets the preload scanner find it. */
.page-head__bg { position: absolute; inset: 0; z-index: 0; }
.page-head__bg img { width: 100%; height: 100%; object-fit: cover; }
.page-head::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(100deg,
    rgba(16,19,23, var(--head-scrim, .82)) 0%,
    rgba(16,19,23, calc(var(--head-scrim, .82) * .88)) 42%,
    rgba(16,19,23, calc(var(--head-scrim, .82) * .55)) 100%);
}
.page-head::after {
  content: ""; position: absolute; right: -60px; top: -40px; width: 320px; height: 320px; z-index: 1;
  background: var(--ink-2); clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%); opacity: .55;
}
.page-head__in { position: relative; z-index: 2; }
.page-head .crumbs,
.page-head h1,
.page-head p { text-shadow: 0 1px 14px rgba(8, 10, 12, .8); }
.page-head h1 { color: #fff; margin-bottom: .35em; }
.page-head p { color: #DCE2E8; max-width: 58ch; margin: 0; }
.page-head .crumbs, .page-head .crumbs a { color: #D6DDE3; }
/* Qualified with .page-head because `.page-head p { margin: 0 }` is (0,1,1) and
   outranks a bare .crumbs (0,1,0) — the margin set there is silently dropped. */
.page-head .crumbs { margin-bottom: 1.8rem; }

.crumbs { font: 500 .715rem/1 var(--mono); letter-spacing: .09em; text-transform: uppercase; color: var(--steel-2); margin-bottom: 1.8rem; }
.crumbs a { color: var(--steel-2); text-decoration: none; }
.crumbs a:hover { color: var(--amber); }
.crumbs span { color: var(--line-dark); margin-inline: .45rem; }

.shell { display: grid; grid-template-columns: minmax(0, 1fr) 348px; gap: clamp(2rem, 4vw, 3.4rem); align-items: start; padding-block: clamp(2.8rem, 5vw, 4.4rem); }
/* No sidebar: the grid was supplying the measure, so the prose needs its own or
   it runs to the full 1240px wrap and becomes unreadable. */
.shell--solo { grid-template-columns: minmax(0, 1fr); }
.prose--solo { max-width: 72ch; }

/* Background for the inner-page content areas. The wrapper exists because
   .shell IS the 1240px wrap — painting the background on it would cut the chips
   off at the wrap edge, mid-page. This lets it bleed off the viewport instead.

   `fixed` pins it to the viewport rather than the document, so it stays in the
   bottom-right corner for the whole scroll instead of only appearing once the
   reader reaches the end of a 3600px article. Note that with `fixed` both size
   and position resolve against the viewport, not this element.

   85% is safe against the prose because the plate's left 65% is pure white
   (measured 255): the chips only begin past that, which clears the prose column
   by +97px at 1280 and more at every larger width. */
.shell-bg {
  background-image: url("../img/bg-page.jpg");
  background-size: 85% auto;
  background-position: right bottom;
  background-repeat: no-repeat;
  background-attachment: fixed;
}
/* `fixed` is unreliable on touch — iOS Safari mis-sizes or drops it outright —
   and it reads as parallax, which is unwelcome under reduced-motion. Both fall
   back to scrolling with the document, which still works, just less visibly. */
@media (hover: none) {
  .shell-bg { background-attachment: scroll; }
}
@media (prefers-reduced-motion: reduce) {
  .shell-bg { background-attachment: scroll; }
}
.sidebar { display: grid; gap: 1.35rem; }

.infocard { background: var(--paper); border: 1px solid var(--line); padding: 1.35rem 1.4rem; border-radius: 2px; }
.infocard h4 { font: 800 .95rem/1.2 var(--display); text-transform: uppercase; letter-spacing: .04em; margin-bottom: .9rem; }
.infocard dl { margin: 0; display: grid; gap: .75rem; }
.infocard dt { font: 600 .67rem/1 var(--mono); letter-spacing: .11em; text-transform: uppercase; color: var(--steel); }
.infocard dd { margin: .25rem 0 0; font-size: .95rem; }
.infocard dd a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--amber); }
.infocard dd a:hover { color: var(--amber-dk); }

/* ---------- Icon set ----------
   Data-URI SVGs applied as masks rather than background images, so each glyph
   is painted in whatever colour the rule chooses and can follow a hover state.
   Stroke colour inside the SVG is irrelevant — only its alpha is used. */
:root {
  --ic-pin:   url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21.5s7-6.6 7-11.5a7 7 0 1 0-14 0c0 4.9 7 11.5 7 11.5z'/%3E%3Ccircle cx='12' cy='10' r='2.6'/%3E%3C/svg%3E");
  --ic-phone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.8 3h3.1l1.6 4-2.1 1.6a12.4 12.4 0 0 0 6 6L17 12.5l4 1.6v3.1a2 2 0 0 1-2.2 2A17.5 17.5 0 0 1 3.7 5.2A2 2 0 0 1 6.8 3z'/%3E%3C/svg%3E");
  --ic-mail:  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2.5' y='5' width='19' height='14' rx='1.6'/%3E%3Cpath d='m3.2 6.6 8.8 6.4 8.8-6.4'/%3E%3C/svg%3E");
  --ic-clock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7.2V12l3.4 2.1'/%3E%3C/svg%3E");
}

/* Icon + label + value rows. Replaces the dt/dd pairs these cards used: a
   definition list left nowhere to hang an icon without inventing extra markup
   inside every dt. */
.clist { list-style: none; margin: 0; padding: 0; display: grid; gap: .95rem; }
/* The icon is absolutely positioned rather than a grid track. As a grid the row
   held three items — ::before, the label span, and the value — so the value was
   pushed onto a second row inside the 1.05rem icon column and wrapped one word
   per line. Absolute keeps the row a normal block and lets the value flow. */
.clist li { position: relative; padding-left: 1.75rem; font-size: .95rem; }
.clist li::before {
  content: ""; position: absolute; left: 0; top: .12rem;
  width: 1.05rem; height: 1.05rem;
  background-color: var(--amber-dk);
  -webkit-mask: var(--ic) center / contain no-repeat;
          mask: var(--ic) center / contain no-repeat;
}
.clist__l {
  display: block; margin-bottom: .2rem;
  font: 600 .64rem/1 var(--mono); letter-spacing: .11em; text-transform: uppercase;
  color: var(--steel);
}
.clist a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--amber); }
.clist a:hover { color: var(--amber-dk); }
.clist--pin   { --ic: var(--ic-pin); }
.clist--phone { --ic: var(--ic-phone); }
.clist--mail  { --ic: var(--ic-mail); }
.clist--clock { --ic: var(--ic-clock); }

/* Capabilities box. It was a bulleted text list that read as prose rather than
   as somewhere to go; these are full-width rows with a chevron, which both
   signals navigation and gives a tap target the width of the card. */
.navlist { list-style: none; margin: 0; padding: 0; }
.navlist li + li { border-top: 1px solid var(--line); }
.navlist a {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  padding: .68rem 0; color: var(--ink); text-decoration: none;
  font: 600 .87rem/1.35 var(--body);
  transition: color .15s var(--ease), padding-left .18s var(--ease);
}
.navlist a::after {
  content: ""; flex: none; width: 6px; height: 6px;
  border-top: 2px solid var(--amber); border-right: 2px solid var(--amber);
  transform: rotate(45deg); transition: transform .18s var(--ease);
}
.navlist a:hover { color: var(--amber-dk); padding-left: .28rem; }
.navlist a:hover::after { transform: rotate(45deg) translate(2px, -2px); }

/* Article typography */
.prose h2 { margin-top: 2.5rem; }
.prose h2:first-child { margin-top: 0; }
.prose h3 { margin-top: 1.9rem; font-size: 1.1rem; }
.prose > p:first-of-type { font-size: 1.06rem; }
.prose a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--amber); }
.prose a:hover { color: var(--amber-dk); }
.prose ul { padding-left: 0; list-style: none; margin: 0 0 1.4rem; }
.prose ul li { position: relative; padding: .5rem 0 .5rem 1.7rem; }
.prose ul li::before { content: ""; position: absolute; left: 0; top: 1.05em; width: 9px; height: 9px; background: var(--amber); clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%); }

/* Answer block — the direct answer to a question heading */
.answer {
  background: var(--paper); border-left: 3px solid var(--amber);
  padding: 1.15rem 1.3rem; margin: 0 0 1.4rem;
  font-size: 1.02rem; font-weight: 500;
}
.answer p:last-child { margin-bottom: 0; }

/* Inline CTA inside prose */
.prose-cta { margin: 2rem 0; }

/* FAQ */
.faq { border-top: 1px solid var(--line); }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__q {
  width: 100%; text-align: left; background: none; border: 0; cursor: pointer;
  padding: 1.15rem 2.5rem 1.15rem 0; position: relative;
  font-family: var(--display); font-weight: 700; font-size: 1.02rem; line-height: 1.35; color: var(--ink);
}
.faq__q::after {
  content: ""; position: absolute; right: .4rem; top: 50%; width: 13px; height: 2px;
  background: var(--amber); transform: translateY(-50%);
}
.faq__q::before {
  content: ""; position: absolute; right: 5.5px; top: 50%; width: 2px; height: 13px;
  background: var(--amber); transform: translateY(-50%); transition: transform .22s var(--ease);
}
.faq__item[data-open="true"] .faq__q::before { transform: translateY(-50%) scaleY(0); }
/* Slides instead of toggling display, which cannot be transitioned. The panel
   clips with overflow and animates max-height; main.js writes the pixel height
   because `auto` is not an interpolable value.

   The bottom spacing lives on the last child rather than as padding on .faq__a:
   padding is not squeezed by max-height, so it would leave every closed panel
   1.3rem tall. */
.faq__a {
  overflow: hidden;
  max-height: 0;
  padding-right: 2.5rem;
  color: var(--steel);
  transition: max-height .34s var(--ease);
}
/* Fallback before main.js runs, and if it never does: an open item is unclipped
   and readable. JS then writes an inline pixel height, which outranks this. */
.faq__item[data-open="true"] .faq__a { max-height: none; }
.faq__a p:last-child { margin-bottom: 1.3rem; }
.faq__a strong { color: var(--ink); }

/* ---------- 13. Gallery ---------- */
.gal { display: grid; grid-template-columns: repeat(4, 1fr); gap: .7rem; }
.gal button {
  padding: 0; border: 0; cursor: pointer; background: var(--ink-3);
  aspect-ratio: 1 / 1; overflow: hidden; display: block;
}
.gal img { width: 100%; height: 100%; object-fit: cover; transition: transform .45s var(--ease), opacity .25s var(--ease); }
.gal button:hover img { transform: scale(1.07); opacity: .82; }

.lightbox {
  position: fixed; inset: 0; z-index: 200; background: rgba(10,12,14,.94);
  display: none; align-items: center; justify-content: center; padding: 3.5rem 1.2rem;
}
.lightbox[data-open="true"] { display: flex; }
.lightbox img { max-width: min(1100px, 92vw); max-height: 84vh; width: auto; object-fit: contain; }
.lightbox__close, .lightbox__nav {
  position: absolute; background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.25);
  color: #fff; width: 46px; height: 46px; cursor: pointer; font-size: 1.3rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.lightbox__close { top: 1.1rem; right: 1.1rem; }
.lightbox__nav--prev { left: 1.1rem; top: 50%; transform: translateY(-50%); }
.lightbox__nav--next { right: 1.1rem; top: 50%; transform: translateY(-50%); }
.lightbox__close:hover, .lightbox__nav:hover { background: var(--amber); color: var(--ink); border-color: var(--amber); }
.lightbox__count { position: absolute; bottom: 1.2rem; left: 50%; transform: translateX(-50%); font: 600 .74rem/1 var(--mono); letter-spacing: .1em; color: var(--steel-2); }

/* ---------- 14. CTA band ---------- */
.cta-band { background: var(--amber); color: var(--ink); }
.cta-band__in { display: flex; flex-wrap: wrap; align-items: center; gap: 1.6rem 2.4rem; padding-block: clamp(2.4rem, 4vw, 3.2rem); }
.cta-band h2 { margin: 0; flex: 1 1 380px; font-size: clamp(1.5rem, 2.8vw, 2.1rem); }
.cta-band .actions { display: flex; flex-wrap: wrap; gap: .8rem; }
/* background-color, not the background shorthand: the shorthand resets
   background-image to none at (0,2,0), which would erase the ghost button's
   diagonal-edge gradients defined at (0,1,0). */
.cta-band .btn { background-color: var(--ink); color: #fff; }
.cta-band .btn:hover { background-color: #000; }
.cta-band .btn--ghost { background-color: transparent; color: var(--ink); }
.cta-band .btn--ghost:hover { background-color: var(--ink); color: #fff; }

/* ---------- 15. Footer ---------- */
.site-foot { background: var(--ink); color: var(--steel-2); padding-block: clamp(2.8rem, 5vw, 4rem) 0; }
.site-foot__grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1.2fr; gap: 2.2rem; }
.site-foot img.logo { height: 64px; width: auto; margin-bottom: 1.25rem; }
.site-foot h4 { font: 800 .8rem/1 var(--display); letter-spacing: .13em; text-transform: uppercase; color: #fff; margin-bottom: 1.1rem; }
.site-foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.site-foot a { color: var(--steel-2); text-decoration: none; font-size: .93rem; }
.site-foot a:hover { color: var(--amber); }
.site-foot p { font-size: .93rem; margin-bottom: .8rem; }
.site-foot .addr { font-style: normal; font-size: .93rem; line-height: 1.85; }

/* Amber diamond markers on the footer link columns — the same shape .ticks and
   .prose ul use, so the footer speaks the same language as the body. Scoped to
   .foot-links so the icon list in the contact column keeps its own markers. */
.site-foot .foot-links { gap: .5rem; }
.site-foot .foot-links li { position: relative; padding-left: 1.15rem; font-size: .93rem; line-height: 1.5; }
.site-foot .foot-links li::before {
  content: ""; position: absolute; left: 0; top: .5em;
  width: 7px; height: 7px; background: var(--amber);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}
/* Footer icon list. Qualified with .site-foot throughout: `.site-foot ul` is
   (0,1,1) and would otherwise beat a bare .clist at (0,1,0) on gap, and
   `.site-foot a` would beat .clist a on colour. No labels here — on three rows
   the icon alone is unambiguous. */
.site-foot .clist { gap: .72rem; }
.site-foot .clist li { font-size: .93rem; line-height: 1.5; }
.site-foot .clist li::before { background-color: var(--amber); }
.site-foot .clist a { color: var(--steel-2); border-bottom: 0; }
.site-foot .clist a:hover { color: var(--amber); }
.foot-bottom {
  margin-top: 2.6rem; border-top: 1px solid var(--line-dark); padding-block: 1.3rem;
  display: flex; flex-wrap: wrap; gap: .6rem 1.5rem; align-items: center;
  font: 500 .72rem/1.6 var(--mono); letter-spacing: .04em; color: var(--steel);
}
.foot-bottom .push { margin-left: auto; }
/* The bar's own text is --steel, which is only 3.4:1 on --ink — too low for a
   link. Lifted to --steel-2 (7.1:1) and given a rule so it reads as clickable.
   font-size: inherit because `.site-foot a` sets .93rem, which would make the
   link larger than the .72rem line it sits on. */
.foot-bottom a {
  color: var(--steel-2); font-size: inherit; text-decoration: none;
  border-bottom: 1px solid rgba(245, 162, 0, .45);
  transition: color .15s var(--ease), border-color .15s var(--ease);
}
.foot-bottom a:hover { color: var(--amber); border-bottom-color: var(--amber); }

/* ---------- 16. Responsive ---------- */

/* Short desktop screens (the 768px-tall laptop) can't take the hero at its
   comfortable spacing. Tighten type and form padding only where vertical room
   is genuinely scarce, so roomier displays keep the looser setting. Scoped
   above 1080px because below that the hero is single-column and scrolls anyway. */
@media (min-width: 1081px) and (max-height: 720px) {
  .hero { padding-block: clamp(1rem, 2vw, 1.6rem); }
  .hero h1 { font-size: clamp(1.7rem, 2.9vw, 2.3rem); }
  .hero__lede { font-size: .95rem; }
  .hero__proof { margin-top: 1rem; }
  .hero__proof li { padding: .38rem 0; font-size: .8rem; }
  .qcard--hero .qcard__head { padding: .7rem 1.2rem; }
  .qcard--hero .qcard__body { padding: .95rem 1.2rem 1.05rem; }
  .qcard--hero .field { margin-bottom: .5rem; }
  .qcard--hero .field label { margin-bottom: .22rem; }
  .qcard--hero .field input,
  .qcard--hero .field select,
  .qcard--hero .field textarea { padding: .58rem .75rem; }
  .qcard--hero .field textarea { min-height: 48px; }
  .qcard--hero .btn { padding: .78rem 1.4rem; }
  .qcard--hero .form-note { margin-top: .5rem; font-size: .68rem; }
}

@media (max-width: 1080px) {
  .hero__in { grid-template-columns: 1fr; }
  .shell { grid-template-columns: 1fr; }
  .sidebar { position: static; grid-template-columns: 1fr 1fr; }
  .specbar__grid { grid-template-columns: repeat(2, 1fr); }
  .specbar__item:nth-child(3) { border-left: 0; padding-left: 0; }
  .specbar__item:nth-child(odd) { border-left: 0; padding-left: 0; }
  .site-foot__grid { grid-template-columns: 1fr 1fr; }
}

/* The nav needs the drawer earlier than the rest of the layout does. With the
   Capabilities tab added it measures ~700px, which crowds the logo below about
   1000px and wraps "Photo Gallery" onto two lines. Split out from the 900px
   block so the content grids still switch where they always did.
   main.js mirrors this threshold in isDesktop(). */
@media (max-width: 1000px) {
  .nav {
    position: fixed; inset: 0 0 0 auto; width: min(340px, 84vw);
    background: var(--ink-2); border-left: 1px solid var(--line-dark);
    flex-direction: column; align-items: stretch; gap: 0;
    padding: calc(var(--head-h) + 1.2rem) 1.2rem 2rem;
    transform: translateX(100%); transition: transform .28s var(--ease);
    overflow-y: auto; z-index: 55;
  }
  .nav[data-open="true"] { transform: translateX(0); }
  .nav a, .nav .drop__btn { padding: .9rem .4rem; width: 100%; justify-content: space-between; }
  .nav a[aria-current="page"] { box-shadow: none; color: var(--amber); }
  .drop__menu {
    position: static; opacity: 1; visibility: visible; transform: none;
    box-shadow: none; border: 0; border-left: 2px solid var(--line-dark);
    margin-left: .4rem; padding: 0 0 .4rem .4rem; display: none;
  }
  .drop[data-open="true"] .drop__menu { display: block; }
  .head-cta { display: none; }
  /* matched to .nav a.head-cta above, or that rule's margin-left would win here */
  .nav a.head-cta { display: inline-flex; margin: 1rem 0 0; }
  .burger { display: flex; }
}

@media (max-width: 900px) {
  /* Corner-anchored backgrounds are sized as a share of the viewport, so on a
     phone they shrink to a smudge. Scale them back up — the sections stack and
     grow tall here, so there is room for them without crowding anything. */
  .band--tex--whyus { background-size: 88% auto; }
  .band--machine { background-size: 96% auto; }
  /* Below 1080 the shell is single-column and the sidebar stacks under the
     prose, so the bottom of the page is opaque cards rather than copy. */
  .shell-bg { background-size: 96% auto; background-attachment: scroll; }
  .grid--3 { grid-template-columns: repeat(2, 1fr); }
  .gal { grid-template-columns: repeat(3, 1fr); }
}


@media (max-width: 620px) {
  body { font-size: 16px; }
  .grid--3, .grid--2 { grid-template-columns: 1fr; }
  .sidebar { grid-template-columns: 1fr; }
  .specbar__grid { grid-template-columns: 1fr 1fr; }
  .specbar__item { padding: 1.15rem .9rem; }
  .gal { grid-template-columns: repeat(2, 1fr); gap: .5rem; }
  .site-foot__grid { grid-template-columns: 1fr; }
  .field-row { grid-template-columns: 1fr; }
  .utility__in { font-size: .68rem; }
  .utility .push { margin-left: 0; }
  .foot-bottom .push { margin-left: 0; }
}

/* ---------- 17. Motion preferences ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---------- 18. Print ---------- */
@media print {
  .site-head, .utility, .sidebar, .cta-band, .site-foot, .burger { display: none !important; }
  body { font-size: 12pt; }
  .shell { grid-template-columns: 1fr; }
}
