/* ==========================================================================
   YITAC — Website Revamp Prototype
   Design system. Platform-agnostic: no framework dependency, so this can be
   ported to a Drupal 7 theme or a modern stack without rewriting.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */
:root {
  /* Brand. --red is taken from the live theme stylesheet (#DA201B, 67 uses).
     The concept deck's swatch reads slightly brighter; change this one value
     if brand guidelines say otherwise and it propagates everywhere. */
  --red:        #DA201B;
  --red-deep:   #B31813;
  --red-tint:   #FBEDEC;
  /* Accent for slate/dark grounds. Chosen for brand fidelity over contrast:
     2.14:1 on --slate, below the 4.5:1 WCAG threshold for text this size.
     A lighter tint reads pink, so the trade was made deliberately — the
     alternative is darkening the panels themselves. See .section--slate
     .eyebrow. Do not reuse on light grounds: 3.19:1 on white. */
  --red-on-dark: #FF5347;

  --slate:      #4E5D64;
  --slate-deep: #3B474C;
  --slate-soft: #64757D;

  --ivory:      #FCFBF7;
  --stone:      #F0EFEC;
  --white:      #FFFFFF;

  --ink:        #22282B;
  --body:       #5A666B;
  --muted:      #8A9499;
  --line:       #DEDCD6;
  --line-soft:  #ECEAE4;
  --on-dark:    rgba(255,255,255,.78);
  --line-dark:  rgba(255,255,255,.18);

  /* Type — Arial first, Arimo as the metric-compatible web fallback */
  --font: Arial, Arimo, "Helvetica Neue", Helvetica, sans-serif;

  --step--1: clamp(.8125rem, .78rem + .16vw, .875rem);
  --step-0:  clamp(1rem, .96rem + .2vw, 1.0625rem);
  --step-1:  clamp(1.125rem, 1.05rem + .35vw, 1.3125rem);
  --step-2:  clamp(1.375rem, 1.24rem + .6vw, 1.75rem);
  --step-3:  clamp(1.75rem, 1.5rem + 1.1vw, 2.5rem);
  --step-4:  clamp(2.125rem, 1.6rem + 2.3vw, 3.5rem);
  --step-5:  clamp(2.5rem, 1.7rem + 3.6vw, 4.5rem);

  /* Space */
  --gutter: clamp(20px, 4.5vw, 64px);
  --maxw: 1300px;
  --section-y: clamp(56px, 8vw, 120px);
  --radius: 2px;
}

/* --------------------------------------------------------------------------
   2. Reset + base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--step-0);
  line-height: 1.65;
  color: var(--body);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
}

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

h1, h2, h3, h4 { color: var(--ink); line-height: 1.1; margin: 0 0 .5em; font-weight: 700; letter-spacing: -.02em; }
h1 { font-size: var(--step-5); }
h2 { font-size: var(--step-4); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); letter-spacing: -.01em; }
p  { margin: 0 0 1.15em; max-width: 68ch; }
p:last-child { margin-bottom: 0; }

a { color: var(--red); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--red-deep); }

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

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--red); color: #fff; padding: 14px 22px; font-weight: 700;
}
.skip-link:focus { left: 0; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* --------------------------------------------------------------------------
   3. Layout primitives
   -------------------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--section-y); }
.section--tight { padding-block: clamp(40px, 5vw, 72px); }
/* For a full-padding section sitting directly above a --tight one: the two
   paddings stack across the colour change, so matching the smaller value
   keeps the gap even on both sides of the join. */
.section--tight-bottom { padding-bottom: clamp(40px, 5vw, 72px); }
.section--ivory { background: var(--ivory); }
.section--stone { background: var(--stone); }
.section--slate { background: var(--slate); }
.section--slate, .section--slate p { color: var(--on-dark); }
.section--slate h1, .section--slate h2, .section--slate h3, .section--slate h4 { color: #fff; }

.split {
  display: grid;
  gap: clamp(32px, 5vw, 80px);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 900px) {
  .split { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
  .split--lede { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); align-items: end; }
  /* --lede bottom-aligns because the right column is usually a lede
     paragraph sitting on the headline's baseline. When it holds a block with
     its own mass (the 20-years stat), centring reads as one row instead. */
  .split--lede.split--mid { align-items: center; }
}

/* Full-bleed two-column band where both sides must share one height —
   the contact page's slate panel has to run the full depth of the form. */
.split--stretch { align-items: stretch; }

/* Splits at 760 rather than the 900 the rest of .split uses. This carries the
   contact page, where the two halves are the contact details and the form:
   two independent blocks, not a headline and its supporting column, so they
   read as one page side by side on a tablet instead of the details scrolling
   past before the form starts. Placed after the 900 block so it holds there
   too. The form's own columns are handled by a container query — see
   .form-grid — since its width no longer tracks the viewport. */
@media (min-width: 760px) {
  .split--even { grid-template-columns: 1fr 1fr; }
}

.grid-4 { display: grid; gap: clamp(28px, 3.2vw, 44px); grid-template-columns: 1fr; }
@media (min-width: 620px)  { .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .grid-4 { grid-template-columns: repeat(4, 1fr); } }

.grid-3 { display: grid; gap: clamp(28px, 3.2vw, 48px); grid-template-columns: 1fr; }
@media (min-width: 760px) { .grid-3 { grid-template-columns: repeat(3, 1fr); } }
/* Cards that carry an image need more column than the bare three-up leaves on a
   tablet: at 768 the columns fall to ~210px, too narrow for a landscape frame
   and a title. Grids holding them run two-up through the tablet range and reach
   three at 1040. Text-only panels and flat cards keep the 760 step — they have
   no frame to squeeze. */
@media (min-width: 760px) and (max-width: 1039px) {
  .grid-3:has(.card > .img-slot) { grid-template-columns: repeat(2, 1fr); }
}

/* Five-up, for the accreditation row. Steps 2 -> 3 -> 5 rather than 2 -> 4 -> 5
   so no breakpoint ever leaves a single orphaned mark on its own row. */
.grid-5 { display: grid; gap: clamp(20px, 2.4vw, 32px); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 620px)  { .grid-5 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1040px) { .grid-5 { grid-template-columns: repeat(5, 1fr); } }

.grid-2 { display: grid; gap: clamp(24px, 3vw, 40px); grid-template-columns: 1fr; }
@media (min-width: 700px) { .grid-2 { grid-template-columns: repeat(2, 1fr); } }

/* Six partner logos. Its own steps rather than .grid-3 because the widest
   lockups run to ~205px: .grid-3 goes three-up at 760, which leaves ~175px
   inside a box and shrinks the wide marks out of step with the compact ones.
   1 -> 2 -> 3 keeps two clean rows at desktop and never orphans a logo. */
.grid-partners {
  display: grid;
  gap: clamp(40px, 4.4vw, 60px) clamp(24px, 3vw, 44px);
  grid-template-columns: 1fr;
}
@media (min-width: 520px) { .grid-partners { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .grid-partners { grid-template-columns: repeat(3, 1fr); } }

/* --------------------------------------------------------------------------
   4. Typographic components
   -------------------------------------------------------------------------- */
.eyebrow {
  display: block;
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--red);
  margin: 0 0 18px;
}
/* Brand red at full strength is 1.37:1 on slate — the hue and the background
   sit at almost the same lightness. --red-on-dark lifts it to 2.14:1, which
   is better but still under the threshold; in sRGB a red light enough to pass
   here is necessarily desaturated, and that reads as pink. Accepted as a
   brand call. Darkening these panels to ink would let the same red hit 4.68:1
   if this is ever revisited. */
.section--slate .eyebrow, .hero .eyebrow, .feature-case__body .eyebrow { color: var(--red-on-dark); }

.lede {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--body);
  max-width: 60ch;
}
.section--slate .lede { color: var(--on-dark); }

