/* Generated by build.mjs from css/tokens.css + css/styles.css — do not edit. */
/* ==========================================================================
   Pinnacle Management Group — design tokens

   ONE authored look. Colours are PMG's own — warm near-black, warm ivory,
   the bronze sampled from the firm's logo — and stay that way; that part of
   the system is locked. Structure, type, and interaction are aligned with
   the group's own Legacy Aviation Group (lag-systems.com): Switzer carrying
   the entire type scale at a light weight, "Ethic New" italic reserved for
   the one-word accent inside a headline, pill buttons, and the single
   burger-driven nav.

   Semantic tokens (--ink, --body, --accent, --line, --surface…) are
   re-declared by .band--light, so a component reads the token and never needs
   to know which ground it is sitting on.

   TRAP, learned the hard way and worth keeping: declare text colour on the
   BAND, never on `body`. A custom property resolves on the element that
   consumes it, so `body { color: var(--ink) }` computes exactly once and every
   descendant inherits that one value — which is white type on a white band.
   ========================================================================== */

/* --- faces ---------------------------------------------------------------
   Switzer:   licensed locally, shared with legacyaviationgroup.com — the
              only family carrying headline, label, and body type, matching
              Legacy's own system (their DOM sampled 485 Switzer nodes against
              9 for the accent face, i.e. Switzer is effectively everything).
   Ethic New: Legacy's accent face — the single italic word inside a headline
              ("Experience *Luxury* in Private Aviation"). Subset to Latin,
              static Light Italic instance only: 97.9KB source down to 26.3KB.
              Replaces the Newsreader-Italic accent this same role used
              before; Newsreader is dropped entirely now that nothing else on
              the site sets serif type (was 75.2KB for a face used nowhere
              else once headlines moved to Switzer).
   Both self-hosted, no external font request at runtime.
   ------------------------------------------------------------------------ */
@font-face {
  font-family: "Switzer";
  src: url("../assets/fonts/Switzer-Variable.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Ethic New";
  src: url("../assets/fonts/EthicNew-LightItalic.woff2") format("woff2");
  font-weight: 300;
  font-style: italic;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   Metric-matched fallback.

   With font-display: swap, the fallback renders first and Switzer replaces
   it. If their metrics differ, every line of text changes height at that
   moment and the whole page shifts.

   Switzer x-height 0.5310, Arial x-height 0.5186 — size-adjust is target /
   fallback. The Ethic New accent sets single words at most, never a full
   line the layout depends on, so it ships without a matched fallback: a
   generic italic serif standing in for one or two words until it swaps is
   not worth a second size-adjusted @font-face.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Switzer Fallback";
  src: local("Arial"), local("Helvetica Neue"), local("Helvetica");
  size-adjust: 102.4%;       /* 0.5310 / 0.5186 */
  ascent-override: 95.7%;    /* 0.9800 / 1.024  */
  descent-override: 24.4%;   /* 0.2500 / 1.024  */
  line-gap-override: 8.8%;   /* 0.0900 / 1.024  */
}

:root {
  color-scheme: dark;

  /* ---------------------------------------------------------------------
     Raw palette. PMG's own — unchanged, and not to be re-derived from a
     reference site again. Five values and white.
     --------------------------------------------------------------------- */
  --c-ink:      #14110E;  /* warm near-black: primary dark ground and dark type */
  --c-ink-2:    #1B1714;  /* raised dark surface */
  --c-ink-3:    #241F1A;  /* highest dark surface, hover states */
  --c-paper:    #F5F2EB;  /* warm off-white: primary light ground */
  --c-paper-2:  #EBE6DC;  /* raised light surface, rules */
  --c-white:    #FFFFFF;
  /* Sampled directly from PMG's own logo file (the chevrons measure #9C8679
     across every opaque pixel). The two tints are the same hue and
     saturation — hsl(22.3, 15%, L) — moved only in lightness until each one
     passes AA:
       -l  L=70%  8.92:1 on --c-ink, 9.32:1 on --c-deep
       -d  L=36%  6.02:1 on --c-paper
     The brand colour itself is 3.08:1 on paper and must never carry text
     there; as a FILL under near-black type it is 5.46:1, which passes. */
  --c-bronze:   #9C8679;  /* PMG's own accent — brand equity, kept exactly */
  /* Same value as --c-bronze, as bare channels, so a translucent wash can be
     written rgb(var(--accent-rgb) / 0.12) instead of repeating the literal. */
  --accent-rgb: 156 134 121;
  --accent-dk-rgb: 106 88 78;   /* --c-bronze-d, for washes on light grounds */
  --c-bronze-l: #BEB0A7;  /* accent type on dark grounds */
  --c-bronze-d: #6A584E;  /* accent type on light grounds */

  /* ---------------------------------------------------------------------
     Semantic tokens — dark ground is the default.
     --------------------------------------------------------------------- */
  --ground:      var(--c-ink);
  --ink:         #FFFFFF;
  --body:        rgb(255 255 255 / 0.70);
  --micro:       rgb(255 255 255 / 0.56);
  --faint:       rgb(255 255 255 / 0.38);
  --accent:      var(--c-bronze-l);
  --accent-fill: var(--c-bronze);
  --line:        rgb(255 255 255 / 0.13);
  --line-soft:   rgb(255 255 255 / 0.07);
  --line-accent: rgb(var(--accent-rgb) / 0.42);
  --surface:     var(--c-ink-2);
  --surface-hi:  var(--c-ink-3);

  /* Button: solid bronze with dark type reads 6.4:1 on either ground. */
  --btn-bg:      var(--c-bronze);
  --btn-ink:     var(--c-ink);
  --btn-bg-hi:   #A8958A;

  /* ---------------------------------------------------------------------
     Type. Switzer carries the entire scale — headlines included, matching
     Legacy's system. "Ethic New" italic sets one accent word per heading at
     most, the same discipline the old Newsreader-italic accent followed,
     just a different face.
     --------------------------------------------------------------------- */
  --display: "Switzer", "Switzer Fallback", -apple-system, BlinkMacSystemFont,
             "Helvetica Neue", Arial, sans-serif;
  --accent-face: "Ethic New", Georgia, "Times New Roman", serif;
  --sans:  "Switzer", "Switzer Fallback", -apple-system, BlinkMacSystemFont,
           "Helvetica Neue", Arial, sans-serif;

  --t-hero:    clamp(2.75rem, 1.45rem + 5.4vw, 6.25rem);
  --t-h1:      clamp(2.25rem, 1.55rem + 2.9vw, 4rem);
  --t-h2:      clamp(1.75rem, 1.35rem + 1.75vw, 2.75rem);
  --t-h3:      clamp(1.1875rem, 1.09rem + 0.42vw, 1.4375rem);
  --t-plate:   clamp(1.5rem, 1.15rem + 1.5vw, 2.375rem);
  --t-stat:    clamp(2.5rem, 1.7rem + 3.2vw, 4.5rem);
  --t-lede:    clamp(1.0625rem, 1.0rem + 0.34vw, 1.3125rem);
  --t-body:    1.0625rem;
  --t-small:   0.9375rem;
  --t-micro:   0.8125rem;
  --t-label:   0.6875rem;

  --lh-tight:  1.06;
  --lh-head:   1.14;
  --lh-body:   1.62;
  --tr-label:  0.17em;   /* eyebrow tracking */
  --tr-tight:  -0.022em; /* display tracking — matches Legacy's own h2/h3 ratio (-2.2%) */
  --tr-word:   0.19em;   /* the logo wordmark is set very wide; this matches it */

  /* ---------------------------------------------------------------------
     Space. A single scale; nothing off-scale anywhere in styles.css.
     --------------------------------------------------------------------- */
  --s1: 0.25rem;  --s2: 0.5rem;   --s3: 0.75rem;  --s4: 1rem;
  --s5: 1.5rem;   --s6: 2rem;     --s7: 3rem;     --s8: 4rem;
  --s9: 6rem;     --s10: 8rem;    --s11: 10rem;   --s12: 13rem;

  /* Grid and metrics. */
  --wrap:    1300px;
  --wrap-nr: 1060px;  /* narrow measure for editorial pages */
  --measure: 62ch;
  --gutter:  clamp(1.25rem, 4.5vw, 5.5rem);
  --band:    clamp(4.5rem, 8vw, 9rem);   /* vertical band padding */
  --nav-h:   76px;
  /* Cards stay near-square — Legacy's own photo grid and fact panels carry
     no visible rounding. Full pill is reserved for interactive controls
     (buttons, the nav CTA), matching Legacy's 999px button radius exactly
     rather than applying one radius everywhere. */
  --r:       2px;
  --r-sm:    4px;
  --r-pill:  999px;

  /* Motion. One easing curve, three durations. */
  --ease:   cubic-bezier(0.22, 0.68, 0.16, 1);
  --dur-s:  0.28s;
  --dur-m:  0.52s;
  --dur-l:  0.88s;
}

/* --------------------------------------------------------------------------
   Light ground. The bronze darkens to #6A584E because the brand colour
   measures only 3.08:1 on paper and fails AA for type. It stays #9C8679 for
   FILLS, where the type sitting on it is near-black.
   -------------------------------------------------------------------------- */
.band--light {
  --ground:      var(--c-paper);
  --ink:         var(--c-ink);
  --body:        rgb(20 17 14 / 0.74);
  --micro:       rgb(20 17 14 / 0.60);
  --faint:       rgb(20 17 14 / 0.40);
  --accent:      var(--c-bronze-d);
  --line:        rgb(20 17 14 / 0.14);
  --line-soft:   rgb(20 17 14 / 0.07);
  --line-accent: rgb(var(--accent-dk-rgb) / 0.34);
  --surface:     var(--c-white);
  --surface-hi:  var(--c-paper-2);
  background: var(--ground);
  color: var(--body);
}

/* A second light ground, one step warmer, so two light bands can sit next to
   each other without the seam disappearing. */
.band--warm {
  --surface: var(--c-white);
  background: var(--c-paper-2);
}

.band--dark {
  --ground: var(--c-ink);
  background: var(--ground);
  color: var(--body);
}

/* Deepest ground, for the hero and the closing call to action. Lifted off
   near-black: at #0D0B09 a full-width band reads as a hole in the page. */
.band--deep {
  --ground: #17130F;
  background: var(--ground);
  color: var(--body);
}

/* ==========================================================================
   Pinnacle Management Group — components
   Reads only the semantic tokens in tokens.css. No component knows which
   ground it is on.
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + var(--s5));
  /* `clip`, not `hidden`. `overflow-x: hidden` promotes the element to a
     scroll container, which breaks position: sticky inside it and hands the
     scroll position to the wrong element. `clip` just clips. */
  overflow-x: clip;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--c-ink);
  font-family: var(--sans);
  font-size: var(--t-body);
  font-weight: 350;
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
body.is-locked { overflow: hidden; }

