/* ============================================================
   BlackTrace Operations — styles.v8.css
   Implements Brand System v1.1 (August 2026).

   Every value below is traceable to the Brand Standards Guide:
     §09 Colour        — palette tokens, 90/8/2 discipline
     §10 Typography    — Bebas Neue / Outfit / DM Mono
     §11 Accessibility — verified contrast, focus, reduced motion
     §17 Components    — square corners, rules, buttons, icons
     §19 Do's & don'ts — no gradients, no shadows, no effects

   Self-hosted fonts. No external requests.

   VERSIONED FILENAME. This file is served with a one-year immutable
   cache header, so it must be renamed (styles.v8.css, and so on) on
   any release that changes it. The same applies to site.v4.js and
   nav.v4.js.
   ============================================================ */

/* ===== §10 Typography — self-hosted faces ===================== */

@font-face {
  font-family: 'Bebas Neue';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/bebas-neue-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('assets/fonts/outfit-latin-300-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/outfit-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('assets/fonts/outfit-latin-500-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('assets/fonts/outfit-latin-600-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('assets/fonts/outfit-latin-700-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/dm-mono-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('assets/fonts/dm-mono-latin-500-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* ===== §09 Colour — palette tokens ============================
   Charcoal is the UI/text dark. Ink is reserved for logo artwork
   only and is therefore not used as a surface anywhere below.
   ============================================================== */

:root {
  /* Core palette — Brand Standards Guide §09 */
  --cream:      #F5F0E8;   /* primary light ground; logo on dark   */
  --warm:       #F0EBE2;   /* alternate shading, panel fills        */
  --white:      #FFFFFF;   /* primary surface                       */
  --charcoal:   #1C1916;   /* body text, table headers, dark bands  */
  --ink:        #141210;   /* logo artwork only — do not use as UI  */
  --red:        #8B1A1A;   /* accent: rules, numbers, the dot       */
  --stone:      #6E635A;   /* secondary text                        */
  --muted:      #8A8178;   /* tertiary text on dark grounds only    */
  --hairline:   #D8D2C8;   /* rules, borders, dividers              */

  /* §11 Accessibility — red text on dark grounds only (4.95:1)   */
  --signal-red: #D76565;

  /* Rules on dark grounds. Not a new colour: Cream at 12%, which is the
     dark-ground equivalent of Hairline. v3.0 used a flat hex here that was
     not in the §09 palette; this composites to within one step of it while
     being expressible entirely in approved terms.
     Opacity is used for rules and borders only, never for text. */
  --hairline-dark: rgba(245, 240, 232, 0.12);

  /* Measure and rhythm */
  --max:        1160px;
  --header-h:   100px;
  --gutter:     48px;

  /* §17 Components — square corners throughout */
  --radius:     0;

  /* §10 Typography — families with robust fallbacks */
  /* Every fallback listed is a condensed face, so if the self-hosted Bebas
     Neue ever fails to load a display line still reads as a display line
     rather than collapsing into the body font's proportions. */
  --font-display: 'Bebas Neue', 'Haettenschweiler', 'Arial Narrow',
                  'Helvetica Neue Condensed', 'Liberation Sans Narrow',
                  'Nimbus Sans Narrow', Impact, sans-serif;
  --font-body:    'Outfit', Arial, Helvetica, system-ui, -apple-system, sans-serif;
  --font-mono:    'DM Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}

/* ===== Reset & base ========================================== */

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  /* The header is position:fixed, so the browser's own idea of where a fragment
     target begins is the top of the viewport — underneath the bar. This offsets
     every in-page jump by the real header height at the current breakpoint plus
     24px of deliberate breathing room, so a heading lands clear of the header
     rather than behind it.

     Set on the scrolling element, which covers link clicks, direct loads with a
     #fragment and scrollIntoView alike, at every breakpoint, with no script and
     no pixel arithmetic to drift out of date as the header height changes. */
  scroll-padding-top: calc(var(--header-h) + 24px);
}

body {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 16px;
  color: var(--charcoal);
  background-color: var(--cream);
  line-height: 1.65;
  padding-top: var(--header-h);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

main { flex: 1; }

a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }

.container {
  width: min(var(--max), calc(100% - (var(--gutter) * 2)));
  margin-inline: auto;
}

/* §11 Accessibility — content available to assistive technology but not
   painted. Used for the menu control's label on very narrow screens, so the
   control keeps a real accessible name without resorting to aria-label. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* §11 Accessibility — skip link */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--cream);
  color: var(--charcoal);
  padding: 12px 20px;
  font-family: var(--font-mono);
  font-size: 13px;
  border: 2px solid var(--red);
}
.skip-link:focus {
  left: 12px;
  top: 12px;
}

/* ===== §10 Typography ======================================== */

h1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(42px, 5.6vw, 74px);
  line-height: 1.02;
  letter-spacing: 0.012em;
  text-wrap: balance;
}

h2 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: clamp(22px, 2.6vw, 34px);
  letter-spacing: -0.018em;
  line-height: 1.22;
  text-wrap: balance;
}

h3 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: clamp(17px, 1.6vw, 20px);
  letter-spacing: -0.008em;
  line-height: 1.32;
}

h4 {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red);
  line-height: 1.4;
}

p { line-height: 1.7; }

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

em { font-style: italic; }

/* §17 — eyebrow label with a short red rule. Red as punctuation. */
.eyebrow {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--stone);
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
}
.eyebrow::before {
  content: "";
  display: block;
  width: 32px;
  height: 2px;
  background: var(--red);
  flex-shrink: 0;
}
.eyebrow.centered { justify-content: center; }
.eyebrow.centered::before { display: none; }

.lead {
  font-size: clamp(17px, 1.9vw, 21px);
  font-weight: 300;
  line-height: 1.58;
  color: var(--charcoal);
  max-width: 62ch;
}

.muted { color: var(--stone); }

/* §17 — figure captions: DM Mono, stone, below the figure */
.figure-caption {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--stone);
  margin-top: 24px;
}
.section-dark .figure-caption { color: var(--muted); }

/* Body lists — hairline separated, red em-dash marker */
ul {
  list-style: none;
  padding: 0;
}
ul li {
  padding: 9px 0 9px 22px;
  position: relative;
  border-bottom: 1px solid var(--hairline);
  color: var(--charcoal);
  font-size: 15px;
  line-height: 1.6;
}
ul li:first-child { border-top: 1px solid var(--hairline); }
ul li::before {
  content: "—";
  position: absolute;
  left: 0;
  color: var(--red);
  font-family: var(--font-mono);
  font-size: 12px;
}

ul.plain li { border: 0; padding-left: 0; }
ul.plain li::before { content: none; }

/* ===== Header ================================================ */

.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  height: var(--header-h);
  background: var(--charcoal);
  border-bottom: 1px solid var(--hairline-dark);
  border-top: 3px solid var(--red);
}

.header-inner {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
}

/* §07 Clear space & minimum size.

   ===== APPROVED WEBSITE-HEADER EXCEPTION (v3.3.1) =====================
   The client has reviewed the alternatives and approved a 100px desktop bar
   carrying the full 216.6 x 63 lockup. The lockup is NOT reduced, distorted,
   cropped or redrawn. The exception is to the clear-space zone only, it is
   vertical only, and it applies to the website header only. Nothing else on
   the site, and no other medium, relies on it or compensates for it.

   X = the height of the Breach Mark frame = 0.5875 of the rendered lockup
   height. The artwork carries built-in padding of 20.6% of its height above the
   painted ink and 17.35% below, and that padding counts toward the zone.

   Measured, with the deviation stated rather than hidden:

     desktop  216.6 x 63, header 100px   X = 37.01   top 29.7  bottom 28.4
     tablet   199.4 x 58, header  95px   X = 34.08   top 28.6  bottom 27.6
     mobile   165.0 x 48, header  96px   X = 28.20   top 31.8  bottom 32.3

   Mobile remains fully compliant on all four sides and is unchanged. Desktop
   and tablet sit inside the zone above and below.

   HORIZONTAL clear space is NOT part of the exception and is still satisfied
   in full at every width. That is why the lockup still steps down to 199.4px
   at 1180px, where --gutter narrows to 32px: at 63px the left arm would be
   35.5px against 37.0px, and nobody approved that one.

   browser/test_header.py pins these numbers. The vertical arms are checked
   against the approved figures rather than waived, so an unintended change to
   the header still fails the suite. */