.rule {
  width: 64px; height: 4px; background: var(--red);
  border: 0; margin: 0 0 28px;
}

.text-muted { color: var(--muted); }
.small { font-size: var(--step--1); line-height: 1.55; }

/* --------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 16px 28px;
  font-size: var(--step-0);
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  border: 2px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease, transform .18s ease;
}
.btn:hover { transform: translateY(-1px); }

.btn--primary { background: var(--red); color: #fff; border-color: var(--red); }
.btn--primary:hover { background: var(--red-deep); border-color: var(--red-deep); color: #fff; }

.btn--ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn--ghost:hover { border-color: var(--ink); color: var(--ink); }

.btn--on-dark { background: transparent; color: #fff; border-color: rgba(255,255,255,.55); }
.btn--on-dark:hover { background: #fff; color: var(--ink); border-color: #fff; }

.btn--slate { background: var(--slate); color: #fff; border-color: var(--slate); }
.btn--slate:hover { background: var(--slate-deep); border-color: var(--slate-deep); color: #fff; }

.btn-row { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 34px; }

.link-arrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: var(--step--1); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; text-decoration: none; color: var(--red);
}
.link-arrow:hover { color: var(--red-deep); text-decoration: underline; text-underline-offset: 4px; }

/* Capability shortcuts. White against the stone band so they read as buttons,
   with the red carried by an edge rather than four red labels competing with
   each other. Fixed 2-up rather than auto-fit: the desktop layout puts this in
   the narrow half of a .split where two fit, and auto-fit would let the tablet
   full-width band run to three and break that 2x2 reading. */
.caps { display: grid; gap: 12px; grid-template-columns: 1fr; }
@media (min-width: 620px) { .caps { grid-template-columns: repeat(2, 1fr); } }
.caps__item {
  display: flex; align-items: center; min-height: 68px;
  padding: 14px 18px;
  background: #fff;
  border: 1px solid var(--line-soft); border-left: 4px solid var(--red);
  border-radius: var(--radius);
  font-weight: 700; font-size: var(--step-0); line-height: 1.25;
  color: var(--ink); text-decoration: none;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.caps__item:hover { background: var(--red); color: #fff; border-left-color: var(--red-deep); }

/* Service tiles — the About page's route into Services. Deliberately not
   .caps__item: that component is a shortcut chip carrying nothing but a name,
   while these have to earn a click on a page where the reader has no service
   context yet, so each carries a line of description and its own arrow. The
   red is held on the top edge and only arrives on hover, keeping four tiles
   from competing with the red CTA further down the page. */
.svc-tiles { display: grid; gap: clamp(14px, 1.6vw, 20px); grid-template-columns: 1fr; }
@media (min-width: 620px)  { .svc-tiles { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .svc-tiles { grid-template-columns: repeat(4, 1fr); } }

.svc-tile {
  display: flex; flex-direction: column;
  padding: clamp(22px, 2.4vw, 28px);
  background: #fff;
  border: 1px solid var(--line-soft);
  border-top: 3px solid var(--line);
  border-radius: var(--radius);
  text-decoration: none;
  transition: border-top-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
.svc-tile:hover { border-top-color: var(--red); transform: translateY(-3px); box-shadow: 0 12px 28px rgba(34,40,43,.09); }

.svc-tile__num {
  font-size: var(--step--1); font-weight: 700;
  letter-spacing: .08em; color: var(--muted); margin-bottom: 18px;
}
.svc-tile__name {
  font-size: var(--step-1); font-weight: 700; line-height: 1.25;
  color: var(--ink); margin-bottom: .5em;
}
.svc-tile__desc { font-size: var(--step--1); color: var(--body); margin: 0 0 22px; }
/* Pushed to the foot so the arrows line up across tiles whose descriptions
   run to different lengths. */
.svc-tile .link-arrow { margin-top: auto; }

/* Three-up variant. Used where a tile is a category holding several product
   links rather than a single destination — the technical index on Solutions.
   Declared after the base breakpoints so it wins at the 4-column step. */
.svc-tiles--3 { grid-template-columns: 1fr; }
/* Three at 900 rather than the 760 that bare .grid-3 columns use: these
   carry card padding and a border, so the measure inside them runs short
   and product names start wrapping mid-phrase at tablet widths. Two-up is
   not an option with three tiles — it orphans one on its own row.
   Each tile spans the same three rows of the parent and inherits them as a
   subgrid, so a category name that wraps to two lines lifts the name row for
   every tile and all three product lists still begin on one line. */
@media (min-width: 900px) {
  .svc-tiles--3 {
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: auto auto auto;
  }
  .svc-tiles--3 .svc-tile--list {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 3;
    row-gap: 0;
  }
}
@media (min-width: 1040px) { .svc-tiles--3 { grid-template-columns: repeat(3, 1fr); } }

/* The card itself is not a link here, so the lift and the red top edge are
   withdrawn — only the rows inside it are clickable. */
.svc-tile--list {
  padding: clamp(26px, 2.8vw, 34px);
}
.svc-tile--list:hover {
  transform: none; box-shadow: none; border-top-color: var(--line);
}
/* The gap the name would have carried moves onto the list, so it lands on the
   subgrid row boundary and stays equal across tiles whatever the name does. */
.svc-tile--list .svc-tile__name { margin-bottom: 0; }
.svc-tile__links {
  list-style: none; margin: 30px 0 0; padding: 0;
  align-self: start;
}
.svc-tile__links li + li { border-top: 1px solid var(--line-soft); }
.svc-tile__links a {
  display: block; padding: 16px 0;
  font-size: var(--step--1); line-height: 1.45;
  color: var(--body); text-decoration: none;
}
.svc-tile__links li:first-child a { padding-top: 0; }
.svc-tile__links li:last-child a { padding-bottom: 0; }
.svc-tile__links a:hover { color: var(--red); }

/* --------------------------------------------------------------------------
   6. Header + navigation
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: #fff;
  border-bottom: 1px solid var(--line-soft);
}

.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; min-height: 84px;
}

.brand { display: block; flex: none; }
.brand img { width: clamp(124px, 14vw, 168px); }

.nav { display: none; }
@media (min-width: 1060px) {
  .nav {
    display: flex; align-items: center; gap: clamp(18px, 2.2vw, 34px);
    margin-left: auto; /* push nav (and the CTA after it) to the right */
  }
}

.nav a {
  position: relative;
  font-size: var(--step-0);
  font-weight: 700;
  color: var(--ink);
  text-decoration: none;
  padding: 6px 0;
  transition: color .18s ease;
}
.nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px;
  height: 3px; background: var(--red); transform: scaleX(0);
  transform-origin: left; transition: transform .18s ease;
}
.nav a:hover, .nav a:focus-visible { color: var(--red); }
.nav a:hover::after, .nav a:focus-visible::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }
.nav a[aria-current="page"] { color: var(--red); }