img, picture, video, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; }

/* Focus: always visible, never a browser default ring on a dark ground. */
:focus-visible {
  outline: 2px solid var(--accent-fill);
  outline-offset: 3px;
}
.skip {
  position: absolute; left: var(--s4); top: -100vh; z-index: 200;
  background: var(--c-bronze); color: var(--c-ink);
  padding: var(--s3) var(--s5); font-size: var(--t-micro);
  font-weight: 500; letter-spacing: 0.04em; text-decoration: none;
}
.skip:focus { top: var(--s4); }

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

.band { padding-block: var(--band); position: relative; }
.band--tight { padding-block: calc(var(--band) * 0.62); }
.band--flush-t { padding-top: 0; }
.band--flush-b { padding-bottom: 0; }

/* The one decorative device on the site: a hairline that fades from the
   accent at its midpoint. Used to separate bands, never as ornament. */
.rule {
  height: 1px; border: 0; background: var(--line);
}

/* 12-column grid. Everything on the site aligns to it. */
.grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--s6) var(--s5); }
.c-3 { grid-column: span 3; } .c-4 { grid-column: span 4; } .c-5 { grid-column: span 5; }
.c-6 { grid-column: span 6; } .c-7 { grid-column: span 7; } .c-8 { grid-column: span 8; }
.c-12 { grid-column: span 12; }
.off-1 { grid-column-start: 2; }

@media (max-width: 900px) {
  .grid { gap: var(--s6) var(--s4); }
  .c-3, .c-4, .c-5 { grid-column: span 6; }
  .c-6, .c-7, .c-8 { grid-column: span 12; }
  .off-1 { grid-column-start: auto; }
}
@media (max-width: 560px) {
  .c-3, .c-4, .c-5 { grid-column: span 12; }
}

/* Main column plus aside.

   This used to be built from .c-7 + .c-4 on the 12-column grid, which broke
   between 561px and 900px: at that range .c-7 collapses to full width but .c-4
   only collapses to half, so the aside sat in a ~270px column setting its prose
   one word per line. The span classes are right for grids of peers and wrong
   for a pair with different jobs, so a pair gets its own layout. */