.brand {
  display: flex;
  align-items: center;
  /* §08 — the lockup must never be stretched or condensed. Without this the
     brand is a shrinkable flex item, and at 320px the header could not fit
     165px of logo plus a 93px menu control plus a 32px gap, so the browser
     compressed the image to 139 x 48: an aspect ratio of 2.90 against the
     artwork's 3.4375, and below the 160px minimum width at §07.
     The narrow-breakpoint rules further down reclaim the space instead. */
  flex-shrink: 0;
  /* Optical centring. The painted ink is not centred within the artwork — its
     midpoint sits 1.3 artboard units below the box's own midpoint — so a lockup
     centred geometrically in the bar reads as sitting slightly low. Two pixels
     of bottom margin on a centred flex item lifts it by one, which centres the
     ink by eye rather than the box by arithmetic. */
  margin-bottom: 2px;
}
.brand-logo {
  /* v3.2 — the lockup was enlarged for presence. Every size below is paired
     with a header height that keeps §07 clear space satisfied; the geometry is
     verified at six widths by browser/test_header.py.

       desktop  63px high -> 216.6px wide, header 100px
       tablet   58px high -> 199.4px wide, header  95px
       mobile   48px high -> 165.0px wide, header  96px

     All three are above the §07 minimum reproduction width of 160px, so the
     full horizontal lockup is retained at every breakpoint. */
  height: 63px;
  width: auto;
  /* Overrides the global `img { max-width: 100% }`, which was the mechanism
     by which the lockup was being compressed. */
  max-width: none;
  flex-shrink: 0;
}

/* ===== Navigation ============================================
   Native <details> disclosure. The element ships with `open` in the
   markup, so the links are visible in every engine without CSS or
   script. Desktop hides the <summary> and lays the links out as a
   row; mobile turns the <summary> into the menu control.

   Nothing here depends on overriding the browser's hiding of closed
   <details> content, because the element is never closed at desktop.
   ============================================================== */

.nav-wrap {
  display: flex;
  align-items: center;
}

.nav {
  display: flex;
  align-items: center;
  gap: 4px;
}

.nav a {
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--muted);              /* 4.58:1 on charcoal */
  padding: 10px 13px;
  border-bottom: 2px solid transparent;
  transition: color .18s ease, border-color .18s ease;
}
.nav a:hover {
  color: var(--cream);
  border-bottom-color: var(--hairline-dark);
}
.nav a.active {
  color: var(--cream);
  border-bottom-color: var(--red);
}

/* The menu control. Hidden at desktop, where the links are laid out
   directly and the disclosure is permanently open. */
.nav-toggle {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  border: 1px solid var(--hairline-dark);
  background: transparent;
  cursor: pointer;
  list-style: none;
  color: var(--muted);
  flex-shrink: 0;
  /* WCAG 2.2 SC 2.5.8 requires 24px; 44px is the comfortable touch target.
     Stated explicitly because the only in-flow child is the 2px bars span —
     once the "Menu" wordmark is visually hidden at the narrowest widths, the
     control would otherwise collapse to 22px tall. */
  min-height: 44px;
  min-width: 44px;
  box-sizing: border-box;
  justify-content: center;
  transition: color .18s ease, border-color .18s ease;
}
.nav-toggle::-webkit-details-marker { display: none; }
.nav-toggle::marker { content: ""; }
.nav-toggle:hover { color: var(--cream); border-color: var(--muted); }

.nav-toggle-label {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* Three bars, drawn from a single element so the markup stays lean. */
.nav-toggle-bars {
  position: relative;
  display: block;
  width: 18px;
  height: 2px;
  background: currentColor;
  flex-shrink: 0;
}
.nav-toggle-bars::before,
.nav-toggle-bars::after {
  content: "";
  position: absolute;
  left: 0;
  width: 18px;
  height: 2px;
  background: currentColor;
  transition: transform .18s ease;
}
.nav-toggle-bars::before { top: -6px; }
.nav-toggle-bars::after  { top: 6px; }

/* ===== §17 Buttons ===========================================
   Square corners. No gradients, no shadows, no uppercase labels,
   no icons inside buttons.
   ============================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 14px 28px;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.005em;
  line-height: 1.2;
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  text-decoration: none;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}

/* Primary — blood red fill, cream text. One per view. */
.btn-primary {
  background: var(--red);
  color: var(--cream);              /* 8.19:1 */
  border-color: var(--red);
}
.btn-primary:hover {
  background: var(--charcoal);
  border-color: var(--charcoal);
  color: var(--cream);
}

/* Outline — charcoal border and text, for light grounds */
.btn-outline {
  background: transparent;
  color: var(--charcoal);
  border-color: var(--charcoal);
}
.btn-outline:hover {
  background: var(--charcoal);
  color: var(--cream);
}

/* Outline cream — for dark grounds */
.btn-outline-cream {
  background: transparent;
  color: var(--cream);
  border-color: var(--muted);
}
.btn-outline-cream:hover {
  background: var(--cream);
  border-color: var(--cream);
  color: var(--charcoal);
}

/* Solid — used where a filled action is needed on a dark ground */
.btn-dark {
  background: var(--cream);
  color: var(--charcoal);
  border-color: var(--cream);
}
.btn-dark:hover {
  background: transparent;
  color: var(--cream);
  border-color: var(--cream);
}

.btn-row {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 32px;
}

/* ===== Hero ================================================== */

.hero {
  background: var(--charcoal);
  color: var(--cream);
  padding: 96px 0 88px;
}

.hero-inner {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: 72px;
  align-items: start;
}

.hero-kicker {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);              /* 4.58:1 on charcoal */
  margin-bottom: 26px;
  display: flex;
  align-items: center;
  gap: 14px;
}
.hero-kicker::before {
  content: "";
  display: block;
  width: 32px;
  height: 2px;
  background: var(--red);           /* non-text: contrast N/A */
  flex-shrink: 0;
}

.hero h1 {
  color: var(--cream);
  margin-bottom: 8px;
  /* §10 — the display face. Bebas Neue is a caps-only design, so the glyphs
     paint as capitals whatever the source case; setting the transform
     explicitly means the treatment survives intact if the webfont ever fails
     to load and a fallback face with real lowercase is substituted. */
  text-transform: uppercase;
  letter-spacing: 0.018em;
  line-height: 0.98;
  /* Sized so that each sentence sets on a single line at desktop widths. The
     longer of the two, STRENGTHEN THE DEFENCE., is what governs: the hero copy
     column is 615px at every width above 1180px, and 68px is the largest size
     at which that sentence still sets on one line inside it. */
  font-size: clamp(40px, 4.9vw, 68px);
}

/* §17 — a 2px crimson rule at 44px, left aligned */
.hero-rule {
  width: 44px;
  height: 2px;
  background: var(--red);
  margin: 28px 0;
}

.hero .lead {
  color: var(--cream);
  font-weight: 300;
  font-size: 18px;
  max-width: 54ch;
}

.hero-stats {
  border-left: 1px solid var(--hairline-dark);
  padding-left: 44px;
  display: flex;
  flex-direction: column;
}

.hero-stat {
  padding: 22px 0;
  border-bottom: 1px solid var(--hairline-dark);
}
.hero-stat:first-child { padding-top: 0; }
.hero-stat:last-child { border-bottom: none; padding-bottom: 0; }

.stat-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 8px;
}

.stat-value {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 32px;
  color: var(--cream);
  line-height: 1.05;
  letter-spacing: 0.015em;
  margin-bottom: 6px;
}

.stat-desc {
  font-size: 13.5px;
  color: var(--muted);              /* 4.58:1 */
  line-height: 1.5;
}

/* ===== Section system ======================================== */

.section { padding: 104px 0; }
.section-tight { padding: 72px 0; }