.header-cta { display: none; }
@media (min-width: 1060px) { .header-cta { display: inline-flex; margin-left: clamp(16px, 2.5vw, 40px); } }
.header-cta {
  padding: 13px 22px; font-size: var(--step--1); letter-spacing: .08em;
  color: var(--red); border: 2px solid var(--red); border-radius: var(--radius);
  font-weight: 700; text-decoration: none; text-transform: uppercase;
  transition: background-color .18s ease, color .18s ease;
}
.header-cta:hover { background: var(--red); color: #fff; }

.nav-toggle {
  display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
  width: 48px; height: 48px; padding: 0 11px;
  background: none; border: 1px solid var(--line); border-radius: var(--radius);
  cursor: pointer;
}
@media (min-width: 1060px) { .nav-toggle { display: none; } }
.nav-toggle span { display: block; height: 2px; background: var(--ink); transition: transform .2s ease, opacity .2s 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-nav {
  display: none;
  border-top: 1px solid var(--line-soft);
  background: #fff;
  padding: 12px var(--gutter) 32px;
}
.mobile-nav.is-open { display: block; }
@media (min-width: 1060px) { .mobile-nav { display: none !important; } }
.mobile-nav a {
  display: block; padding: 16px 0;
  border-bottom: 1px solid var(--line-soft);
  color: var(--ink); text-decoration: none; font-size: var(--step-1); font-weight: 700;
}
.mobile-nav a[aria-current="page"] { color: var(--red); }
.mobile-nav .btn {
  display: flex; width: 100%; justify-content: center; margin-top: 24px;
  padding: 15px 22px;
  background: transparent; color: var(--red); border: 2px solid var(--red);
  font-size: var(--step--1); letter-spacing: .08em; text-transform: uppercase;
}
.mobile-nav .btn:hover { background: var(--red); color: #fff; }

/* --------------------------------------------------------------------------
   7. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  background: var(--slate-deep);
  color: #fff;
  overflow: hidden;
}
.hero__media {
  position: absolute; inset: 0;
  background:
    linear-gradient(102deg, rgba(46,57,62,.97) 0%, rgba(46,57,62,.88) 34%, rgba(46,57,62,.55) 62%, rgba(46,57,62,.42) 100%),
    repeating-linear-gradient(64deg, #56666D 0 2px, #4C5B62 2px 5px),
    var(--slate);
}
/* Photographic hero. The photograph goes in as a real <img> rather than a CSS
   background: a relative url() inside a custom property resolves against this
   stylesheet's folder, not the page, and a CMS emits an image field as a tag
   anyway. The scrim moves to ::after so it still sits over the picture. */
.hero__media--photo { background: var(--slate-deep); }
.hero__media--photo::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg,
    rgba(46,57,62,.94) 0%, rgba(46,57,62,.90) 38%,
    rgba(46,57,62,.60) 62%, rgba(46,57,62,.34) 100%);
}
/* Overscaled to 152% and anchored left so only the drawing itself is in frame.
   The supplied photograph has "PDV" lettering across its right third, which is
   not YITAC's mark and would land mid-hero at a 1:1 crop. Replace the file with
   a clean, higher-resolution shot and this can drop back to width: 100%. */
.hero__img {
  position: absolute; top: 0; left: 0;
  width: 152%; height: 100%;
  object-fit: cover; object-position: left center;
}

.hero__inner {
  position: relative;
  padding-block: clamp(64px, 10vw, 132px);
  max-width: 780px;
}
.hero h1 { color: #fff; margin-bottom: .35em; }
.hero .lede { color: rgba(255,255,255,.86); max-width: 52ch; }
.hero--compact .hero__inner { padding-block: clamp(52px, 7vw, 96px); }

/* Proof strip that sits under the hero. Deliberately unnumbered — 01-04 is
   the journey's device, and running it twice on one page reads as one long
   eight-step sequence. */
.proofbar { background: #fff; border-top: 4px solid var(--red); }
.proofbar__inner {
  display: grid; gap: clamp(24px, 3vw, 40px);
  grid-template-columns: 1fr;
  padding-block: clamp(32px, 4vw, 48px);
}
@media (min-width: 720px)  { .proofbar__inner { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) {
  /* Centred, so short labels don't leave the dividers hanging in white space. */
  .proofbar__inner { grid-template-columns: minmax(0,1.3fr) repeat(4, minmax(0,1fr)); align-items: center; }
}
.proofbar__claim { font-size: var(--step-1); font-weight: 700; color: var(--ink); line-height: 1.3; max-width: 26ch; }
/* At tablet widths the claim would take cell 1 of a 2-column grid and push
   the four items into a 2x2 with an orphan; span it so they pair up. */
@media (min-width: 720px) and (max-width: 1099px) { .proofbar__claim { grid-column: 1 / -1; } }
/* The divider is a fixed-height pseudo-element, not a border, so every rule
   is identical whether its label sits on one line or wraps to two. A border
   would inherit the item's height and read as ragged between 1100-1180px,
   where "Certified expertise" wraps. */
.proofbar__item { position: relative; padding-left: 22px; }
.proofbar__item::before {
  content: ""; position: absolute; left: 0; top: 50%;
  transform: translateY(-50%);
  width: 1px; height: 2.9em; background: var(--line);
}
@media (max-width: 719px) {
  .proofbar__item { border-top: 1px solid var(--line); padding-left: 0; padding-top: 16px; }
  .proofbar__item::before { content: none; }
}
.proofbar__label { font-weight: 700; color: var(--ink); line-height: 1.3; }

/* --------------------------------------------------------------------------
   8. Journey / numbered cards
   -------------------------------------------------------------------------- */
.journey__item { border-top: 1px solid var(--line); padding-top: 22px; }
.section--slate .journey__item { border-top-color: var(--line-dark); }
.journey__num { display: block; font-size: var(--step--1); font-weight: 700; color: var(--red); margin-bottom: 14px; }
.journey__item h3 { margin-bottom: .45em; }
.journey__item p { font-size: var(--step-0); margin: 0; }

/* The figure is a display graphic: pale grey, scaled to fill its column, with
   the label reading underneath it. Sized in cqw against the stat's own width
   rather than vw, so it fills the column at every breakpoint instead of
   holding at one viewport and drifting at the rest. */
.stat { text-align: left; container-type: inline-size; }
.stat__figure {
  display: block;
  font-size: clamp(3.5rem, 70cqw, 22rem);
  font-weight: 700; line-height: .78; letter-spacing: -.05em;
  color: var(--line);
}
.stat__label { display: block; font-weight: 700; color: var(--ink); font-size: var(--step-0); margin-top: 14px; }

/* Phase list (dark band) */
.phases { margin-top: 8px; }
.phase {
  /* Same tightening as .service-row: while the number and name share a stacked
     row, the number is a marker rather than a column, so the wide gap only eats
     the measure the name needs. Restored with the 3-column grid at 700px. */
  display: grid; gap: 6px 14px;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  padding: 22px 0;
  border-bottom: 1px solid var(--line-dark);
}
@media (min-width: 700px) { .phase { gap: 6px 24px; grid-template-columns: 40px 190px 1fr; } }
.phase__num { font-size: var(--step--1); font-weight: 700; color: rgba(255,255,255,.55); }
.phase__name { font-size: var(--step-2); font-weight: 700; color: #fff; letter-spacing: -.02em; }
.phase__desc { color: var(--on-dark); grid-column: 1 / -1; }
@media (min-width: 700px) { .phase__desc { grid-column: auto; } }

/* --------------------------------------------------------------------------
   9. Service rows
   -------------------------------------------------------------------------- */
.service-row {
  /* Tight column gap while stacked: the number is a 2-digit marker, not a
     column, and 32px of it here pushes names like "Green Mark Certification"
     onto a second line. The desktop gap is restored with the 4-column grid. */
  display: grid; gap: 8px 14px;
  grid-template-columns: auto 1fr;
  align-items: center;
  padding: clamp(24px, 3vw, 34px) 0;
  border-bottom: 1px solid var(--line);
  text-decoration: none;
  transition: background-color .18s ease, padding-inline .18s ease;
}
.service-row:first-of-type { border-top: 1px solid var(--line); }
@media (min-width: 860px) {
  .service-row { gap: 8px 32px; grid-template-columns: 48px minmax(0, 1fr) minmax(0, 1.05fr) auto; }
}
.service-row:hover { background: var(--ivory); }
@media (min-width: 860px) { .service-row:hover { padding-inline: 16px; } }
.service-row__num { font-size: var(--step--1); font-weight: 700; color: var(--red); }
.service-row__name { font-size: var(--step-2); font-weight: 700; color: var(--ink); letter-spacing: -.02em; }
.service-row__desc { color: var(--body); grid-column: 1 / -1; margin: 0; }
/* The Explore link is the row's fourth child. Left to auto-placement on the
   stacked 2-column grid it lands back in column 1, so that column sizes to the
   word "EXPLORE" (~70px) instead of the "01" marker, and the whole name column
   is pushed across. Spanning it, as the description already does, keeps column
   1 at the width of the number. */
.service-row .link-arrow { grid-column: 1 / -1; }
@media (min-width: 860px) {
  .service-row__desc { grid-column: auto; }
  .service-row .link-arrow { grid-column: auto; }
}

/* --------------------------------------------------------------------------
   10. Cards — solutions, cases, articles
   -------------------------------------------------------------------------- */
.card {
  display: flex; flex-direction: column;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
.card:hover { border-color: var(--slate); transform: translateY(-3px); box-shadow: 0 12px 28px rgba(34,40,43,.09); }
.card__body { padding: clamp(22px, 2.4vw, 30px); display: flex; flex-direction: column; flex: 1; }
.card__kicker {
  font-size: .75rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--red); margin-bottom: 12px;
}
.card__title { font-size: var(--step-2); margin-bottom: .4em; }
.card__body p { font-size: var(--step-0); margin-bottom: 22px; }
.card__body .link-arrow { margin-top: auto; }
.card--flat { border-color: transparent; background: var(--stone); }
.card--flat:hover { border-color: var(--slate); }

/* Real product artwork in place of an .img-slot. YITAC's supplied banners are
   square and carry their own lettering and caption bar, so the frame is held
   at 1:1 — any other ratio crops the caption off. */
.card__media {
  aspect-ratio: 1 / 1;
  background: var(--stone);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.card__media img { width: 100%; height: 100%; object-fit: cover; }

/* Lede plus two solution cards at 50 / 25 / 25. Not .split + .grid-2, which
   gave 53.5 / 23 / 23 and left the two cards on their own nested grid. */
.solution-cols { display: grid; gap: clamp(24px, 3vw, 40px); grid-template-columns: 1fr; }
@media (min-width: 720px) {
  .solution-cols { grid-template-columns: repeat(2, 1fr); }
  .solution-cols__lede { grid-column: 1 / -1; }
}
@media (min-width: 1000px) {
  /* Left on stretch so the two cards stay equal height whatever the copy. */
  .solution-cols { grid-template-columns: 2fr 1fr 1fr; }
  .solution-cols__lede { grid-column: auto; }
}

/* Image slots — art-direction placeholders, replaced with real photography */
.img-slot {
  position: relative;
  display: flex; align-items: flex-end;
  min-height: 220px;
  padding: 20px;
  background:
    linear-gradient(135deg, rgba(78,93,100,.14), rgba(78,93,100,.05)),
    repeating-linear-gradient(45deg, #E7E5DF 0 10px, #EFEDE8 10px 20px);
  border-bottom: 1px solid var(--line);
  color: var(--slate);
  font-size: .75rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  font-weight: 700;
}
.img-slot--tall { min-height: clamp(280px, 34vw, 460px); }
.img-slot--wide { min-height: clamp(220px, 26vw, 340px); }
/* Sits at the head of a quarter-width card. Held on a ratio rather than a
   height: the card runs full-bleed on a phone and half-width on a tablet, and a
   fixed height would flatten the frame to a letterbox at those widths while the
   desktop kept its 3:2. min-height: 0 clears the 220px the base rule sets,
   which would otherwise win at narrow widths and reintroduce the distortion. */
.img-slot--card { min-height: 0; aspect-ratio: 3 / 2; padding: 14px; }
.img-slot--card span { font-size: .6875rem; padding: 6px 10px; }
/* Every slot heading a card is held on the same 3:2, for the reason above: the
   card changes width at each breakpoint and a min-height frame would go
   portrait in a narrow column and letterbox in a wide one. */
.card > .img-slot { min-height: 0; aspect-ratio: 3 / 2; }
.img-slot span {
  background: rgba(255,255,255,.9);
  padding: 7px 12px;
  border-left: 3px solid var(--red);
  line-height: 1.4;
  max-width: 32ch;
}

/* Featured case band */
.feature-case {
  display: grid; grid-template-columns: 1fr;
  background: var(--slate);
  border-radius: var(--radius);
  overflow: hidden;
}
@media (min-width: 900px) { .feature-case { grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr); } }
.feature-case__media { min-height: 260px; }
.feature-case__body {
  padding: clamp(28px, 4vw, 56px);
  display: flex; flex-direction: column; justify-content: center;
}
.feature-case__body h3 { color: #fff; font-size: var(--step-3); }
.feature-case__body p { color: var(--on-dark); }
.feature-case__body .link-arrow { color: var(--red-on-dark); margin-top: 24px; }

/* Chain / pathway line */
.chain {
  display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center;
  font-size: var(--step--1); color: var(--muted); font-weight: 700;
  letter-spacing: .04em;
}
/* Drawn rather than typeset. Arial's arrow glyph is a hairline, which is the
   lightest mark in the pathway line and the first thing to disappear on a
   slate ground; a 2px rule plus a rotated corner gives the mark enough body
   to survive while keeping the direction a bullet would throw away.
   The span is empty by design — the shape is the CSS, not a character. */
.chain .arw {
  display: inline-block; position: relative;
  width: 17px; height: 2px;
  background: currentColor;
  color: var(--red);
  vertical-align: middle;
}
.chain .arw::after {
  content: ""; position: absolute; right: 0; top: 50%;
  width: 6px; height: 6px;
  border-top: 2px solid currentColor;
  border-right: 2px solid currentColor;
  transform: translateY(-50%) rotate(45deg);
}
/* Full-strength --red is 1.37:1 here; the dark-ground accent lifts the arrows
   to 2.14:1 and keeps the pathway line one colour. Still under the 3:1
   graphical threshold — rgba(255,255,255,.65) would give 3.97:1 if these ever
   need to be legible on their own rather than as connective marks. */
.section--slate .chain .arw,
.feature-case__body .chain .arw { color: var(--red-on-dark); }

/* --------------------------------------------------------------------------
   11. Fact / spec blocks
   -------------------------------------------------------------------------- */
.facts { display: grid; gap: clamp(24px, 3vw, 40px); grid-template-columns: 1fr; }
@media (min-width: 620px)  { .facts { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .facts { grid-template-columns: repeat(4, 1fr); } }
.fact { border-left: 4px solid var(--red); padding-left: 18px; }
.fact__value { font-size: var(--step-3); font-weight: 700; color: var(--ink); line-height: 1.05; letter-spacing: -.03em; }
.fact__label { display: block; font-size: var(--step--1); color: var(--body); margin-top: 6px; }

.panel {
  border-top: 4px solid var(--red);
  padding-top: 22px;
}

/* Image with a claim panel pulled up over its lower edge. The image carries
   more height than it did stacked, so the overlap eats borrowed space rather
   than cropping the photograph. */
.overlap { position: relative; }
/* Caption moves to the top of the frame — the panel now occupies the bottom. */
.overlap .img-slot { min-height: clamp(320px, 40vw, 540px); align-items: flex-start; }
.overlap__panel {
  position: relative; z-index: 2;
  background: #fff;
  margin-top: clamp(-104px, -7vw, -48px);
  margin-left: clamp(20px, 4vw, 56px);
  padding: clamp(24px, 3vw, 34px);
}
/* From 1100px the image is tall enough to hold the panel inside it, so the
   panel sits on the photograph rather than hanging off its lower edge. Below
   that the image would be almost entirely covered, so the overhang is kept.
   The extra .panel keeps this desktop rule more specific than the base panel
   styles while preserving the mobile overhang treatment below. */
@media (min-width: 1100px) {
  .overlap .panel.overlap__panel {
    position: absolute;
    left: clamp(20px, 4vw, 56px); right: 0;
    bottom: clamp(20px, 2.5vw, 36px);
    margin: 0;
  }
}
/* Below 700px the column is too narrow to carry an overhang. The left indent
   sits against a flush right edge, which reads as a misalignment rather than a
   deliberate offset, and the pull-up covers the lower third of an image that is
   already short. The panel drops to a plain block under the frame; its red rule
   becomes the join, so the pairing survives without the overlap. */
@media (max-width: 699px) {
  .overlap .img-slot { min-height: clamp(230px, 48vw, 300px); border-bottom: 0; }
  .overlap .panel.overlap__panel {
    margin-top: 0; margin-left: 0;
    padding: clamp(22px, 6vw, 28px);
  }
}
/* Stated explicitly because a white panel can sit inside .section--slate,
   which otherwise paints every heading and paragraph white. */
.panel h4 { margin-bottom: .5em; color: var(--ink); }
.panel p { font-size: var(--step-0); color: var(--body); }

.band {
  display: flex; flex-wrap: wrap; gap: 12px 32px;
  align-items: center; justify-content: space-between;
  background: var(--slate); color: #fff;
  padding: clamp(20px, 2.6vw, 30px) clamp(22px, 3vw, 40px);
  border-radius: var(--radius);
}
.band strong { color: #fff; }
.band .eyebrow { margin: 0; }
.band__meta { color: var(--on-dark); font-size: var(--step--1); }

.callout {
  display: grid; gap: 16px 32px;
  align-items: center;
  background: var(--stone);
  padding: clamp(22px, 3vw, 34px);
  border-radius: var(--radius);
}
/* From tablet up the CTA row runs 50:50 — the ask on the left half, the button
   held to the right edge of its own half. Grid rather than flex + space-between:
   flex dropped the button onto its own line as soon as the two stopped fitting
   side by side, which is exactly the tablet width. Equal columns keep the row
   intact and the button aligned the same way on every page. Scoped to callouts
   that carry a button — the note-only variant stays a full-width block. */
@media (min-width: 620px) {
  .callout:has(.btn) { grid-template-columns: 1fr 1fr; }
  .callout:has(.btn) .btn { justify-self: end; }
}
.callout p { font-weight: 700; color: var(--ink); margin: 0; }
/* Caps to match .header-cta — the two are the same ask in different places,
   and the closing band reads as the page's terminal action. Tracking added
   because caps at this weight set too tight without it. */
.callout .btn { text-transform: uppercase; letter-spacing: .06em; }

/* Data table for case study evidence */
.table-wrap { overflow-x: auto; margin: 28px 0; border: 1px solid var(--line); border-radius: var(--radius); }
table { border-collapse: collapse; width: 100%; min-width: 460px; font-size: var(--step-0); }
caption { text-align: left; padding: 16px 18px; font-weight: 700; color: var(--ink); border-bottom: 1px solid var(--line); }
th, td { padding: 14px 18px; text-align: left; border-bottom: 1px solid var(--line-soft); }
thead th { background: var(--slate); color: #fff; font-size: var(--step--1); letter-spacing: .06em; text-transform: uppercase; }
tbody tr:last-child td { border-bottom: 0; }
tbody th { font-weight: 700; color: var(--ink); }

/* Partner logos */
/* --partner-h keeps every box in a row the same height so the rules above and
   below them, and the caption baselines underneath, stay on one line. 108px
   clears the certification marks; the partner grid raises it for its taller
   logos. Without it the boxes size to their own logo and the rules go ragged. */
.partner {
  display: flex; align-items: center; justify-content: center;
  min-height: var(--partner-h, 108px); padding: 20px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  font-size: var(--step-2); font-weight: 700; color: var(--muted);
  letter-spacing: -.02em; text-align: center;
}

/* Certification marks come off the asset bucket at mixed sizes and aspect
   ratios. Capping height rather than width sets them on a common optical
   baseline; sizing by width would make the wide BCA lockup dwarf the rest.
   The partner logos vary far more — different baked-in whitespace, aspect
   ratios from 1.9:1 to 3.8:1 — so each sets its own --logo-h to match on
   visible area instead. 60px stays the default for the certification row. */
.partner img { height: auto; width: auto; max-width: 100%; max-height: var(--logo-h, 60px); }
/* The SGBC mark is the only portrait one — matched on area, not height, so it
   does not read as the small logo in the row. */
.partner--tall img { max-height: 88px; }

/* Benefit list. The live product pages carry these as plain bullets; a bullet
   glyph at Arial's weight disappears next to --step-0 body text, so the marker
   is drawn as a red rule instead and the rows are separated rather than
   indented. Two columns from 760px — eight benefits in one column runs past
   the fold on the solution pages. */
.benefit-list { list-style: none; margin: 0; padding: 0; }
.benefit-list li {
  position: relative;
  padding: 0 0 18px 30px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--line-soft);
  font-size: var(--step-0);
  break-inside: avoid;
}
.benefit-list li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: 16px; height: 3px; background: var(--red);
}
.benefit-list li:last-child { border-bottom: 0; margin-bottom: 0; padding-bottom: 0; }
.benefit-list strong { color: var(--ink); }
@media (min-width: 760px) {
  .benefit-list--2col { column-count: 2; column-gap: clamp(32px, 4vw, 64px); }
  /* The last item in the first column would otherwise lose its rule mid-page,
     so every item keeps its border and only the true last one is stripped. */
  .benefit-list--2col li:last-child { border-bottom: 1px solid var(--line-soft); padding-bottom: 18px; }
}

/* Specification rows. The live site sets these as dot leaders inside a single
   text run, which wraps unpredictably and cannot be read out in order by a
   screen reader. A <dl> keeps the term/value pairing explicit and lets the
   value sit hard right on one line. */
.spec-list { margin: 0; }
.spec-list div {
  display: flex; flex-wrap: wrap; gap: 4px 24px;
  justify-content: space-between; align-items: baseline;
  padding: 14px 0;
  border-bottom: 1px solid var(--line-soft);
}
.spec-list div:first-child { padding-top: 0; }
.spec-list div:last-child { border-bottom: 0; }
.spec-list dt { color: var(--body); font-size: var(--step-0); max-width: 44ch; }
.spec-list dd {
  margin: 0; font-weight: 700; color: var(--ink);
  font-size: var(--step-0); text-align: right;
}

/* Document downloads. Filenames come off the Drupal file system as raw
   snake_case; they are kept verbatim as the href target but given a readable
   label, with the extension and the raw name shown underneath so a specifier
   can still match it against what they were sent. */
.doc-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.doc-list a {
  display: flex; align-items: baseline; gap: 16px;
  padding: 18px 20px;
  background: #fff;
  border: 1px solid var(--line);
  border-left: 4px solid var(--red);
  border-radius: var(--radius);
  color: var(--ink); text-decoration: none; font-weight: 700;
  transition: border-color .18s ease, transform .18s ease;
}
.doc-list a:hover { border-color: var(--slate); border-left-color: var(--red); transform: translateY(-2px); }
.doc-list .doc-list__ext {
  flex: 0 0 auto;
  font-size: .625rem; letter-spacing: .08em; text-transform: uppercase;
  background: var(--stone); color: var(--slate);
  padding: 4px 8px; border-radius: var(--radius);
}
.doc-list .doc-list__file {
  display: block; margin-top: 4px;
  font-weight: 400; font-size: var(--step--1); color: var(--muted);
  word-break: break-all;
}

/* In-page section jumps for the solution pages. The live product pages put
   technical characteristics, dimensions, application and downloads behind
   JavaScript tabs, which hides three quarters of the specification from search
   engines and from anyone printing the page. Here every section is on the page
   and this is a shortcut to it, not a switch that reveals it. */
.jump-nav { display: flex; flex-wrap: wrap; gap: 10px; margin: 0; padding: 0; list-style: none; }
.jump-nav a {
  display: block; padding: 10px 18px;
  background: #fff; border: 1px solid var(--line); border-radius: 40px;
  color: var(--slate); text-decoration: none;
  font-size: var(--step--1); font-weight: 700;
}
.jump-nav a:hover { border-color: var(--slate); color: var(--ink); }
.jump-nav--stack { flex-direction: column; align-items: stretch; }

/* --------------------------------------------------------------------------
   12. Article prose — Knowledge Centre body copy
   The one place on the site where headings, lists, tables and quotes come out
   of a rich-text field instead of being composed from components. Everything
   is scoped to .prose, so whatever an editor pastes can never restyle the
   rest of the page. Measure is held at 68ch: the heading scale steps down one
   level from the section headings around it, because inside an article an h2
   is a subhead, not a section title.
   -------------------------------------------------------------------------- */
/* Contents rail then reading column. Not .split — that puts its wider column
   first, which is backwards for an article. The rail sticks below the sticky
   header; the prose column is what scrolls past it. */
.article-layout {
  display: grid; gap: clamp(32px, 5vw, 72px);
  /* minmax(0,1fr), not 1fr: a bare 1fr track floors at the content's
     min-content width, and .table-wrap's 460px table would push the whole
     page into horizontal scroll on a phone. */
  grid-template-columns: minmax(0, 1fr); align-items: start;
}
@media (min-width: 940px) {
  .article-layout { grid-template-columns: minmax(0, 230px) minmax(0, 1fr); }
  .article-layout__rail { position: sticky; top: 108px; }
}
/* The sticky header would otherwise cover whatever a contents link jumps to. */
.prose [id] { scroll-margin-top: 108px; }

.prose { max-width: 68ch; }
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }

.prose h2 { font-size: var(--step-3); margin: 1.6em 0 .45em; }
.prose h3 { font-size: var(--step-2); margin: 1.5em 0 .45em; }
.prose h4 { font-size: var(--step-1); margin: 1.4em 0 .4em; }
.prose p  { max-width: none; }
.prose a  { color: var(--red); text-underline-offset: 3px; }

/* Same red rule marker as .benefit-list, at body scale. A disc bullet at
   Arial's weight all but vanishes next to --step-0 text. */
.prose ul { list-style: none; margin: 0 0 1.3em; padding: 0; }
.prose ul li { position: relative; padding-left: 28px; margin-bottom: .65em; }
.prose ul li::before {
  content: ""; position: absolute; left: 0; top: .66em;
  width: 14px; height: 3px; background: var(--red);
}
.prose ol { margin: 0 0 1.3em; padding-left: 22px; }
.prose ol li { margin-bottom: .65em; padding-left: 6px; }
.prose li > ul, .prose li > ol { margin: .65em 0 0; }
.prose li::marker { color: var(--red); font-weight: 700; }

/* Pull quote. Not a card — a rule and a size change, so it reads as a lift
   out of the argument rather than an interruption to it. */
.prose blockquote {
  margin: clamp(30px, 3.6vw, 44px) 0;
  padding-left: clamp(22px, 2.4vw, 30px);
  border-left: 4px solid var(--red);
}
.prose blockquote p {
  font-size: var(--step-2); font-weight: 700; line-height: 1.3;
  letter-spacing: -.02em; color: var(--ink);
}
.prose blockquote cite {
  display: block; margin-top: 16px;
  font-size: var(--step--1); font-style: normal; font-weight: 700;
  letter-spacing: .04em; color: var(--muted);
}

/* Tables run wider than the reading measure. .table-wrap already scrolls on
   small screens; this lets it use the column it is given on large ones. */
.prose .table-wrap { max-width: none; margin-block: clamp(30px, 3.6vw, 44px); }
.prose table caption {
  caption-side: bottom; padding: 12px 18px;
  font-size: var(--step--1); color: var(--muted); text-align: left;
}

/* Byline strip under the article h1. Sits on the dark hero. */
.article-meta {
  display: flex; flex-wrap: wrap; gap: 8px 20px;
  margin-top: 26px; padding: 0; list-style: none;
  font-size: var(--step--1); color: rgba(255,255,255,.72);
}
.article-meta li + li { position: relative; padding-left: 21px; }
.article-meta li + li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: 9px; height: 1px; background: rgba(255,255,255,.4);
}

/* --------------------------------------------------------------------------
   13. Forms
   -------------------------------------------------------------------------- */
/* The form is the query container its field grid measures against. */
form { container-type: inline-size; }

/* Paired fields go two-up on the form's own width, not the viewport's: the
   form sits in half a .split--even from 760 up, so a viewport query would put
   two fields in a 315px tablet column and leave ~145px to type an email into.
   340px is the column the split gives at 900 — the width the two-up layout was
   drawn at — so desktop is unchanged and only the tablet column drops to one. */
.form-grid { display: grid; gap: 26px; grid-template-columns: 1fr; }
@container (min-width: 340px) { .form-grid { grid-template-columns: 1fr 1fr; } }
.field--full { grid-column: 1 / -1; }

label { display: block; font-size: var(--step--1); font-weight: 700; color: var(--ink); margin-bottom: 8px; }
.req { color: var(--red); }

input[type="text"], input[type="email"], input[type="tel"], textarea, select {
  width: 100%;
  padding: 13px 2px;
  font: inherit;
  font-size: var(--step-0);
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  transition: border-color .18s ease;
}
input:focus, textarea:focus, select:focus { border-bottom-color: var(--red); outline-offset: 6px; }
textarea { min-height: 130px; resize: vertical; }
::placeholder { color: var(--muted); opacity: 1; }

/* Enquiry-type chips route the lead from the first click */
.chips { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 8px; }
.chip { position: relative; }
.chip input {
  position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer;
}
.chip span {
  display: block; padding: 13px 20px;
  border: 1px solid var(--line); border-radius: var(--radius);
  font-size: var(--step--1); font-weight: 700; color: var(--body);
  transition: border-color .18s ease, color .18s ease, background-color .18s ease;
}
.chip input:hover + span { border-color: var(--slate); }
.chip input:checked + span { border-color: var(--red); color: var(--red); background: var(--red-tint); }
.chip input:focus-visible + span { outline: 3px solid var(--red); outline-offset: 3px; }

.consent { display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: start; }
.consent input { margin-top: 5px; width: 18px; height: 18px; accent-color: var(--red); }
.consent label { font-weight: 400; font-size: var(--step--1); color: var(--body); margin: 0; line-height: 1.55; }

.contact-list { margin: 0; padding: 0; }
.contact-list div {
  display: grid; grid-template-columns: 110px 1fr; gap: 16px;
  padding: 16px 0; border-bottom: 1px solid var(--line-dark);
}
.contact-list dt { font-weight: 700; color: #fff; font-size: var(--step--1); }
.contact-list dd { margin: 0; color: var(--on-dark); }
.contact-list a { color: #fff; }

/* --------------------------------------------------------------------------
   14. Footer
   -------------------------------------------------------------------------- */
.site-footer { background: var(--slate-deep); color: var(--on-dark); padding-block: clamp(48px, 6vw, 80px) 0; }
.site-footer h4 { color: #fff; font-size: var(--step--1); letter-spacing: .12em; text-transform: uppercase; margin-bottom: 20px; }
.footer-grid { display: grid; gap: clamp(32px, 4vw, 56px); grid-template-columns: 1fr; }
@media (min-width: 700px)  { .footer-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .footer-grid { grid-template-columns: 1.4fr repeat(3, 1fr); } }
.footer-nav { list-style: none; margin: 0; padding: 0; }
.footer-nav li { margin-bottom: 12px; }
.footer-nav a { color: var(--on-dark); text-decoration: none; }
.footer-nav a:hover { color: #fff; text-decoration: underline; }
/* T / F / E channel markers. Fixed width so the values align down a common
   edge, and aria-hidden in the markup with the full word beside them in a
   .visually-hidden span — a screen reader should say "Telephone", not "T".
   --muted would be 3.09:1 on --slate-deep; this reads as secondary and
   still clears 4.5:1. */
.footer-nav__label {
  display: inline-block; min-width: 1.5em;
  font-size: var(--step--1); font-weight: 700;
  color: rgba(255,255,255,.6);
}
.footer-nav__val { color: var(--on-dark); }
/* Same outline-CTA pattern as .header-cta — same metrics, same tracking —
   but drawn in white, since red on --slate-deep is 1.5:1. Kept as its own
   class because .header-cta is display:none below 1060px. */
.footer-cta {
  display: inline-flex; align-items: center;
  margin-top: 10px;
  padding: 13px 22px;
  font-size: var(--step--1); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; text-decoration: none;
  color: #fff;
  border: 2px solid rgba(255,255,255,.55);
  border-radius: var(--radius);
  transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.footer-cta:hover { background: #fff; color: var(--ink); border-color: #fff; }
.site-footer .brand img { filter: brightness(0) invert(1); opacity: .95; width: 150px; }
.certs { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }
.certs span {
  border: 1px solid var(--line-dark); padding: 7px 12px;
  font-size: .7rem; letter-spacing: .08em; text-transform: uppercase; font-weight: 700;
  color: var(--on-dark);
}
.footer-base {
  margin-top: clamp(40px, 5vw, 64px);
  border-top: 1px solid var(--line-dark);
  padding-block: 26px;
  display: flex; flex-wrap: wrap; gap: 12px 28px; justify-content: space-between;
  font-size: var(--step--1);
}

/* --------------------------------------------------------------------------
   15. Print
   -------------------------------------------------------------------------- */
@media print {
  .site-header, .nav-toggle, .mobile-nav { display: none !important; }
  .hero { background: none; color: #000; }
  .hero h1, .hero .lede { color: #000; }
  body { color: #000; }
}