.split {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
  gap: var(--s7) var(--s9);
  align-items: start;
}
@media (max-width: 900px) {
  .split { grid-template-columns: 1fr; gap: var(--s8); }
}

/* --------------------------------------------------------------------------
   Type
   -------------------------------------------------------------------------- */
.eyebrow {
  display: block;
  /* Also used on h2 (see eyebrowH in pages.mjs), so it has to neutralise the
     heading defaults rather than assume it is a span. */
  font-size: var(--t-label);
  margin-top: 0;
  font-family: var(--sans);
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--s5);
}

.display, .h1, .h2 {
  font-family: var(--display);
  font-weight: 200;
  letter-spacing: var(--tr-tight);
  color: var(--ink);
  text-wrap: balance;
}
.display { font-size: var(--t-hero); line-height: var(--lh-tight); }
.h1 { font-size: var(--t-h1); line-height: var(--lh-head); }
.h2 { font-size: var(--t-h2); line-height: var(--lh-head); }

/* h3 is sans — it labels rather than states. Sentence case, not uppercase. */
.h3 {
  font-family: var(--sans);
  font-size: var(--t-h3);
  font-weight: 450;
  line-height: 1.32;
  letter-spacing: -0.008em;
  color: var(--ink);
}

/* The italic accent face is used once per heading at most, on a single word,
   to carry emphasis without changing size or weight — Legacy's own device,
   in Legacy's own face rather than a fake-italic slant of Switzer (which
   ships no italic style). */
.display em, .h1 em, .h2 em {
  font-family: var(--accent-face);
  font-style: italic;
  font-weight: 300;
  color: var(--accent);
}

.lede {
  font-size: var(--t-lede);
  line-height: 1.58;
  font-weight: 350;
  color: var(--body);
  max-width: 54ch;
}
.prose { max-width: var(--measure); color: var(--body); }
.prose + .prose { margin-top: var(--s5); }
.small { font-size: var(--t-small); color: var(--body); }
.micro { font-size: var(--t-micro); color: var(--micro); line-height: 1.55; }

/* Editorial pull statement. Serif, large, no quotation marks — the scale
   already tells the reader it is a statement. */
.plate {
  font-family: var(--display);
  font-size: var(--t-plate);
  font-weight: 200;
  line-height: 1.3;
  letter-spacing: -0.014em;
  color: var(--ink);
  max-width: 30ch;
  text-wrap: balance;
}
.plate--wide { max-width: 46ch; }

/* --------------------------------------------------------------------------
   Buttons and links
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: var(--s3);
  padding: 0.95rem var(--s6);
  border: 1px solid transparent; border-radius: var(--r-pill);
  /* Pill shape and sizing match Legacy's own button (lag-systems.com); the
     fill and ink stay PMG's — bronze background, near-black text, 6.4:1. */
  font-size: 0.9375rem; font-weight: 600; letter-spacing: 0.02em;
  text-transform: none; text-decoration: none; cursor: pointer;
  transition: background var(--dur-s) var(--ease), border-color var(--dur-s) var(--ease),
              color var(--dur-s) var(--ease);
}
.btn__arrow { transition: transform var(--dur-s) var(--ease); }
.btn:hover .btn__arrow, .btn:focus-visible .btn__arrow { transform: translateX(4px); }

.btn--solid { background: var(--btn-bg); color: var(--btn-ink); }
.btn--solid:hover, .btn--solid:focus-visible { background: var(--btn-bg-hi); }

.btn--ghost { border-color: var(--line); color: var(--ink); }
.btn--ghost:hover, .btn--ghost:focus-visible {
  border-color: var(--accent-fill); color: var(--ink); background: rgb(var(--accent-rgb) / 0.09);
}

.actions { display: flex; flex-wrap: wrap; gap: var(--s4); align-items: center; }
/* Below this width two buttons never fit side by side, so stack them to a
   common width instead of leaving a ragged pair. */
@media (max-width: 430px) {
  .actions { flex-direction: column; align-items: stretch; }
  .actions .btn { justify-content: space-between; }
}

/* Inline link: the underline is drawn, so it can animate from the left. */
.link {
  display: inline-flex; align-items: center; gap: var(--s2);
  font-size: var(--t-micro); font-weight: 500; letter-spacing: 0.05em;
  text-transform: uppercase; text-decoration: none; color: var(--ink);
  padding-block: 1px 3px; position: relative;
}
.link::after {
  content: ""; position: absolute; left: 0; bottom: 1px; height: 1px; width: 100%;
  background: var(--accent-fill); transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur-m) var(--ease);
}
.link:hover::after, .link:focus-visible::after { transform: scaleX(1); }
.link-arrow { display: inline-block; transition: transform var(--dur-s) var(--ease); }
.link:hover .link-arrow, .link:focus-visible .link-arrow { transform: translateX(4px); }

/* --------------------------------------------------------------------------
   Navigation
   -------------------------------------------------------------------------- */
.nav {
  position: fixed; inset: 0 0 auto; z-index: 100;
  height: var(--nav-h);
  background: rgb(13 11 9 / 0);
  /* height is intentionally NOT transitioned: animating it forces layout on
     every scroll-state toggle. The 12px snap from 76px to 64px reads as part
     of the same beat as the background/blur fade, not as a separate jump. */
  transition: background var(--dur-m) var(--ease), border-color var(--dur-m) var(--ease);
  border-bottom: 1px solid transparent;
}
.nav.is-stuck {
  height: 64px;
  background: rgb(13 11 9 / 0.92);
  backdrop-filter: blur(14px) saturate(140%);
  border-bottom-color: var(--line-soft);
}
.nav.is-open { background: var(--c-ink); backdrop-filter: none; }

/* Burger left, brand centered, CTA right — Legacy's own nav shape rather
   than a left-logo-plus-inline-links bar. The burger is the ONLY way into
   the rest of the site now; there is no hover mega panel, matching
   lag-systems.com, which has no inline dropdown on any viewport either. */
.nav__inner {
  height: 100%; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter);
}