.section-cream { background: var(--cream); }
.section-warm  { background: var(--warm); }
.section-white {
  background: var(--white);
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}
.section-dark  { background: var(--charcoal); color: var(--cream); }
.section-ink   { background: var(--charcoal); color: var(--cream); }

.section-head { margin-bottom: 64px; }
.section-head h2 { max-width: 26ch; }
.section-head p {
  margin-top: 20px;
  max-width: 62ch;
  color: var(--stone);
  font-size: 17px;
  font-weight: 300;
}

.section-dark .section-head p,
.section-ink .section-head p { color: var(--muted); }

.section-dark .eyebrow,
.section-ink .eyebrow { color: var(--muted); }

.section-dark h2, .section-dark h3,
.section-ink h2, .section-ink h3 { color: var(--cream); }
.section-dark p, .section-ink p { color: var(--muted); }
.section-dark .lead { color: var(--cream); }

.section-dark ul li, .section-ink ul li {
  color: var(--cream);
  border-color: var(--hairline-dark);
}
.section-dark ul li:first-child,
.section-ink ul li:first-child { border-top-color: var(--hairline-dark); }
.section-dark strong, .section-ink strong { color: var(--cream); }

/* ===== Services grid (homepage) ============================== */

.services-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
}

.service-card {
  background: var(--white);
  padding: 40px 34px;
  display: flex;
  flex-direction: column;
  transition: background-color .18s ease;
}
.service-card:hover { background: var(--warm); }

.service-num {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red);                /* 8.19:1 on light grounds */
  margin-bottom: 22px;
  display: block;
}

.service-card h3 {
  margin-bottom: 14px;
  color: var(--charcoal);
}

.service-card p {
  font-size: 14.5px;
  color: var(--stone);
  line-height: 1.65;
  margin-bottom: 24px;
  flex: 1;
}

.service-link {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--red);
  border-bottom: 1px solid var(--hairline);
  align-self: flex-start;
  /* WCAG 2.2 SC 2.5.8 — 24px minimum target height */
  display: inline-flex;
  align-items: flex-end;
  min-height: 26px;
  padding-bottom: 5px;
  transition: border-color .18s ease;
}
.service-link:hover { border-bottom-color: var(--red); }

.service-card-alt { background: var(--charcoal); }
.service-card-alt:hover { background: var(--charcoal); }
.service-card-alt h3 { color: var(--cream); }
.service-card-alt p { color: var(--muted); }
.service-card-alt .service-num { color: var(--muted); }
.service-card-alt .service-link {
  color: var(--cream);
  border-bottom-color: var(--hairline-dark);
}
.service-card-alt .service-link:hover { border-bottom-color: var(--cream); }

/* ===== Split layout ========================================== */

.split { display: grid; grid-template-columns: 1fr 1fr; gap: 0; }
.split-text { padding: 80px 64px 80px 0; }
.split-panel { padding: 80px 0 80px 64px; border-left: 1px solid var(--hairline); }
.split-panel-dark { background: var(--charcoal); color: var(--cream); padding: 80px 48px; }

/* ===== Process steps ========================================= */

.process-list { display: flex; flex-direction: column; }

.process-step {
  display: grid;
  grid-template-columns: 52px 1fr;
  gap: 26px;
  padding: 30px 0;
  border-bottom: 1px solid var(--hairline);
}
.process-step:first-child { border-top: 1px solid var(--hairline); }

/* §17 — a DM Mono number in place of a decorative icon */
.step-num {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 12px;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--hairline);
  color: var(--red);
  flex-shrink: 0;
  margin-top: 2px;
}

.step-content h3 { margin-bottom: 8px; color: var(--charcoal); }
.step-content p { font-size: 14.5px; color: var(--stone); margin: 0; }

/* ===== Card grid (sectors, capabilities) ===================== */

.who-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
}

.who-card {
  padding: 36px 32px;
  background: var(--white);
  transition: background-color .18s ease;
}
.who-card:hover { background: var(--warm); }

/* §17 — DM Mono numerals, not decorative icon tiles */
.who-icon {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--red);
  display: block;
  margin-bottom: 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--hairline);
}

.who-card h3 { margin-bottom: 12px; color: var(--charcoal); }
.who-card p { font-size: 14px; color: var(--stone); line-height: 1.65; margin: 0; }

/* ===== Sector detail blocks (industries) ===================== */

.sector-list { display: flex; flex-direction: column; }

.sector-block {
  padding: 52px 0;
  border-top: 1px solid var(--hairline);
}
.sector-block:last-child { border-bottom: 1px solid var(--hairline); }

.sector-head {
  display: grid;
  grid-template-columns: 72px 1fr;
  gap: 26px;
  align-items: start;
  margin-bottom: 32px;
}

.sector-num {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.14em;
  color: var(--red);
  padding-top: 7px;
}

.sector-head h2 { font-size: clamp(20px, 2.2vw, 27px); margin-bottom: 14px; }
.sector-head p { color: var(--stone); font-size: 15.5px; max-width: 68ch; margin: 0; }

.sector-cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  margin-left: 98px;
}

.sector-col { background: var(--white); padding: 26px 24px; }

.sector-col h3 {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--hairline);
}

.sector-col ul li {
  font-size: 13.5px;
  color: var(--stone);
  padding: 7px 0 7px 18px;
  border: 0;
  line-height: 1.55;
}
.sector-col ul li:first-child { border-top: 0; padding-top: 0; }
.sector-col ul li::before { font-size: 11px; top: 6px; }

/* Priority sectors carry the warm ground and a short crimson rule */
.sector-block.is-priority .sector-col { background: var(--warm); }
.sector-block.is-priority .sector-num::after {
  content: "";
  display: block;
  width: 28px;
  height: 2px;
  background: var(--red);
  margin-top: 12px;
}

/* ===== Stat bar (dark) ======================================= */

.stat-bar {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--hairline-dark);
  border-bottom: 1px solid var(--hairline-dark);
  margin: 0 0 80px;
}

.stat-bar-item {
  padding: 38px 34px 38px 0;
  border-right: 1px solid var(--hairline-dark);
}
.stat-bar-item:not(:first-child) { padding-left: 34px; }
.stat-bar-item:last-child { border-right: none; }

.stat-bar-num {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 40px;
  color: var(--cream);
  line-height: 1.05;
  letter-spacing: 0.015em;
  margin-bottom: 10px;
}

.stat-bar-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--muted);
  line-height: 1.5;
}

/* ===== §17 Callout panel ===================================== */

.callout {
  background: var(--warm);
  border-left: 3px solid var(--red);
  padding: 24px 28px;
  margin: 36px 0;
}
.callout-label {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red);
  display: block;
  margin-bottom: 12px;
}
.callout p { color: var(--charcoal); font-size: 15.5px; margin: 0; max-width: 70ch; }

.section-dark .callout { background: transparent; }
.section-dark .callout p { color: var(--cream); }
.section-dark .callout-label { color: var(--muted); }

/* ===== CTA band ==============================================
   §09 — red is punctuation, never a background field. The band is
   charcoal with a red rule rather than a full red surface.
   ============================================================== */

.cta-section {
  background: var(--charcoal);
  border-top: 3px solid var(--red);
  padding: 88px 0;
  text-align: center;
}
.cta-section h2 { color: var(--cream); margin-bottom: 18px; margin-inline: auto; max-width: 22ch; }
.cta-section p {
  color: var(--muted);
  font-size: 17px;
  font-weight: 300;
  max-width: 58ch;
  margin: 0 auto 36px;
}
.cta-actions {
  display: flex;
  gap: 14px;
  justify-content: center;
  flex-wrap: wrap;
}

/* ===== FAQ =================================================== */

.faq-group { margin-bottom: 52px; }
.faq-group:last-child { margin-bottom: 0; }

.faq-group-title {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 6px;
}

.faq-list { display: flex; flex-direction: column; }

.faq-item { border-bottom: 1px solid var(--hairline); }
.faq-item:first-child { border-top: 1px solid var(--hairline); }

/* Native <details>/<summary>. No script, so the FAQ works with JavaScript
   disabled and the CSP needs no inline-script allowance. */

.faq-q {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  padding: 22px 0;
  cursor: pointer;
  list-style: none;
  color: var(--charcoal);
  transition: color .18s ease;
}
.faq-q::-webkit-details-marker { display: none; }
.faq-q::marker { content: ""; }
.faq-q:hover { color: var(--red); }

/* The heading carries the outline level; <summary> carries the control. */
.faq-q-text {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16.5px;
  font-weight: 500;
  letter-spacing: -0.008em;
  line-height: 1.45;
  color: inherit;
}

.faq-q::after {
  content: "+";
  font-family: var(--font-mono);
  font-size: 17px;
  color: var(--red);
  flex-shrink: 0;
  line-height: 1.45;
  transition: transform .25s ease;
}
.faq-item[open] > .faq-q::after { transform: rotate(45deg); }

.faq-a { padding-bottom: 26px; }
.faq-a p { font-size: 15px; color: var(--stone); line-height: 1.72; margin-bottom: 14px; }
.faq-a p:last-child { margin-bottom: 0; }
.faq-a ul { margin-bottom: 20px; }
.faq-a ul li { font-size: 14px; color: var(--stone); }

/* ===== Contact =============================================== */

.contact-grid {
  display: grid;
  grid-template-columns: 5fr 4fr;
  gap: 72px;
  align-items: start;
}

.contact-sidebar { padding-left: 56px; border-left: 1px solid var(--hairline); }

.contact-form-wrap {
  background: var(--white);
  border: 1px solid var(--hairline);
  padding: 44px;
}

.field { margin-bottom: 22px; }

.contact-form label {
  display: block;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--stone);
  margin-bottom: 9px;
}

.req { color: var(--red); }

.contact-form input,
.contact-form textarea,
.contact-form select {
  display: block;
  width: 100%;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--cream);
  color: var(--charcoal);
  padding: 13px 15px;
  font-family: var(--font-body);
  font-size: 16px;
  outline: none;
  transition: border-color .18s ease, background-color .18s ease;
}

.contact-form input:hover,
.contact-form textarea:hover,
.contact-form select:hover { border-color: var(--stone); }

.contact-form input:focus,
.contact-form textarea:focus,
.contact-form select:focus {
  border-color: var(--red);
  background: var(--white);
}

.contact-form textarea { resize: vertical; min-height: 170px; }

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }

.hint {
  font-size: 13px;
  color: var(--stone);
  margin-top: 9px;
  line-height: 1.5;
}

.form-actions { margin-top: 8px; }
.form-actions .btn { width: 100%; }

.form-fineprint {
  font-size: 13px;
  color: var(--stone);
  margin-top: 14px;
  line-height: 1.55;
}

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

.sidebar-block {
  margin-bottom: 38px;
  padding-bottom: 38px;
  border-bottom: 1px solid var(--hairline);
}
.sidebar-block:last-child { border-bottom: none; padding-bottom: 0; margin-bottom: 0; }

.sidebar-block h2 { font-size: 19px; margin-bottom: 12px; }
.sidebar-block h3 { font-size: 16px; margin-bottom: 12px; color: var(--charcoal); }
.sidebar-block p { font-size: 14.5px; color: var(--stone); margin-bottom: 16px; }
.sidebar-block p:last-child { margin-bottom: 0; }
.sidebar-block ul li { font-size: 14px; color: var(--stone); }

.next-steps-list { display: flex; flex-direction: column; }

.next-step {
  display: grid;
  grid-template-columns: 34px 1fr;
  gap: 16px;
  align-items: start;
  padding: 18px 0;
  border-bottom: 1px solid var(--hairline);
}
.next-step:first-child { border-top: 1px solid var(--hairline); }

.next-num {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--hairline);
  color: var(--red);
  flex-shrink: 0;
}

.next-step strong {
  display: block;
  font-size: 15px;
  font-weight: 600;
  margin-bottom: 4px;
  color: var(--charcoal);
}
.next-step p { font-size: 13.5px; color: var(--stone); margin: 0; }

.prefer-email-row {
  margin-top: 28px;
  padding-top: 28px;
  border-top: 1px solid var(--hairline);
}
.prefer-email-row h3 { font-size: 16px; margin-bottom: 10px; }
.prefer-email-row p { font-size: 14px; color: var(--stone); margin-bottom: 14px; }

/* ===== Page hero (inner pages) =============================== */

.page-hero {
  background: var(--charcoal);
  color: var(--cream);
  padding: 84px 0 76px;
}

.page-hero .eyebrow { color: var(--muted); }
.page-hero h1 { color: var(--cream); margin-bottom: 22px; }
.page-hero .lead { color: var(--cream); font-weight: 300; max-width: 60ch; }
.page-hero .muted {
  color: var(--muted);
  margin-top: 20px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: 0.05em;
  line-height: 1.7;
  max-width: 72ch;
}

/* ===== Prose ================================================= */

.prose { padding: 88px 0; }
.prose-narrow { max-width: 720px; }
.prose-narrow > * + * { margin-top: 22px; }

.prose-narrow h2 {
  margin-top: 52px;
  font-size: clamp(21px, 2.4vw, 28px);
  padding-bottom: 14px;
  border-bottom: 1px solid var(--hairline);
}

.prose-narrow p { color: var(--charcoal); font-size: 16px; line-height: 1.75; }
.prose-narrow .muted { color: var(--stone); font-size: 15px; }
.prose-narrow a { color: var(--red); text-decoration: underline; text-underline-offset: 3px; }

/* Body prose helpers — replace per-element inline styles */
.body-copy { color: var(--charcoal); font-size: 16px; line-height: 1.78; margin-bottom: 22px; max-width: 68ch; }
.body-copy:last-child { margin-bottom: 0; }
.body-copy-sm { font-size: 15px; line-height: 1.72; color: var(--stone); margin-bottom: 18px; max-width: 68ch; }
.body-copy-sm:last-child { margin-bottom: 0; }
.section-dark .body-copy, .section-dark .body-copy-sm { color: var(--muted); }
.intro-copy { color: var(--charcoal); font-size: 17px; font-weight: 300; line-height: 1.72; max-width: 68ch; margin-bottom: 56px; }

/* ===== Service blocks (services page) ======================== */

.service-block {
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--red);
  background: var(--white);
  padding: 40px 40px 40px 37px;
  margin: 0 0 24px;
}

.service-block h2 { font-size: clamp(21px, 2.2vw, 26px); margin-bottom: 10px; }

/* The principal service is given weight over the four capabilities beneath it. */
.service-block-flagship {
  border-top: 3px solid var(--red);
  padding: 48px 48px 48px 45px;
  margin-bottom: 8px;
}
.service-block-flagship h2 { font-size: clamp(26px, 3.2vw, 36px); margin-bottom: 12px; }
.service-block-flagship > .service-num { color: var(--red); }
.service-block-flagship p { font-size: 16px; }
@media (max-width: 760px) {
  .service-block-flagship { padding: 30px 26px 30px 23px; }
}

/* v3.3 — the two adversarial capabilities. A 2px crimson rule where the
   principal service carries 3px, and the group label in crimson. Same box,
   same type sizes, same order: the hierarchy is stated once and quietly. */
.service-block-lead { border-top: 2px solid var(--red); }
.service-block-lead > .service-num { color: var(--red); }

.service-subhead {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 24px;
  line-height: 1.6;
}

.service-block > .service-num { margin-bottom: 14px; }
.service-block p { color: var(--charcoal); font-size: 15.5px; line-height: 1.75; margin-bottom: 14px; max-width: 74ch; }
.service-block ul { margin-bottom: 18px; }

/* ===== Framework stage blocks (methodology) ================== */

.approach-block {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 30px;
  padding: 38px 0;
  border-bottom: 1px solid var(--hairline);
}
.approach-block:first-child { border-top: 1px solid var(--hairline); }

.approach-num {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 52px;
  color: var(--red);
  line-height: 0.9;
  letter-spacing: 0.01em;
}

.approach-block h2 { font-size: clamp(19px, 2vw, 23px); margin-bottom: 12px; color: var(--charcoal); }