.brand { display: flex; align-items: center; gap: var(--s4); text-decoration: none; justify-self: center; min-height: 24px; }
.brand .logo { width: 48px; height: auto; fill: var(--c-bronze); transition: fill var(--dur-s) var(--ease); }
.brand:hover .logo { fill: var(--c-bronze-l); }
/* The real lockup sets the wordmark in a wide-tracked geometric sans, in
   white, stacked in three lines beside the chevrons. One line at this size
   with matching tracking is the closest honest rendition in the site's own
   typeface; the footer uses the stacked form. If PMG supplies the vector
   lockup, swap it in here and delete this rule. */
.brand__name {
  font-size: 0.9375rem; font-weight: 500;
  letter-spacing: var(--tr-word); text-transform: uppercase;
  color: #FFFFFF; white-space: nowrap;
}
.brand__short { display: none; }

/* Retired: the horizontal inline link row. Every route now lives behind the
   burger, in .drawer, matching Legacy's own single-surface navigation. */

/* Plain text in the bar — no pill, no border. A drawn underline on hover is
   the same device .link uses in page content; the arrow nudges forward the
   same way. This is the bar's own control, not a page action that wandered
   up into the nav, so it stays quieter than the solid buttons in the hero. */
.nav__cta {
  /* Grid items stretch to fill their cell by default — without this the
     control fills the whole right-hand column instead of sizing to its text. */
  justify-self: end;
  display: inline-flex; align-items: center; gap: var(--s2);
  font-size: var(--t-micro); font-weight: 500; letter-spacing: 0.05em;
  text-transform: uppercase; text-decoration: none; color: #FFFFFF;
  padding-block: 1px 3px; position: relative;
}
.nav__cta::after {
  content: ""; position: absolute; left: 0; bottom: 1px; height: 1px; width: 100%;
  background: var(--c-bronze-l); transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur-m) var(--ease);
}
.nav__cta:hover::after, .nav__cta:focus-visible::after { transform: scaleX(1); }
.nav__cta:hover, .nav__cta:focus-visible { color: var(--c-bronze-l); }
.nav__cta .btn__arrow { display: inline-block; transition: transform var(--dur-s) var(--ease); }
.nav__cta:hover .btn__arrow, .nav__cta:focus-visible .btn__arrow { transform: translateX(4px); }
.nav__cta-mini { display: none; }

.nav__burger {
  display: block; justify-self: start; background: none; border: 0; cursor: pointer;
  width: 40px; height: 40px; padding: 9px 6px;
}
.nav__burger span {
  display: block; height: 1px; background: #FFFFFF; margin: 5px 0;
  transition: transform var(--dur-m) var(--ease), opacity var(--dur-s) var(--ease);
}
.nav.is-open .nav__burger span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav.is-open .nav__burger span:nth-child(2) { opacity: 0; }
.nav.is-open .nav__burger span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* The navigation surface. A warm diagonal wash off the top corner — the same
   device .hold uses for an empty state — keeps the full-bleed panel from
   reading as a flat modal dropped on top of the page. */
.drawer {
  position: fixed; inset: var(--nav-h) 0 0; z-index: 98;
  background:
    linear-gradient(160deg, rgb(var(--accent-rgb) / 0.10), rgb(var(--accent-rgb) / 0) 55%),
    var(--c-ink);
  padding: var(--s7) 0 var(--s8);
  overflow-y: auto; display: none;
}
.drawer.is-open { display: block; }

.drawer__grid { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--s8) var(--s9); align-items: start; }
.drawer__primary { min-width: 0; }

.drawer__link {
  display: flex; align-items: baseline; gap: var(--s5);
  padding: var(--s4) 0; border-bottom: 1px solid var(--line-soft);
  text-decoration: none; color: #FFFFFF;
  font-family: var(--display); font-size: clamp(1.75rem, 1.3rem + 2vw, 2.75rem); font-weight: 200;
  transition: color var(--dur-s) var(--ease), transform var(--dur-m) var(--ease);
}
.drawer__link:hover, .drawer__link:focus-visible { color: var(--c-bronze-l); transform: translateX(var(--s3)); }
.drawer__link[aria-current="page"] { color: var(--c-bronze-l); }
/* The index number leads, large enough to carry its own weight against the
   headline-scale label beside it, rather than sitting as a faint afterthought. */
.drawer__link .idx {
  order: -1; font-family: var(--display); font-size: 1.0625rem; font-weight: 300;
  color: var(--c-bronze); letter-spacing: 0; min-width: 2ch;
}

/* Sector index — set apart from the primary list with its own label and a
   tighter, denser grid, so five headline-scale routes and eleven sector
   names don't compete for the same visual weight. */