.approach-stage-label {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--stone);
  display: block;
  margin-bottom: 10px;
}

.approach-block p { color: var(--stone); font-size: 15px; margin-bottom: 14px; line-height: 1.72; }
.approach-block ul { margin-top: 18px; }
.approach-block ul li { font-size: 14px; color: var(--stone); }

/* ===== Framework track (dark) ================================ */

.framework-track {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0;
  margin-top: 12px;
}

.framework-phase {
  position: relative;
  padding: 34px 28px 0 0;
  border-top: 1px solid var(--hairline-dark);
}

/* The red marker is a geometric accent, not text — §11 permits */
.framework-phase::before {
  content: "";
  position: absolute;
  top: -4px;
  left: 0;
  width: 7px;
  height: 7px;
  background: var(--red);
}

.framework-phase-num {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--muted);
  display: block;
  margin-bottom: 10px;
}

.framework-phase h3 { font-size: 18px; color: var(--cream); margin-bottom: 10px; }
.framework-phase p { font-size: 13px; line-height: 1.6; color: var(--muted); margin: 0; }

/* ===== Deliverables ========================================== */

.deliverables-grid,
.deliverables-grid-5 {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  margin: 28px 0 0;
}

.deliverable { background: var(--white); padding: 30px 26px; }

.deliverable-icon {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 16px;
  display: block;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--hairline);
}

.deliverable h3 { font-size: 16.5px; margin-bottom: 10px; }
.deliverable p { font-size: 13.5px; color: var(--stone); margin: 0; line-height: 1.6; }

/* ===== Rules ================================================= */

.hr-split {
  border: 0;
  height: 1px;
  background: var(--hairline);
  margin: 56px 0;
}

/* ===== Principles / assurance grids ========================== */

.principles-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  margin: 24px 0 0;
}

.principle { background: var(--white); padding: 30px 28px; }
.principle:nth-child(even) { background: var(--warm); }

.principle-label {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--red);
  margin-bottom: 12px;
  display: block;
}

.principle h3 { font-size: 16.5px; margin-bottom: 8px; }
.principle p { font-size: 13.5px; color: var(--stone); margin: 0; line-height: 1.62; }

.assurance-grid,
.assurance-grid-6 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  margin: 28px 0 0;
}

.assurance-item { background: var(--white); padding: 26px 28px; }

.assurance-label {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red);
  display: block;
  margin-bottom: 10px;
}

.assurance-item p { font-size: 14px; color: var(--stone); margin: 0; line-height: 1.65; }
.assurance-item a { color: var(--red); text-decoration: underline; text-underline-offset: 3px; }

/* ===== Footer ================================================ */

.footer {
  background: var(--charcoal);
  color: var(--muted);
  padding: 44px 0;
  border-top: 2px solid var(--red);
  flex-shrink: 0;
}

.footer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  line-height: 1.7;
}

.footer-entity p { margin: 0; font-size: 12px; line-height: 1.8; }
.footer-entity p + p { color: var(--muted); }

.footer-legal {
  margin-top: 28px;
  padding-top: 20px;
  border-top: 1px solid var(--hairline-dark);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.05em;
  color: var(--muted);
}

.footer-links { display: flex; gap: 28px; flex-wrap: wrap; align-items: center; }

.footer-inner a {
  color: var(--muted);
  border-bottom: 1px solid transparent;
  transition: color .18s ease, border-color .18s ease;
}

/* WCAG 2.2 SC 2.5.8 — 24px minimum target height */
.footer-links a {
  display: inline-flex;
  align-items: center;
  min-height: 26px;
}
.footer-inner a:hover { color: var(--cream); border-bottom-color: var(--cream); }

/* ===== Cookie notice ========================================= */

.cookie-notice {
  position: fixed;
  bottom: 0;
  right: 0;
  left: 0;
  z-index: 1000;
  background: var(--charcoal);
  border-top: 2px solid var(--red);
  padding: 20px var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
}

/* `hidden` is authored into the markup and removed by the site script. The
   attribute must beat `display: flex`, so it is stated explicitly. Without
   JavaScript the notice never appears at all. */
.cookie-notice[hidden] { display: none; }
.cookie-notice.hidden { display: none; }

.cookie-text {
  font-size: 13.5px;
  color: var(--cream);
  line-height: 1.6;
  max-width: 78ch;
  margin: 0;
}

.cookie-text a { color: var(--cream); text-decoration: underline; text-underline-offset: 3px; }

.cookie-actions { display: flex; align-items: center; gap: 20px; }

.cookie-btn {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  padding: 11px 24px;
  background: var(--cream);
  color: var(--charcoal);
  border: 1px solid var(--cream);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color .18s ease, color .18s ease;
}
.cookie-btn:hover { background: transparent; color: var(--cream); }

.cookie-dismiss {
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--cream);
  background: none;
  border: 0;
  cursor: pointer;
  /* WCAG 2.2 SC 2.5.8 — 24px minimum target height */
  min-height: 26px;
  padding: 4px 6px;
  white-space: nowrap;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: transparent;
  transition: text-decoration-color .18s ease;
}
.cookie-dismiss:hover { text-decoration-color: var(--cream); }

/* ===== Layout utilities ====================================== */

.grid-2-1       { display: grid; grid-template-columns: 2fr 1fr; gap: 80px; align-items: start; }
.grid-1-2       { display: grid; grid-template-columns: 1fr 2fr; gap: 80px; align-items: start; }
.grid-1-1       { display: grid; grid-template-columns: 1fr 1fr; gap: 80px; align-items: start; }
.grid-1-1-tight { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: start; }
.two-col-narrow { display: grid; grid-template-columns: 1fr 2fr; gap: 80px; align-items: start; }

.sticky-aside { position: sticky; top: calc(var(--header-h) + 40px); }

/* ===== Utilities =============================================
   These exist so that no element needs a style attribute, which lets the
   Content-Security-Policy drop style-src 'unsafe-inline' entirely.
   ============================================================== */

.u-mb-0   { margin-bottom: 0; }
.u-mb-md  { margin-bottom: 20px; }
.u-mb-lg  { margin-bottom: 24px; }
.u-mb-xl  { margin-bottom: 56px; }
.u-mt-md  { margin-top: 20px; }
.u-mt-xl  { margin-top: 80px; }
.u-measure      { max-width: 660px; }
.u-measure-head { max-width: 34ch; margin-bottom: 12px; }
.grid-single    { grid-template-columns: 1fr; }

.inline-link {
  color: var(--red);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.inline-link:hover { text-decoration-thickness: 2px; }

.inline-link-plain {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.section-dark .inline-link,
.page-hero .inline-link { color: var(--cream); }


/* ============================================================
   v3.2 COMPONENTS
   Built from the §09 palette and §17 component rules only. No
   imagery, no gradients, no shadows — the diagrams are drawn
   with rules, hairlines and type, which is what §01 "precision"
   and §19 ask for.
   ============================================================ */

/* ===== Pull statement ========================================
   §17 permits a 2px crimson rule at 44-60px as an emphasis
   device. The statement is set in the body face rather than
   Bebas, because it is a sentence and not a headline.
   ============================================================== */

.pull-statement {
  padding: 22px 0 22px 32px;
  border-left: 3px solid var(--red);
  /* A px cap, deliberately. `ch` here would resolve against this wrapper's
     inherited 16px font rather than the 46px statement inside it, capping the
     block at roughly 230px and breaking the statement into a narrow column. */
  max-width: 760px;
}
.pull-statement p {
  font-size: clamp(26px, 3.6vw, 46px);
  font-weight: 300;
  line-height: 1.24;
  letter-spacing: -0.02em;
  color: var(--charcoal);
  margin: 0;
  text-wrap: balance;
}
.pull-statement .pull-emphasis { font-weight: 600; }
.section-dark .pull-statement p,
.section-dark .pull-statement { color: var(--cream); }
.pull-attrib {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--stone);
  margin-top: 20px;
}
.section-dark .pull-attrib { color: var(--muted); }

/* ===== Operating-model tiles (homepage hero) =================
   Replaces the former pseudo-statistic panel. Four principles,
   not four numbers.
   ============================================================== */

.model-list {
  border-left: 1px solid var(--hairline-dark);
  padding-left: 44px;
  display: flex;
  flex-direction: column;
}
.model-item {
  padding: 20px 0;
  border-bottom: 1px solid var(--hairline-dark);
}
.model-item:first-child { padding-top: 0; }
.model-item:last-child { border-bottom: none; padding-bottom: 0; }

.model-term {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 27px;
  letter-spacing: 0.02em;
  line-height: 1.1;
  color: var(--cream);
  margin-bottom: 6px;
}
.model-desc {
  font-size: 14px;
  line-height: 1.55;
  color: var(--muted);
  margin: 0;
}

/* ===== Protective-security system diagram ====================
   Threat -> three domains -> assessment -> evidence ->
   prioritised improvement. Every label is real text in the DOM,
   so it is readable, selectable and indexable; the connectors
   are the only decoration.
   ============================================================== */

.system-flow {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  max-width: 900px;
  margin: 0 auto;
}

.flow-node {
  border: 1px solid var(--hairline-dark);
  padding: 20px 26px;
  text-align: center;
}
.flow-node-label {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  display: block;
  margin-bottom: 8px;
}
.flow-node-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(20px, 2.4vw, 27px);
  letter-spacing: 0.02em;
  line-height: 1.12;
  color: var(--cream);
  margin: 0;
}
.flow-node-note {
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--muted);
  margin: 8px 0 0;
}