.drawer__aside { padding-top: var(--s2); border-left: 1px solid var(--line-soft); padding-left: var(--s7); }
.drawer__aside .eyebrow { color: var(--c-bronze-l); }
.drawer__sub { padding: var(--s2) 0 var(--s6); display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3) var(--s5); }
.drawer__sub a {
  font-size: var(--t-small); color: rgb(255 255 255 / 0.66); text-decoration: none;
  padding-block: 2px; transition: color var(--dur-s) var(--ease);
}
.drawer__sub a:hover, .drawer__sub a:focus-visible { color: #FFFFFF; }
.drawer__foot {
  margin-top: var(--s6); padding-top: var(--s6); border-top: 1px solid var(--line-soft);
  display: grid; gap: var(--s4);
}
@media (max-width: 760px) {
  .drawer__grid { grid-template-columns: 1fr; gap: var(--s7); }
  .drawer__aside { border-left: 0; padding-left: 0; }
  .drawer__link { font-size: 1.75rem; }
}

/* The CTA stays in the bar at every width — hiding it behind the burger
   put the one action the site exists to produce two taps away. The label
   shortens under the wordmark's own squeeze point; the accessible name on
   the anchor does not. */
@media (max-width: 640px) {
  .brand__name { display: none; }
  .nav__cta-full { display: none; }
  .nav__cta-mini { display: inline; }
  .brand__short {
    display: block; font-size: 0.6875rem; font-weight: 500; color: #FFFFFF;
    letter-spacing: var(--tr-word); text-transform: uppercase;
  }
}
@media (max-width: 360px) {
  .brand__short { display: none; }
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative; min-height: min(94vh, 900px);
  display: flex; align-items: flex-end;
  padding-top: calc(var(--nav-h) + var(--s7));
  padding-bottom: var(--s8);
  overflow: hidden; isolation: isolate;
}
.hero__media { position: absolute; inset: 0; z-index: -2; }
.hero__media .frame, .hero__media img { width: 100%; height: 100%; border-radius: 0; }
.hero__media img { object-fit: cover; object-position: center 42%; }
/* Two-stop scrim: a vertical wash for type legibility at the bottom, and a
   flat tint so the photograph never competes with the headline. */
.hero__media::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(to top, rgb(13 11 9 / 0.94) 0%, rgb(13 11 9 / 0.74) 36%, rgb(13 11 9 / 0.34) 70%, rgb(13 11 9 / 0.44) 100%),
    /* The left column is where the type lives, and the photograph has a bright
       fuselage running through exactly that band. This keeps the body copy off
       it without flattening the right-hand side of the image. */
    /* Held wider and stronger than a darker photograph would need: the hero is
       a cream-and-pale-wood cabin interior, so the type has to make its own
       ground rather than borrow one from the image. */
    linear-gradient(to right, rgb(23 19 15 / 0.82) 0%, rgb(23 19 15 / 0.60) 40%, rgb(23 19 15 / 0.20) 78%);
}
.hero__inner { position: relative; z-index: 1; width: 100%; }
.hero .display { max-width: 20ch; color: #FFFFFF; }
.hero .lede { color: rgb(255 255 255 / 0.8); margin-top: var(--s5); max-width: 52ch; }
.hero .actions { margin-top: var(--s6); }
.hero__meta {
  display: flex; flex-wrap: wrap; gap: var(--s5); align-items: center;
  margin-top: var(--s7); padding-top: var(--s5);
  border-top: 1px solid rgb(255 255 255 / 0.14);
  font-size: var(--t-label); letter-spacing: var(--tr-label);
  text-transform: uppercase; color: rgb(255 255 255 / 0.6);
}
.hero__meta span { display: inline-flex; align-items: center; gap: var(--s3); }
.hero__meta span + span::before {
  content: ""; width: 3px; height: 3px; border-radius: 50%;
  background: var(--c-bronze); margin-right: var(--s2);
}

/* On a narrow screen the hero's text stacks, which makes the section tall —
   and a bottom-weighted scrim stretched over 900px of height swallows most of
   the photograph, leaving what looks like a picture sitting on a black box.
   Two changes: let the hero hug its content, and move the opaque band down. */
@media (max-width: 700px) {
  .hero {
    min-height: min(80vh, 660px);
    padding-top: calc(var(--nav-h) + var(--s6));
    padding-bottom: var(--s7);
  }
  /* The top stop is raised as well as the bottom: on mobile the eyebrow sits
     high in the frame, which on this photograph is the bright window. */
  .hero__media::after {
    background:
      linear-gradient(to top, rgb(13 11 9 / 0.93) 0%, rgb(13 11 9 / 0.82) 26%,
                              rgb(13 11 9 / 0.60) 58%, rgb(13 11 9 / 0.62) 100%);
  }
  .hero__media img { object-position: center 34%; }
  .hero .display { max-width: none; }
  /* The separator is drawn before every item after the first, so once the row
     wraps a dot can land at the start of a line. Drop them and let the gap
     carry the separation. */
  .hero__meta { gap: var(--s2) var(--s5); }
  .hero__meta span + span::before { display: none; }
}

/* Interior page hero — shallower, always over a photograph or flat ground. */
.phero {
  position: relative; padding-top: calc(var(--nav-h) + var(--s8));
  padding-bottom: var(--s8); overflow: hidden; isolation: isolate;
  background: #0D0B09;
}
.phero--photo { min-height: 62vh; display: flex; align-items: flex-end; }
.phero__media { position: absolute; inset: 0; z-index: -2; }
.phero__media .frame, .phero__media img { width: 100%; height: 100%; border-radius: 0; }
/* --crop is set per company on the wrapper; the default keeps the horizon
   slightly above centre, which suits every current photograph. */
.phero__media img { object-fit: cover; object-position: var(--crop, center 45%); }

/* Background video, same box as the photo it can replace: absolutely
   positioned to fill .phero__media, cropped the same way. */
.bg-video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: var(--crop, center 45%);
  background: var(--c-ink-2);  /* shows through until the poster decodes */
}
.phero__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top, rgb(23 19 15 / 0.95) 0%, rgb(23 19 15 / 0.72) 46%, rgb(23 19 15 / 0.52) 100%);
}
.phero__inner { position: relative; z-index: 1; width: 100%; }
.phero .h1 { color: #FFFFFF; max-width: 26ch; }
.phero .lede { color: rgb(255 255 255 / 0.78); margin-top: var(--s5); }

/* Interior photo heroes need the same treatment as the home hero at narrow
   widths, and for the same reason: a bottom-weighted scrim stretched over 62vh
   of a tall phone viewport turns the photograph into a strip above a black box. */
@media (max-width: 700px) {
  .phero--photo { min-height: min(58vh, 520px); }
  .phero {
    padding-top: calc(var(--nav-h) + var(--s6));
    padding-bottom: var(--s7);
  }
  .phero__media::after {
    background:
      linear-gradient(to top, rgb(13 11 9 / 0.93) 0%, rgb(13 11 9 / 0.80) 30%,
                              rgb(13 11 9 / 0.58) 66%, rgb(13 11 9 / 0.58) 100%);
  }
  .phero .h1 { max-width: none; }
}

/* 404. Sized to its content rather than to the viewport — a near-empty page
   given 62vh of height reads as broken rather than as spacious. */
.phero--404 { padding-bottom: var(--s9); }

/* Breadcrumb */
.crumb {
  display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center;
  font-size: var(--t-label); letter-spacing: var(--tr-label); text-transform: uppercase;
  color: rgb(255 255 255 / 0.64); margin-bottom: var(--s5); list-style: none; padding: 0;
}
.crumb a { text-decoration: none; color: inherit; display: inline-block; padding-block: 5px; }
.crumb a:hover { color: #FFFFFF; }
.crumb li + li::before { content: "/"; margin-right: var(--s3); color: rgb(255 255 255 / 0.3); }

/* --------------------------------------------------------------------------
   Figures
   -------------------------------------------------------------------------- */
.frame { position: relative; overflow: hidden; background: var(--c-ink-2); margin: 0; border-radius: var(--r); }
.frame img { width: 100%; height: 100%; object-fit: cover; }
.frame--43  { aspect-ratio: 4 / 3; }
.frame--169 { aspect-ratio: 16 / 9; }
.frame--54  { aspect-ratio: 5 / 4; }
.frame--32  { aspect-ratio: 3 / 2; }
.frame--11  { aspect-ratio: 1 / 1; }
.frame--tall { aspect-ratio: 4 / 5; }

/* --------------------------------------------------------------------------
   Statistics
   -------------------------------------------------------------------------- */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line); }