/* The threat node opens the diagram: crimson rule above it. */
.flow-node-threat { border-top: 3px solid var(--red); }

/* The three domains examined as one system. */
.flow-domains {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--hairline-dark);
  border: 1px solid var(--hairline-dark);
}
.flow-domain {
  background: var(--charcoal);
  padding: 24px 22px;
}
.flow-domain h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 24px;
  letter-spacing: 0.02em;
  color: var(--cream);
  margin-bottom: 12px;
}
.flow-domain ul { margin: 0; }
.flow-domain ul li {
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted);
  border: 0;
  padding: 4px 0 4px 16px;
}
.flow-domain ul li:first-child { border-top: 0; padding-top: 0; }
.flow-domain ul li::before { font-size: 10px; top: 4px; }

/* Connector: a short crimson rule with a terminating node, the
   same visual language as the logo's trace and dot. */
.flow-link {
  height: 34px;
  position: relative;
  flex-shrink: 0;
}
.flow-link::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 6px;
  width: 2px;
  margin-left: -1px;
  background: var(--red);
}
.flow-link::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 7px;
  height: 7px;
  margin-left: -3.5px;
  background: var(--red);
}

/* The assessment node is where the adversarial perspective enters. */
.flow-node-assess {
  border-color: var(--red);
  border-left-width: 3px;
}

/* ===== BPSAF stage track =====================================
   Each stage carries its number, name, purpose and the output
   the next stage depends on, so it reads as a method rather
   than a five-step marketing graphic.
   ============================================================== */

.bpsaf-track {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0;
  margin-top: 8px;
}

.bpsaf-stage {
  position: relative;
  padding: 30px 26px 0 0;
  border-top: 1px solid var(--hairline-dark);
  /* A grid so the output blocks align across the track regardless of how many
     lines each purpose statement runs to. */
  display: grid;
  grid-template-rows: auto auto 1fr auto;
}
.bpsaf-stage::before {
  content: "";
  position: absolute;
  top: -4px;
  left: 0;
  width: 7px;
  height: 7px;
  background: var(--red);
}
.bpsaf-num {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--muted);
  display: block;
  margin-bottom: 10px;
}
.bpsaf-stage h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 26px;
  letter-spacing: 0.02em;
  color: var(--cream);
  margin-bottom: 10px;
}
.bpsaf-stage p {
  font-size: 13px;
  line-height: 1.55;
  color: var(--muted);
  margin: 0 0 14px;
}
.bpsaf-output {
  align-self: end;
  min-height: 70px;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.5;
  letter-spacing: 0.03em;
  color: var(--muted);
  padding-top: 12px;
  border-top: 1px solid var(--hairline-dark);
}
.bpsaf-output strong {
  display: block;
  color: var(--cream);
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-size: 10px;
  margin-bottom: 5px;
}

/* v3.3.2 — the output blocks share one baseline across the track.

   Each stage was its own independent grid, so the last row was sized by that
   stage's own output text. Four of the five outputs set on two lines and made
   a 74px row; Assess — "A documented evidence base." — sets on one line and
   only reached the 70px minimum. With the block bottom-aligned, a shorter box
   starts lower, which is why that stage's rule and OUTPUT label sat four
   pixels below the rest.

   Subgrid hands row sizing back to the track, so all five stages share one set
   of rows: the fourth row is as tall as the tallest output and every block
   begins on the same line, whatever it says and however many lines the purpose
   statement above it runs to. The stage sets its own row-gap so that the
   track's row-gap at the narrower breakpoints still separates the rows OF
   STAGES without opening gaps inside one.

   Browsers without subgrid fall through to the rules above, unchanged. */
@supports (grid-template-rows: subgrid) {
  .bpsaf-track { grid-template-rows: auto auto 1fr auto; }
  .bpsaf-stage {
    grid-row: span 4;
    grid-template-rows: subgrid;
    row-gap: 0;
  }
  .bpsaf-output { align-self: stretch; }
}

/* The band that carries the principle running through the track. */
.bpsaf-throughline {
  margin-top: 44px;
  padding: 20px 26px;
  border: 1px solid var(--hairline-dark);
  border-left: 3px solid var(--red);
  display: flex;
  align-items: baseline;
  gap: 20px;
  flex-wrap: wrap;
}
.bpsaf-throughline-label {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  flex-shrink: 0;
}
.bpsaf-throughline p {
  font-size: 15px;
  line-height: 1.6;
  color: var(--cream);
  margin: 0;
  flex: 1;
  min-width: 260px;
}

/* ===== Flagship service ======================================
   Establishes the assessment as the principal proposition, with
   the specialist capabilities beneath it rather than beside it.
   ============================================================== */

.flagship {
  background: var(--white);
  border: 1px solid var(--hairline);
  border-top: 3px solid var(--red);
  padding: 48px;
}
.flagship-label {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red);
  display: block;
  margin-bottom: 18px;
}
.flagship h2 { font-size: clamp(26px, 3.2vw, 38px); margin-bottom: 18px; }
.flagship p { font-size: 16.5px; line-height: 1.7; color: var(--charcoal); max-width: 62ch; }
.flagship p + p { margin-top: 16px; }

.capability-note {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  line-height: 1.65;
  color: var(--stone);
  max-width: 70ch;
  margin-bottom: 32px;
}

.capability-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
}

/* v3.3 — capability hierarchy.

   Physical intrusion testing and adversary simulation are the established
   specialist depth and are grouped together above the assessment and
   assurance capabilities. The distinction is carried by grouping, a group
   label and a 2px crimson rule on the two lead cards — not by ranking
   language, and not by demoting anything. All four remain the same size,
   in the same grid, with the same link treatment. */

.capability-set + .capability-set { margin-top: 40px; }

.capability-group {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--charcoal);
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 16px;
}
.capability-group::after {
  content: "";
  height: 1px;
  flex: 1;
  background: var(--hairline);
}

.capability-group-note {
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--stone);
  max-width: 68ch;
  margin-bottom: 20px;
}

.capability-grid-pair { grid-template-columns: repeat(2, 1fr); }

.capability-lead { border-top: 2px solid var(--red); }
.capability {
  background: var(--white);
  padding: 30px 26px;
  display: flex;
  flex-direction: column;
  transition: background-color .18s ease;
}
.capability:hover { background: var(--warm); }
.capability-num {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--hairline);
}
.capability h3 { font-size: 17px; margin-bottom: 10px; color: var(--charcoal); }
.capability p { font-size: 13.5px; color: var(--stone); line-height: 1.6; margin: 0 0 18px; flex: 1; }

/* ===== Industries: sector navigation and disclosures ========= */

.sector-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 56px;
  padding-bottom: 32px;
  border-bottom: 1px solid var(--hairline);
}
.sector-nav a {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  color: var(--charcoal);
  border: 1px solid var(--hairline);
  padding: 9px 14px;
  min-height: 34px;
  display: inline-flex;
  align-items: center;
  transition: border-color .18s ease, background-color .18s ease;
}
.sector-nav a:hover { border-color: var(--red); background: var(--warm); }
.sector-nav-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--stone);
  width: 100%;
  margin-bottom: 4px;
}

.sector-disclosure {
  border-top: 1px solid var(--hairline);
}
.sector-disclosure:last-of-type { border-bottom: 1px solid var(--hairline); }

/* Three-column grid, not a flex row. Under flex the description started
   wherever its sector name happened to end, so the four rows began at four
   different horizontal positions and the column read as ragged. The name
   column is now a fixed track, so every description begins on the same line
   and wrapped lines stay inside it.

     [ sector name ]  [ description ]  [ + ]

   The name track is wide enough for the longest name in the set — Life
   sciences & pharmaceuticals — at the largest size the clamp reaches. */
.sector-summary {
  display: grid;
  grid-template-columns: 360px minmax(0, 1fr) 20px;
  align-items: baseline;
  column-gap: 40px;
  padding: 26px 0;
  cursor: pointer;
  list-style: none;
  min-height: 44px;
}
.sector-summary::-webkit-details-marker { display: none; }
.sector-summary::marker { content: ""; }
.sector-summary::after {
  content: "+";
  font-family: var(--font-mono);
  font-size: 17px;
  color: var(--red);
  justify-self: end;
  text-align: right;
}
.sector-disclosure[open] > .sector-summary::after { content: "\2013"; }

.sector-summary-title {
  font-family: var(--font-body);
  font-size: clamp(18px, 2vw, 22px);
  font-weight: 600;
  letter-spacing: -0.012em;
  color: var(--charcoal);
  margin: 0;
  transition: color .18s ease;
}
.sector-summary:hover .sector-summary-title { color: var(--red); }
.sector-summary-note {
  font-size: 14px;
  color: var(--stone);
  margin: 0;
  /* No max-width and no flex basis: the track decides where the column starts
     and ends, so a long description wraps inside it rather than pushing the
     row out of alignment with its neighbours. */
  max-width: none;
}
.sector-disclosure .sector-cols { margin: 0 0 32px; }

@media (max-width: 1040px) {
  .capability-grid { grid-template-columns: repeat(2, 1fr); }
  .bpsaf-track { grid-template-columns: repeat(3, 1fr); row-gap: 44px; }
}

@media (max-width: 860px) {
  .model-list {
    border-left: none;
    padding-left: 0;
    border-top: 1px solid var(--hairline-dark);
    padding-top: 8px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 32px;
  }
  .model-item, .model-item:first-child, .model-item:last-child {
    padding: 20px 0;
    border-bottom: 1px solid var(--hairline-dark);
  }
  .model-item:nth-last-child(-n+2) { border-bottom: none; }
  .flow-domains { grid-template-columns: 1fr; }
  .bpsaf-track { grid-template-columns: repeat(2, 1fr); }
  .flagship { padding: 32px 26px; }
  .pull-statement { padding-left: 24px; }
  /* Below 860px the three-column system collapses to a stack rather than
     being squeezed: name over description, with the control pinned top-right. */
  .sector-summary {
    display: block;
    position: relative;
    padding-right: 32px;
  }
  .sector-summary-note { margin-top: 8px; }
  .sector-summary::after { position: absolute; right: 0; top: 26px; }
}

@media (max-width: 760px) {
  .bpsaf-output { min-height: 0; }
  .capability-grid { grid-template-columns: 1fr; }
  .bpsaf-track { grid-template-columns: 1fr; row-gap: 36px; }
  .bpsaf-stage { padding-right: 0; }
  .model-list { grid-template-columns: 1fr; }
  .model-item:nth-last-child(-n+2) { border-bottom: 1px solid var(--hairline-dark); }
  .model-item:last-child { border-bottom: none; }
  .flow-node { padding: 18px 20px; }
  .sector-nav { gap: 8px; margin-bottom: 40px; }
}

/* ===== Scroll reveal ==========================================

   Restrained entrance motion — opacity and a 14px rise over 320ms,
   staggered where a sequence carries meaning.

   Everything here is scoped under `js-reveal` on <html>, which nav.v4.js
   adds only when IntersectionObserver is present and the visitor has not
   asked for reduced motion, and which is stripped again by a failsafe if
   site.v4.js never reports in. With scripting off, with reduced motion, or
   with either file missing, no rule below matches and every element paints
   normally. Nothing on this site is ever hidden waiting for a script.
   ============================================================== */

.js-reveal [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  will-change: opacity, transform;
}

.js-reveal [data-reveal].is-in {
  opacity: 1;
  transform: none;
  transition: opacity 320ms cubic-bezier(.22,.61,.36,1),
              transform 320ms cubic-bezier(.22,.61,.36,1);
  will-change: auto;
}

.js-reveal [data-reveal="1"].is-in { transition-delay: 45ms;  }
.js-reveal [data-reveal="2"].is-in { transition-delay: 90ms;  }
.js-reveal [data-reveal="3"].is-in { transition-delay: 135ms; }
.js-reveal [data-reveal="4"].is-in { transition-delay: 180ms; }
.js-reveal [data-reveal="5"].is-in { transition-delay: 225ms; }
.js-reveal [data-reveal="6"].is-in { transition-delay: 270ms; }
.js-reveal [data-reveal="7"].is-in { transition-delay: 315ms; }
.js-reveal [data-reveal="8"].is-in { transition-delay: 360ms; }
.js-reveal [data-reveal="9"].is-in { transition-delay: 405ms; }

/* Keyboard focus jumps ahead of the scroll, so a control can be focused
   before its container has been revealed. Focus reveals it immediately and
   without its place in the stagger: a focused control is never invisible
   for longer than the fade itself. */
.js-reveal [data-reveal].is-in.is-instant { transition-delay: 0ms; }

/* Belt and braces: if the class is ever present under reduced motion —
   a preference changed after load, say — nothing stays hidden. */