.stat { background: var(--ground); padding: var(--s6) var(--s5) var(--s5); }
.stat__v {
  font-family: var(--display); font-size: var(--t-stat); font-weight: 200;
  line-height: 1; letter-spacing: -0.03em; color: var(--ink);
  font-variant-numeric: lining-nums tabular-nums;
}
.stat__v .suffix { color: var(--accent); }
.stat__l {
  display: block; margin-top: var(--s4);
  font-size: var(--t-micro); font-weight: 500; color: var(--ink);
  letter-spacing: 0.01em;
}
.stat__n { display: block; margin-top: var(--s2); font-size: var(--t-micro); color: var(--micro); }
@media (max-width: 900px) { .stats { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 460px) { .stats { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   Section headers
   -------------------------------------------------------------------------- */
.shead { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: var(--s6) var(--s7); align-items: end; }
.shead__aside { align-self: end; }
.shead + * { margin-top: var(--s8); }
@media (max-width: 900px) { .shead { grid-template-columns: 1fr; } .shead + * { margin-top: var(--s7); } }

/* --------------------------------------------------------------------------
   Process 01–04
   -------------------------------------------------------------------------- */
.steps { border-top: 1px solid var(--line); }
.step {
  display: grid; grid-template-columns: 5.5rem minmax(0, 1fr) minmax(0, 1.15fr);
  gap: var(--s5) var(--s7);
  padding-block: var(--s7);
  border-bottom: 1px solid var(--line);
  transition: background var(--dur-m) var(--ease);
}
.step:hover { background: rgb(var(--accent-rgb) / 0.045); }
.step__n {
  font-family: var(--display); font-size: 1.75rem; font-weight: 200;
  color: var(--accent); line-height: 1; font-variant-numeric: lining-nums;
}
.step__owner {
  display: block; margin-top: var(--s3);
  font-size: var(--t-label); letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--micro);
}
.step__lede {
  font-family: var(--display); font-size: var(--t-h3); font-weight: 300;
  line-height: 1.34; color: var(--ink); letter-spacing: -0.01em;
}
.step__points { list-style: none; padding: 0; margin-top: var(--s5); display: grid; gap: var(--s3); }
.step__points li {
  font-size: var(--t-micro); color: var(--micro);
  padding-left: var(--s4); position: relative;
}
.step__points li::before {
  content: ""; position: absolute; left: 0; top: 0.62em;
  width: 4px; height: 1px; background: var(--accent-fill);
}
@media (max-width: 1040px) {
  .step { grid-template-columns: 4rem minmax(0, 1fr); }
  .step__body { grid-column: 2; }
}
@media (max-width: 620px) {
  .step { grid-template-columns: 1fr; gap: var(--s4); }
  .step__body { grid-column: 1; }
}

/* --------------------------------------------------------------------------
   Criteria
   -------------------------------------------------------------------------- */
.metrics { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line); }
.metric { background: var(--ground); padding: var(--s5); }
.metric__k {
  display: block; font-size: var(--t-label); letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--accent); margin-bottom: var(--s3);
}
.metric__v { font-family: var(--display); font-size: 1.375rem; font-weight: 300; color: var(--ink); line-height: 1.24; }
@media (max-width: 900px) { .metrics { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 430px) { .metrics { grid-template-columns: 1fr; } }

.defs { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px; background: var(--line); }
.defs--3 { grid-template-columns: repeat(3, 1fr); }
.def { background: var(--ground); padding: var(--s6) var(--s5); }
.def__t { font-size: var(--t-h3); font-weight: 450; color: var(--ink); line-height: 1.3; }
.def__d { margin-top: var(--s3); font-size: var(--t-small); color: var(--body); }
@media (max-width: 900px) { .defs, .defs--3 { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   Portfolio
   -------------------------------------------------------------------------- */
/* Company names inside a sector, set as prose rather than as cards. Three of
   the nine have live sites and link out; the rest are plain text. Keeping them
   visually identical apart from the underline means the list does not look
   half-broken where a company has no site. */
.colinks { display: grid; gap: var(--s3); }
.colink {
  font-family: var(--display); font-size: 1.1875rem; font-weight: 300;
  letter-spacing: -0.01em; color: var(--ink); text-decoration: none;
  display: inline-block; width: fit-content;
}
.colink:not(.colink--plain) {
  border-bottom: 1px solid var(--line-accent);
  transition: border-color var(--dur-s) var(--ease);
}
.colink:not(.colink--plain):hover,
.colink:not(.colink--plain):focus-visible { border-bottom-color: var(--accent-fill); }

/* Sector rail — horizontal on desktop, scroll-snapped on mobile */
.rail { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line); }
.rcard {
  position: relative; display: block; text-decoration: none; overflow: hidden;
  min-height: 340px; background: var(--c-ink-2); isolation: isolate;
}
/* The rail is a 1px-gap grid, so only its outer corners round. */
.rail { border-radius: var(--r); overflow: hidden; }
.stats, .metrics, .defs, .factbar, .routes { border-radius: var(--r); overflow: hidden; }
.rcard__media { position: absolute; inset: 0; z-index: -2; }
.rcard__media img { width: 100%; height: 100%; object-fit: cover; filter: saturate(0.8); transition: transform var(--dur-l) var(--ease); }
.rcard:hover .rcard__media img { transform: scale(1.04); }
.rcard__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top, rgb(13 11 9 / 0.95) 6%, rgb(13 11 9 / 0.55) 52%, rgb(13 11 9 / 0.32) 100%);
  transition: background var(--dur-m) var(--ease);
}
.rcard:hover .rcard__media::after {
  background: linear-gradient(to top, rgb(13 11 9 / 0.97) 6%, rgb(13 11 9 / 0.62) 52%, rgb(13 11 9 / 0.34) 100%);
}
.rcard__body { position: relative; z-index: 1; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; padding: var(--s6) var(--s5); }
.rcard__sector {
  display: block; font-size: var(--t-label); letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--c-bronze-l); margin-bottom: var(--s3);
}
.rcard__name { font-family: var(--display); font-size: 1.5rem; font-weight: 300; color: #FFFFFF; line-height: 1.16; }
.rcard__sum { margin-top: var(--s3); font-size: var(--t-small); color: rgb(255 255 255 / 0.72); }
.rcard__count {
  margin-top: var(--s4); font-size: var(--t-label); letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--c-bronze-l);
}
@media (max-width: 980px) { .rail { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .rail { grid-template-columns: 1fr; } .rcard { min-height: 280px; } }

/* --------------------------------------------------------------------------
   Company detail
   -------------------------------------------------------------------------- */
.factbar { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line); }
.fact { background: var(--ground); padding: var(--s5); }
.fact__k { display: block; font-size: var(--t-label); letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--accent); margin-bottom: var(--s2); }
.fact__v { font-size: var(--t-small); color: var(--ink); }
.fact__v a { text-decoration: none; border-bottom: 1px solid var(--line-accent); }
.fact__v a:hover { border-bottom-color: var(--accent-fill); }
@media (max-width: 900px) { .factbar { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 430px) { .factbar { grid-template-columns: 1fr; } }

.bullets { list-style: none; padding: 0; display: grid; gap: var(--s4); }
.bullets li { position: relative; padding-left: var(--s5); font-size: var(--t-small); color: var(--body); }
.bullets li::before {
  content: ""; position: absolute; left: 0; top: 0.65em;
  width: 8px; height: 1px; background: var(--accent-fill);
}

/* --------------------------------------------------------------------------
   Empty states — Team, Insights, Case studies.
   The architecture is built and visible; no fabricated content occupies it.
   -------------------------------------------------------------------------- */
.hold {
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: var(--s7) var(--s6);
  background: linear-gradient(160deg, rgb(var(--accent-rgb) / 0.07), rgb(var(--accent-rgb) / 0) 62%);
}
.hold__t { font-family: var(--display); font-size: var(--t-h3); font-weight: 300; color: var(--ink); }
.hold__d { margin-top: var(--s3); font-size: var(--t-small); color: var(--body); max-width: 56ch; }

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */
.form { display: grid; gap: var(--s5); }
.field { display: grid; gap: var(--s2); }
.field > label {
  font-size: var(--t-label); letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--micro);
}
.field input, .field textarea, .field select {
  background: transparent; border: 0; border-bottom: 1px solid var(--line);
  padding: var(--s3) 0; color: var(--ink); font-size: var(--t-body);
  border-radius: 0; transition: border-color var(--dur-s) var(--ease);
}
.field select {
  appearance: none; padding-right: var(--s6);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 10px) calc(50% + 1px), calc(100% - 5px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.field select option { background: var(--c-ink); color: #FFFFFF; }
.band--light .field select option { background: #FFFFFF; color: var(--c-ink); }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none; border-bottom-color: var(--accent-fill);
}
.field input:focus-visible, .field textarea:focus-visible, .field select:focus-visible {
  outline: 2px solid var(--accent-fill); outline-offset: 4px;
}
.field textarea { resize: vertical; min-height: 7rem; }
.field__hint { font-size: var(--t-micro); color: var(--faint); }
.field--row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s5); }
@media (max-width: 620px) { .field--row { grid-template-columns: 1fr; } }
.form__note { font-size: var(--t-micro); color: var(--micro); }

/* Honeypot. Moved off-canvas rather than display:none — some bots skip fields
   that are not rendered at all. */
.hp {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden; pointer-events: none;
}

/* Inline validation. The message sits under the field it belongs to and is
   wired to it with aria-describedby, so a screen reader hears the problem
   when focus lands rather than only in a summary somewhere else. */
.field__err {
  font-size: var(--t-micro); color: #9A4A28; display: none;
  align-items: center; gap: var(--s2);
}
.band--dark .field__err, .band--deep .field__err { color: #E8B4A0; }
.field.is-invalid .field__err { display: flex; }
.field.is-invalid input,
.field.is-invalid select,
.field.is-invalid textarea { border-bottom-color: #9A4A28; }
.band--dark .field.is-invalid input,
.band--dark .field.is-invalid textarea { border-bottom-color: #E8B4A0; }
.form__status { font-size: var(--t-small); min-height: 1.4em; }
.form__status[data-state="err"] { color: #E8B4A0; }
.form__status[data-state="ok"] { color: var(--accent); }
.band--light .form__status[data-state="err"] { color: #9A4A28; }

/* --------------------------------------------------------------------------
   Contact routes
   -------------------------------------------------------------------------- */
.routes { display: grid; gap: 1px; background: var(--line); }
.route { background: var(--ground); padding: var(--s5); display: grid; gap: var(--s2); }
.route__t { font-size: var(--t-h3); font-weight: 450; color: var(--ink); }
.route__d { font-size: var(--t-small); color: var(--body); }

.office { display: grid; gap: var(--s3); }
.office__c { font-family: var(--display); font-size: 1.375rem; font-weight: 300; color: var(--ink); }
.office address { font-style: normal; font-size: var(--t-small); color: var(--body); line-height: 1.7; }

/* --------------------------------------------------------------------------
   Closing call to action
   -------------------------------------------------------------------------- */
.cta { text-align: left; }
.cta .plate { max-width: 34ch; }
.cta .actions { margin-top: var(--s6); }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
.foot { background: #0A0908; padding-block: var(--s8) var(--s6); border-top: 1px solid var(--line-soft); }
.foot__top { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 6fr); gap: var(--s7); }
.foot__brand { display: grid; gap: var(--s4); align-content: start; }
.foot__brand .logo { width: 52px; fill: var(--c-bronze); }
/* Stacked wordmark, echoing the three-line lockup. */
.foot__word {
  font-size: 0.8125rem; font-weight: 500; line-height: 1.9;
  letter-spacing: var(--tr-word); text-transform: uppercase; color: #FFFFFF;
}
.foot__word span { display: block; }
.foot__word sup { font-size: 0.6em; letter-spacing: 0; vertical-align: 0.55em; opacity: 0.7; }
.foot__sig {
  font-family: var(--accent-face); font-style: italic; font-size: 1.125rem;
  font-weight: 300; color: var(--c-bronze-l);
}
.foot__cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s6) var(--s5); }
.foot__h {
  font-size: var(--t-label); letter-spacing: var(--tr-label); text-transform: uppercase;
  color: rgb(255 255 255 / 0.5); margin-bottom: var(--s4); font-weight: 500;
}
.foot__list { list-style: none; padding: 0; display: grid; gap: var(--s2); }
.foot__list a {
  font-size: var(--t-small); color: rgb(255 255 255 / 0.72); text-decoration: none;
  transition: color var(--dur-s) var(--ease);
  /* 19px of line box plus 3px either side clears the 24px minimum in WCAG
     2.5.8 without needing the spacing exception. The list gap drops from 12px
     to 8px so the block keeps the same rhythm. */
  display: inline-block; padding-block: 3px;
}
.foot__list a:hover { color: #FFFFFF; }
.foot__offices { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s5); margin-top: var(--s8); padding-top: var(--s6); border-top: 1px solid var(--line-soft); }
.foot__office-c { font-size: var(--t-micro); font-weight: 500; color: #FFFFFF; margin-bottom: var(--s2); }
.foot__office address { font-style: normal; font-size: var(--t-micro); color: rgb(255 255 255 / 0.56); line-height: 1.7; }
.foot__bot {
  margin-top: var(--s7); padding-top: var(--s5); border-top: 1px solid var(--line-soft);
  display: flex; flex-wrap: wrap; gap: var(--s4) var(--s6); align-items: center; justify-content: space-between;
}
.foot__legal { font-size: var(--t-micro); color: rgb(255 255 255 / 0.44); }
.foot__social { display: flex; gap: var(--s5); list-style: none; padding: 0; }
.foot__social a {
  font-size: var(--t-label); letter-spacing: var(--tr-label); text-transform: uppercase;
  color: rgb(255 255 255 / 0.56); text-decoration: none;
  display: inline-block; padding-block: 5px;
}
.foot__social a:hover { color: #FFFFFF; }
@media (max-width: 900px) {
  .foot__top { grid-template-columns: 1fr; }
  .foot__cols { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .foot__cols, .foot__offices { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   Motion. One reveal, applied by js/main.js via IntersectionObserver.
   Everything degrades to visible if JS never runs — .reveal only becomes
   invisible once the script adds .js-reveal to <html>.
   -------------------------------------------------------------------------- */
.js-reveal .reveal { opacity: 0; transform: translateY(14px); }
.js-reveal .reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity var(--dur-l) var(--ease), transform var(--dur-l) var(--ease);
}
.js-reveal .reveal[data-d="1"].is-in { transition-delay: 0.08s; }
.js-reveal .reveal[data-d="2"].is-in { transition-delay: 0.16s; }
.js-reveal .reveal[data-d="3"].is-in { transition-delay: 0.24s; }

/* Headline mask reveal: each line rides up from behind its own clip.

   The clip box has to be TALLER than the line box or it cuts the descenders
   off. A display face is set here at line-height 1.06 while its own content
   area is about 1.23em tall, so the glyphs already overflow the line box by
   roughly 0.085em top and bottom — and overflow:hidden was slicing the tail
   off every g, y and p in a headline.

   padding-bottom opens the clip box downward and an equal negative
   margin-bottom takes the space back, so the line rhythm is unchanged. The
   start position then has to clear the taller box: 105% of the inner span no
   longer hides it, so the offset goes to 125%. */
/* The container absorbs the last line's padding. A negative margin-bottom on
   the last child pulls the NEXT element up but does not shrink its parent, so
   without this the headline block ends up one padding taller than its own line
   rhythm and everything below it sits 0.2em too low. */
.js-reveal .lines { display: block; margin-bottom: -0.2em; }
.js-reveal .lines .ln {
  display: block;
  overflow: hidden;
  padding-bottom: 0.2em;
  margin-bottom: -0.2em;
}
.js-reveal .lines .ln > span { display: block; transform: translateY(125%); }
.js-reveal .lines.is-in .ln > span {
  transform: none;
  transition: transform 1s var(--ease);
}
.js-reveal .lines.is-in .ln:nth-child(2) > span { transition-delay: 0.07s; }
.js-reveal .lines.is-in .ln:nth-child(3) > span { transition-delay: 0.14s; }
.js-reveal .lines.is-in .ln:nth-child(4) > span { transition-delay: 0.21s; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important; scroll-behavior: auto !important;
  }
  .js-reveal .reveal { opacity: 1; transform: none; }
  .js-reveal .lines .ln > span { transform: none; }
  .rcard:hover .rcard__media img { transform: none; }
}

/* Touch targets. On a fine pointer these links can stay typographically tight;
   on a coarse one a 19px-tall footer link is below the WCAG 2.5.8 minimum and
   simply hard to hit. Scoping the padding to pointer:coarse buys the target
   size without loosening desktop density. */
@media (pointer: coarse) {
  /* At the narrowest widths the brand collapses to the mark alone, which left a
     36x20 hit area. The nav bar has the room; the link takes it. */
  .brand { min-height: 44px; }
  .foot__list { gap: var(--s2); }
  .foot__list a,
  .foot__social a,
  .drawer__sub a { display: inline-block; padding-block: 8px; }
  .crumb a { display: inline-block; padding-block: 6px; }
  .link { padding-block: 7px; }
  .link::after { bottom: 7px; }
}

/* --------------------------------------------------------------------------
   Print. Not an afterthought here: the criteria and the portfolio are exactly
   the pages an intermediary prints or saves to PDF to pass around internally,
   so they have to survive it.
   -------------------------------------------------------------------------- */
@media print {
  .nav, .drawer, .mega, .skip,
  .hero__media, .phero__media,
  .btn, .cta, .foot__social { display: none !important; }

  /* One ground, black on white. The tokens are re-pointed rather than
     overridden per component, so every component follows without a
     print-specific rule of its own. */
  :root, .band--light, .band--dark, .band--deep, .band--warm {
    --ground: #fff;
    --ink: #000;
    --body: #1a1a1a;
    --micro: #444;
    --faint: #666;
    --accent: #4a3f37;
    --accent-fill: #4a3f37;
    --line: #bbb;
    --line-soft: #ddd;
    --line-accent: #999;
    --surface: #fff;
    --surface-hi: #fff;
  }
  body { background: #fff; color: #000; }
  .band, .phero, .hero { padding-block: var(--s5) !important; background: #fff !important; }
  .hero, .phero--photo { min-height: 0 !important; }
  .phero .h1, .hero .display, .phero .lede, .hero .lede, .crumb { color: #000 !important; }
  .hold { background: none !important; }

  /* Nothing that carries a fact should break across a page. */
  .step, .def, .metric, .stat, .fact, .route, .office, .hold {
    break-inside: avoid; page-break-inside: avoid;
  }
  h1, h2, h3, .h1, .h2, .h3 { break-after: avoid; page-break-after: avoid; }

  /* An outbound company URL is useless on paper unless it is printed. */
  main a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.85em; color: #555; }
  main a[href^="mailto:"]::after { content: ""; }

  .foot { border-top: 1px solid #bbb; }
  .frame { border: 1px solid #ddd; }
}