@media (prefers-reduced-motion: reduce) {
  .js-reveal [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ===== §11 Accessibility — focus visibility ==================
   2px indicator with offset. Verified 8.19:1 (red on cream) and
   15.43:1 (cream on charcoal) against their adjacent surfaces.
   ============================================================== */

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

.site-header :focus-visible,
.hero :focus-visible,
.page-hero :focus-visible,
.section-dark :focus-visible,
.section-ink :focus-visible,
.cta-section :focus-visible,
.footer :focus-visible,
.cookie-notice :focus-visible {
  outline-color: var(--cream);
}

/* ===== §11 Accessibility — reduced motion ==================== */

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

/* ===== Print ================================================= */

@media print {
  .site-header, .cookie-notice, .nav-toggle, .skip-link { display: none; }
  body { padding-top: 0; background: #fff; color: #000; }
  .section, .page-hero, .hero, .cta-section { padding: 24px 0; background: #fff; color: #000; }
  .hero h1, .page-hero h1, .cta-section h2, .section-dark h2, .section-dark h3 { color: #000; }
  .faq-a { max-height: none; }
}

/* ===== Responsive ============================================ */

@media (max-width: 1180px) {
  :root { --gutter: 32px; }
}

/* The lockup steps down at 1180px, not at 1040px, and the two must move
   together. --gutter drops from 48px to 32px at 1180px, and the gutter is the
   left arm of the §07 zone: at 63px the lockup needs 37.0px of clear space and
   a 32px gutter leaves 35.5px, so between 1041px and 1180px the desktop lockup
   was inside its own exclusion zone on the page edge. v3.2 did not see this
   because test_header.py sampled 1024 and 1440 and nothing between them — the
   same failure mode that hid the 320px defect in v3.1.1. Both widths are now
   in the suite. */
@media (max-width: 1180px) {
  /* Tablet: 58px -> 199.4px wide, header 95px. Scaled with the desktop bar so
     that the header does not grow as the viewport narrows. The lockup still
     steps down here because --gutter narrows to 32px at this breakpoint and the
     LEFT arm of the zone is not part of the approved exception: 32px + 3.3px of
     artwork inset = 35.3px against X = 34.1px, satisfied. */
  :root { --header-h: 95px; }
  .brand-logo { height: 58px; }
}

@media (max-width: 1040px) {

  .framework-track { grid-template-columns: repeat(3, 1fr); row-gap: 40px; }
  .deliverables-grid, .deliverables-grid-5 { grid-template-columns: repeat(3, 1fr); }
  .deliverables-grid-5 .deliverable:last-child { grid-column: span 3; }
  .nav a { font-size: 11px; padding: 10px 8px; letter-spacing: 0.05em; }
  .sector-cols { margin-left: 0; }
}

@media (max-width: 1024px) {
  .services-grid { grid-template-columns: 1fr 1fr; }
  .who-grid { grid-template-columns: 1fr 1fr; }
  .stat-bar { grid-template-columns: 1fr 1fr; }
  .stat-bar-item { border-bottom: 1px solid var(--hairline-dark); }
  .stat-bar-item:nth-child(odd) { padding-left: 0; }
  .stat-bar-item:nth-child(even) { border-right: none; padding-left: 34px; }
  .stat-bar-item:nth-last-child(-n+2) { border-bottom: none; }
  .principles-grid { grid-template-columns: 1fr; }
  .contact-grid { grid-template-columns: 1fr; gap: 48px; }
  .contact-sidebar { padding-left: 0; border-left: none; border-top: 1px solid var(--hairline); padding-top: 44px; }
  .sticky-aside { position: static; }
}

@media (max-width: 900px) {
  .sector-cols { grid-template-columns: 1fr; }
  .sector-head { grid-template-columns: 56px 1fr; gap: 18px; }
}

@media (max-width: 860px) {
  .grid-2-1, .grid-1-2, .grid-1-1, .grid-1-1-tight, .two-col-narrow {
    grid-template-columns: 1fr;
    gap: 48px;
  }
  .hero-inner { grid-template-columns: 1fr; gap: 52px; }
  .hero-stats {
    border-left: none;
    padding-left: 0;
    border-top: 1px solid var(--hairline-dark);
    padding-top: 8px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 32px;
  }
  .hero-stat, .hero-stat:first-child, .hero-stat:last-child {
    padding: 22px 0;
    border-bottom: 1px solid var(--hairline-dark);
  }
  .hero-stat:nth-last-child(-n+2) { border-bottom: none; }
  .split { grid-template-columns: 1fr; }
  .split-text { padding: 56px 0; }
  .split-panel { padding: 56px 0; border-left: none; border-top: 1px solid var(--hairline); }
  .framework-track { grid-template-columns: repeat(2, 1fr); }
  .services-grid { grid-template-columns: 1fr; }
  .who-grid { grid-template-columns: 1fr; }
  .form-grid { grid-template-columns: 1fr; }
  .deliverables-grid, .deliverables-grid-5 { grid-template-columns: 1fr 1fr; }
  .deliverables-grid-5 .deliverable:last-child { grid-column: span 2; }
  .assurance-grid, .assurance-grid-6 { grid-template-columns: 1fr; }
}

@media (max-width: 760px) {
  /* §07 at mobile: 48px high -> 165.0px wide, still above the 160px minimum,
     so the full horizontal lockup is retained rather than falling back to the
     Breach Mark. X = 28.2px. Header content box is 92px (96 less the 4px of
     rules), leaving 22px above and below: 22 + 10.8 = 32.8 and 22 + 8.3 = 30.3.
     The gutter is 28px rather than 24px so the left page edge also clears:
     28 + 3.6 = 31.6 >= 28.2. */
  :root { --gutter: 28px; --header-h: 96px; }

  /* The disclosure becomes a real menu. `open` is removed by nav.v4.js
     before paint; if that script never runs the panel is simply already
     expanded and the control still closes it. Either way the links are
     reachable and no visible control is inert. */
  .nav-toggle { display: flex; }

  /* Collapsed and expanded are both stated explicitly here rather than
     left to the browser's own handling of closed <details> content,
     because the panel is positioned and would otherwise stay painted.
     Note this rule is scoped to the mobile breakpoint: at desktop the
     disclosure is always open, and the base `.nav { display: flex }`
     applies with no :not([open]) rule that could hide it. */
  .nav-wrap:not([open]) > .nav { display: none; }

  .nav-wrap[open] > .nav {
    display: flex;
    position: absolute;
    top: var(--header-h);
    right: 0;
    left: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 8px 0;
    background: var(--charcoal);
    border-top: 1px solid var(--hairline-dark);
    border-bottom: 1px solid var(--hairline-dark);
  }
  .nav-wrap > .nav a {
    padding: 15px var(--gutter);
    border-bottom: none;
    border-left: 2px solid transparent;
  }
  .nav-wrap > .nav a.active {
    border-left-color: var(--red);
    border-bottom-color: transparent;
  }

  /* Open state: the bars become a cross. */
  .nav-wrap[open] > .nav-toggle { color: var(--cream); border-color: var(--muted); }
  .nav-wrap[open] .nav-toggle-bars { background: transparent; }
  .nav-wrap[open] .nav-toggle-bars::before { transform: translateY(6px) rotate(45deg); }
  .nav-wrap[open] .nav-toggle-bars::after  { transform: translateY(-6px) rotate(-45deg); }

  .brand-logo { height: 48px; }

  .hero { padding: 56px 0 52px; }
  .section { padding: 64px 0; }
  .section-tight { padding: 48px 0; }
  .prose { padding: 56px 0; }
  .page-hero { padding: 56px 0 48px; }
  .cta-section { padding: 64px 0; }
  .section-head { margin-bottom: 44px; }

  .stat-bar { grid-template-columns: 1fr; margin-bottom: 56px; }
  .stat-bar-item,
  .stat-bar-item:nth-child(even),
  .stat-bar-item:nth-child(odd) {
    border-right: none;
    border-bottom: 1px solid var(--hairline-dark);
    padding: 28px 0;
  }
  .stat-bar-item:last-child { border-bottom: none; }

  .service-block { padding: 28px 24px 28px 21px; }
  .contact-form-wrap { padding: 26px; }
  .deliverables-grid, .deliverables-grid-5 { grid-template-columns: 1fr; }
  .deliverables-grid-5 .deliverable:last-child { grid-column: auto; }

  .footer-inner { flex-direction: column; align-items: flex-start; gap: 16px; }
  .cookie-notice { flex-direction: column; align-items: flex-start; gap: 14px; padding: 16px var(--gutter); }
  .cookie-text { font-size: 12.5px; line-height: 1.5; }
  .cookie-btn, .cookie-dismiss { font-size: 13px; }
  .approach-block { grid-template-columns: 48px 1fr; gap: 20px; }
  .approach-num { font-size: 40px; }
  .sector-block { padding: 40px 0; }
  .sector-head { grid-template-columns: 1fr; gap: 10px; margin-bottom: 26px; }
  .sector-num { padding-top: 0; }
}

@media (max-width: 520px) {
  .framework-track { grid-template-columns: 1fr; row-gap: 32px; }
  .framework-phase { padding-right: 0; }
  .btn { width: 100%; }
}

/* ===== Narrowest widths ======================================
   At 320px the container is 264px. The full horizontal lockup is
   retained rather than falling back to the Breach Mark, because it
   still renders at 165px — above the §07 minimum of 160px. The
   space is found by narrowing the header gap and dropping the
   painted "Menu" wordmark; the word remains in the accessibility
   tree via .visually-hidden, so the control keeps its name.

     264 container - 165 logo - 48 control = 51px of clear gap,
     against the 19.4px still required after the artwork's own
     right-hand padding. Verified in-browser at 320px.
   ============================================================== */

@media (max-width: 420px) {
  .header-inner { gap: 16px; }
  .nav-toggle { padding: 9px 13px; gap: 0; }   /* 44 x 44 via the min-* above */
  .nav-toggle-label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
}
