@charset "UTF-8";
/* ==========================================================================
   Heights Consulting Group — "Elevation"
   --------------------------------------------------------------------------
   One stylesheet. No framework, no build step, no dependency.

     1.  Tokens
     2.  Surfaces
     3.  Fonts
     4.  Reset and base
     5.  Layout primitives
     6.  Typography
     7.  Controls
     8.  Motion
     9.  Chrome
    10.  Footer
    11.  Homepage chapters
    12.  Utilities
    13.  Material
    14.  The page figure
    15.  Page components, continued
    16.  Field photography
    17.  The publication index
    18.  Responsive

   ART DIRECTION
   -------------
   The Heights mark is a hard-edged summit: two ascending strokes meeting at a
   point. The system takes three primitives from it and uses nothing else.

     THE RULE      A hairline. Sections are divided by lines, not by boxes.
                   Nothing on this site is a card with a border on four sides.
     THE ASCENT    An indent that steps rightward down a sequence, so a list
                   reads as a climb rather than as rows.
     THE FIELD     Flat colour, edge to edge. Depth comes from changing the
                   field, never from a shadow under a rectangle.

   Colour is monochrome by default: ink, paper, limestone. The Heights blue is
   punctuation — a rule, a mark, one word — and never a surface fill. That
   restraint is what separates this from a technology-vendor palette.

   Every component reads its colour from the six semantic properties set by the
   surface it sits on (§2), so one component is correct on any field and there
   are no "--on-dark" variants anywhere in the sheet.
   ========================================================================== */

/* 1. Tokens ============================================================== */

:root {
    /* --- Ink ------------------------------------------------------------ */
    /* Not black. A near-black carrying a trace of blue, so it sits beside the
       warm paper without either looking tinted. */
    --ink-000: #05080c;
    --ink-050: #0a0e14;
    --ink-100: #10151d;
    --ink-200: #171e28;
    --ink-300: #222b38;
    --ink-400: #333d4c;

    /* --- Neutrals ------------------------------------------------------- */
    --graphite: #4a5461;
    /* Darkened from #6d7783, which failed WCAG AA on both light fields:
       4.18:1 on paper and 3.69:1 on limestone, against 4.5:1 required. It is
       the colour of every chapter label, form hint, byline and metadata line on
       the site, so the failure was everywhere at once and on the smallest type.
       #5e6872 is the same hue at 5.21:1 and 4.60:1 — the least change that
       clears the bar on the darker of the two fields. */
    --slate:    #5e6872;
    --mist:     #98a1ac;
    --haze:     #c2c8d0;

    /* --- Paper ---------------------------------------------------------- */
    --paper:          #f7f5f1;
    --paper-pure:     #ffffff;
    --limestone:      #ebe7df;
    --limestone-deep: #ded9ce;

    /* --- Signal --------------------------------------------------------- */
    /* The verified Heights blue. Used as punctuation, not as a surface. */
    --signal:        #0f4c81;
    --signal-deep:   #0b3a63;
    --signal-lift:   #7ea9ce;
    --signal-wash:   #e9f0f7;

    /* --- Feedback (forms only) ------------------------------------------ */
    --error:      #96201a;
    --error-wash: #fbeeed;
    --success:    #1c5f3f;

    /* --- Type ----------------------------------------------------------- */
    --font-display: "Inter Tight", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
    --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    /* A scale with real range. The top of it is meant to be used once per
       page and to fill the composition it sits in, not to shout. */
    --t-mega: clamp(2.5rem, 1.05rem + 4.9vw, 5.375rem);
    --t-hero: clamp(2.25rem, 1.05rem + 4vw, 4.5rem);
    --t-d1:   clamp(1.875rem, 1.05rem + 2.75vw, 3.5rem);
    --t-d2:   clamp(1.5rem, 1.05rem + 1.5vw, 2.375rem);
    --t-d3:   clamp(1.25rem, 1.08rem + 0.6vw, 1.625rem);
    --t-d4:   clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);

    --t-lede:  clamp(1.0625rem, 0.99rem + 0.35vw, 1.3125rem);
    --t-lede-lg: clamp(1.125rem, 0.98rem + 0.6vw, 1.5rem);
    --t-body:  1.0625rem;
    --t-small: 0.9375rem;
    --t-micro: 0.8125rem;
    --t-nano:  0.6875rem;

    --lead-mega: 0.92;
    --lead-tight: 1.02;
    --lead-snug: 1.14;
    --lead-body: 1.6;
    --lead-loose: 1.72;

    --track-mega:  -0.045em;
    --track-display: -0.032em;
    --track-tight: -0.018em;
    --track-normal: 0;
    --track-label: 0.14em;
    --track-nano:  0.2em;

    --w-regular: 400;
    --w-medium: 500;
    --w-semibold: 600;
    --w-bold: 700;

    /* --- Space ---------------------------------------------------------- */
    --s-1: 0.25rem;
    --s-2: 0.5rem;
    --s-3: 0.75rem;
    --s-4: 1rem;
    --s-5: 1.25rem;
    --s-6: 1.5rem;
    --s-8: 2rem;
    --s-10: 2.5rem;
    --s-12: 3rem;
    --s-16: 4rem;
    --s-20: 5rem;
    --s-24: 6rem;
    --s-32: 8rem;
    --s-40: 10rem;

    /* Chapters breathe. This is the single biggest difference between a page
       that reads as designed and one that reads as assembled. */
    --chapter: clamp(3.5rem, 1.9rem + 5.2vw, 7rem);
    --chapter-tight: clamp(2.5rem, 1.5rem + 3.2vw, 4.5rem);

    /* --- Measure and containers ----------------------------------------- */
    --gutter: clamp(1.25rem, 0.4rem + 3.4vw, 4.5rem);
    --w-full: 100%;
    --w-wide: 92rem;    /* 1472 — the working width of the site */
    --w-page: 78rem;    /* 1248 */
    --w-text: 44rem;    /* 704, prose measure */
    --w-narrow: 36rem;

    /* --- Line ----------------------------------------------------------- */
    --hair: 1px;
    --radius: 0px;
    --radius-sm: 2px;

    /* --- Motion --------------------------------------------------------- */
    /* One easing curve for entrances, one for interface response. Using two
       instead of six is what makes the motion feel like a single hand. */
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --ease: cubic-bezier(0.4, 0, 0.2, 1);
    --dur-fast: 140ms;
    --dur: 260ms;
    --dur-slow: 640ms;
    --dur-reveal: 520ms;

    /* --- Focus ---------------------------------------------------------- */
    /* The accent, not `currentColor`: a ring that inherits the element's own
       colour disappears the moment that colour matches the field behind it,
       which is what happened on every primary button. */
    --focus-ring: 2px solid var(--signal);
    --focus-offset: 4px;

    /* --- Layers --------------------------------------------------------- */
    --z-field: 0;
    --z-content: 1;
    --z-overlay: 55;
    --z-header: 60;

    /* --- Sticky chrome --------------------------------------------------
       Everything that pins derives its offset from these, so the header, the
       in-page index and sticky headings can never drift out of step. */
    --chrome-header: 5rem;

    /* The space the homepage opening leaves above and below its content, the
       same measure on both sides. The interior mastheads keep their own
       padding: they were right, and they are not to be changed to chase a
       homepage problem. */
    --open-pad: clamp(2.5rem, 1.4rem + 3vw, 4rem);
    --chrome-index: 0rem;
    --chrome-top: calc(var(--chrome-header) + var(--chrome-index));
}

:root:has(.section-index) {
    --chrome-index: 3.25rem;
}

/* 2. Surfaces ============================================================ */
/* --------------------------------------------------------------------------
   A surface remaps seven properties. Every component below is written against
   these and only these, so any component is correct on any field, and adding a
   field never means adding a modifier class to the things inside it.

     --bg          the field itself
     --fg          primary text
     --fg-2        secondary text
     --fg-3        quiet text: metadata, labels, numerals
     --rule        hairline
     --rule-2      hairline, emphasised
     --accent      punctuation: marks, active rules, one word
   -------------------------------------------------------------------------- */

.surface,
:root {
    --bg: var(--paper);
    --fg: var(--ink-100);
    --fg-2: var(--graphite);
    --fg-3: var(--slate);
    --rule: rgba(16, 21, 29, 0.13);
    --rule-2: rgba(16, 21, 29, 0.3);
    --accent: var(--signal);
}

.surface {
    background-color: var(--bg);
    color: var(--fg);
}

.surface--paper {
    --bg: var(--paper);
}

.surface--white {
    --bg: var(--paper-pure);
}

.surface--limestone {
    --bg: var(--limestone);
    --rule: rgba(16, 21, 29, 0.16);
    --rule-2: rgba(16, 21, 29, 0.34);
}

.surface--ink {
    --bg: var(--ink-050);
    --fg: #ffffff;
    --fg-2: var(--haze);
    --fg-3: var(--mist);
    --rule: rgba(255, 255, 255, 0.15);
    --rule-2: rgba(255, 255, 255, 0.34);
    --accent: var(--signal-lift);
}

.surface--ink-deep {
    --bg: var(--ink-000);
    --fg: #ffffff;
    --fg-2: var(--haze);
    --fg-3: var(--mist);
    --rule: rgba(255, 255, 255, 0.13);
    --rule-2: rgba(255, 255, 255, 0.3);
    --accent: var(--signal-lift);
}

/* 3. Fonts =============================================================== */
/* Self-hosted, latin subset. No third-party font request. Two files, 93 KB. */

@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("/fonts/inter-variable-latin.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+20AC, U+2122, U+2191,
        U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Inter Tight";
    font-style: normal;
    font-weight: 500 700;
    font-display: swap;
    src: url("/fonts/inter-tight-variable-latin.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+20AC, U+2122, U+2191,
        U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* 4. Reset and base ====================================================== */

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

html {
    -webkit-text-size-adjust: 100%;
    /* NO SMOOTH SCROLLING, AND THIS IS NOT A PREFERENCE. With it declared,
       every in-page anchor on this site did nothing at all: the section index,
       the article contents, the skip link and the Insights pagination each
       changed the URL and left the page exactly where it was. Measured, not
       assumed: with `auto` the same links land on their target every time.

       It also never belonged here. The motion budget is three keyframes, all
       disabled under `prefers-reduced-motion`, and this was ambient motion
       declared unconditionally on the root. An anchor that jumps always works;
       an anchor that does nothing is a broken link that still returns 200.

       `scroll-padding-top` stays: it is what keeps the target clear of the
       fixed header. */
    scroll-padding-top: calc(var(--chrome-top) + var(--s-8));
    background-color: var(--ink-000);
}

body {
    margin: 0;
    background-color: var(--paper);
    color: var(--ink-100);
    font-family: var(--font-sans);
    font-size: var(--t-body);
    line-height: var(--lead-body);
    font-weight: var(--w-regular);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    font-feature-settings: "kern" 1, "liga" 1, "cv05" 1, "ss03" 1;
    /* CLIP, NOT HIDDEN. `overflow-x: hidden` forces `overflow-y` to compute to
       `auto`, which makes the body a scroll container and is the usual reason
       `position: sticky` stops sticking. This site sticks the header, the
       section index and the split asides, so it matters. `clip` guards against
       horizontal overflow without creating a scroll container. */
    overflow-x: clip;
}

h1, h2, h3, h4, h5, h6 {
    margin: 0;
    font-family: var(--font-display);
    font-weight: var(--w-semibold);
    line-height: var(--lead-snug);
    letter-spacing: var(--track-tight);
    color: inherit;
}

p, ul, ol, dl, figure, blockquote, table {
    margin: 0;
}

p {
    text-wrap: pretty;
}

ul, ol {
    padding: 0;
    list-style: none;
}

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

a {
    color: inherit;
    text-decoration: none;
    transition: color var(--dur-fast) var(--ease);
}

strong, b {
    font-weight: var(--w-semibold);
}

address {
    font-style: normal;
}

abbr[title] {
    text-decoration: underline dotted;
    cursor: help;
}

hr {
    border: 0;
    border-top: var(--hair) solid var(--rule);
    margin: 0;
}

::selection {
    background: var(--signal);
    color: #ffffff;
}

/* THE RING CANNOT BE `currentColor`. `.btn--primary` sets `color: #ffffff` on
   focus, so the ring was drawn white, four pixels outside the button, on a
   paper field — invisible on the header CTA, every masthead action and the
   form submit. A focus indicator that disappears on the most important control
   on the page is not an indicator.

   Two rings, so it holds on any field: the accent draws the shape and a white
   halo sits outside it. On ink the halo is what you see; on paper the accent
   is. Neither depends on the element's own text colour. */
/* THE ATTRIBUTE WINS. `[hidden]` comes from the user-agent stylesheet, and any
   author rule setting `display` beats it regardless of specificity — which is
   how `.field { display: grid }` kept the honeypot rendered after it was marked
   hidden. An element the markup says is hidden must be hidden. */
[hidden] {
    display: none !important;
}

:focus-visible {
    outline: var(--focus-ring);
    outline-offset: var(--focus-offset);
    box-shadow: 0 0 0 calc(var(--focus-offset) + 4px) rgba(255, 255, 255, 0.9);
    border-radius: var(--radius-sm);
}

/* On a dark field the halo inverts, or it is the ring that vanishes. */
.surface--ink :focus-visible,
.surface--ink-deep :focus-visible,
.section--ink :focus-visible,
.chrome[data-chrome="dark"] :focus-visible,
.mast :focus-visible,
.arrival :focus-visible {
    box-shadow: 0 0 0 calc(var(--focus-offset) + 4px) rgba(10, 14, 20, 0.9);
}

/* Casing protection: the design system sets several labels in uppercase and a
   brand term must survive it. */
.brand-case {
    text-transform: none;
}

.skip-link {
    position: absolute;
    left: var(--s-4);
    top: var(--s-4);
    z-index: 999;
    transform: translateY(-200%);
    background: var(--ink-050);
    color: #ffffff;
    padding: var(--s-3) var(--s-5);
    font-size: var(--t-small);
    font-weight: var(--w-medium);
    transition: transform var(--dur) var(--ease-out);
}

.skip-link:focus {
    transform: translateY(0);
}

/* 5. Layout primitives =================================================== */

.wrap {
    width: 100%;
    max-width: var(--w-wide);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.wrap--page {
    max-width: var(--w-page);
}

.wrap--text {
    max-width: calc(var(--w-text) + var(--gutter) * 2);
}

.chapter {
    padding-block: var(--chapter);
    position: relative;
}

.chapter--tight {
    padding-block: var(--chapter-tight);
}

.chapter--flush-top {
    padding-block-start: 0;
}

/* The editorial column grid. Twelve columns at the working width; components
   place themselves on it rather than nesting flex boxes. */
.grid12 {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--gutter);
}

/* A rule that spans the field it sits in. This, not a border-radius box, is
   the site's structural device. */
.rule {
    border: 0;
    border-top: var(--hair) solid var(--rule);
    width: 100%;
}

.rule--strong {
    border-top-color: var(--rule-2);
}

/* 6. Typography ========================================================== */

.mega {
    font-family: var(--font-display);
    font-size: var(--t-mega);
    line-height: var(--lead-mega);
    letter-spacing: var(--track-mega);
    font-weight: var(--w-semibold);
    text-wrap: balance;
}

.display-1 {
    font-family: var(--font-display);
    font-size: var(--t-d1);
    line-height: var(--lead-tight);
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
    text-wrap: balance;
}

.display-2 {
    font-family: var(--font-display);
    font-size: var(--t-d2);
    line-height: var(--lead-snug);
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
    text-wrap: balance;
}

.display-3 {
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: var(--lead-snug);
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
    text-wrap: balance;
}

/* The chapter label. Small, wide-tracked, always preceded by its number and a
   short rule — the same object on every chapter of the site, which is what
   makes the page read as one publication. */
.label {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    font-family: var(--font-sans);
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
    margin: 0;
}

.label::before {
    content: "";
    width: var(--s-8);
    height: var(--hair);
    background: var(--rule-2);
    flex: none;
}

.label--plain::before {
    display: none;
}

.label__index {
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}

.lede {
    font-size: var(--t-lede);
    line-height: var(--lead-loose);
    color: var(--fg-2);
    max-width: 40em;
}

.lede--lg {
    font-size: var(--t-lede-lg);
    line-height: 1.5;
    letter-spacing: var(--track-tight);
    color: var(--fg-2);
    max-width: 26em;
}

.prose-note {
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-3);
}

.measure {
    max-width: var(--w-text);
}

.measure-narrow {
    max-width: var(--w-narrow);
}

/* 7. Controls ============================================================ */

.btn {
    --btn-fg: var(--bg);
    --btn-bg: var(--fg);
    --btn-line: var(--fg);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s-3);
    padding: 1.0625rem var(--s-8);
    font-family: var(--font-sans);
    font-size: var(--t-small);
    font-weight: var(--w-semibold);
    letter-spacing: 0.01em;
    line-height: 1.1;
    text-align: center;
    color: var(--btn-fg);
    background: var(--btn-bg);
    border: var(--hair) solid var(--btn-line);
    border-radius: var(--radius);
    cursor: pointer;
    position: relative;
    overflow: hidden;
    isolation: isolate;
    transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

/* The fill wipes upward from the baseline rather than fading. One gesture,
   used on every button on the site. */
.btn::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--btn-fill, var(--paper));
    transform: scaleY(0);
    transform-origin: bottom;
    transition: transform var(--dur) var(--ease-out);
}

.btn:hover::after,
.btn:focus-visible::after {
    transform: scaleY(1);
}

.btn--primary {
    --btn-fg: var(--bg);
    --btn-bg: var(--fg);
    --btn-line: var(--fg);
    --btn-fill: var(--signal);
}

.btn--primary:hover,
.btn--primary:focus-visible {
    color: #ffffff;
    border-color: var(--signal);
}

.btn--secondary {
    --btn-fg: var(--fg);
    --btn-bg: transparent;
    --btn-line: var(--rule-2);
    --btn-fill: var(--fg);
}

.btn--secondary:hover,
.btn--secondary:focus-visible {
    color: var(--bg);
    border-color: var(--fg);
}

.btn--ghost {
    --btn-fg: var(--fg);
    --btn-bg: transparent;
    --btn-line: transparent;
    --btn-fill: transparent;
    padding-inline: 0;
}

.btn-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-4);
}

/* The site's only link affordance besides plain body links: a label above a
   rule that draws itself in on hover. Replaces the arrow-and-chevron habit. */
.cue {
    display: inline-flex;
    flex-direction: column;
    gap: 0.6em;
    font-size: var(--t-small);
    font-weight: var(--w-semibold);
    letter-spacing: 0.005em;
    color: var(--fg);
    padding-bottom: 0.1em;
}

.cue__line {
    display: block;
    height: var(--hair);
    background: var(--rule-2);
    position: relative;
}

.cue__line::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--dur-slow) var(--ease-out);
}

.cue:hover .cue__line::after,
.cue:focus-visible .cue__line::after {
    transform: scaleX(1);
}

.cue:hover {
    color: var(--accent);
}

/* Inline text link, for prose only. */
.link {
    color: var(--accent);
    text-decoration: underline;
    text-underline-offset: 0.2em;
    text-decoration-thickness: from-font;
}

.link:hover {
    text-decoration-thickness: 2px;
}

/* 8. Motion ============================================================== */
/* --------------------------------------------------------------------------
   One entrance, applied by an IntersectionObserver in site.js that adds
   `is-in` to anything carrying data-reveal. Children stagger from --i.

   Nothing here is required for the page to be readable: without JavaScript
   the .no-js rule below leaves every element in its final state.
   -------------------------------------------------------------------------- */

.js [data-reveal] {
    opacity: 0;
    transform: translate3d(0, 1.75rem, 0);
    transition:
        opacity var(--dur-reveal) var(--ease-out),
        transform var(--dur-reveal) var(--ease-out);
    transition-delay: calc(var(--i, 0) * 38ms);
}

.js [data-reveal="rise"] {
    transform: translate3d(0, 3rem, 0);
}

.js [data-reveal="fade"] {
    transform: none;
}

/* A rule that draws itself across the field as the chapter arrives. */
.js [data-reveal="rule"] {
    opacity: 1;
    transform: none;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 640ms var(--ease-out);
    transition-delay: calc(var(--i, 0) * 38ms);
}

.js [data-reveal].is-in {
    opacity: 1;
    transform: none;
}

.js [data-reveal="rule"].is-in {
    transform: scaleX(1);
}

/* 9. Chrome ============================================================== */

/* --- Header ------------------------------------------------------------- */
/* The header floats over the opening field and resolves to a solid paper bar
   the moment the page moves. It carries its own colour state in
   data-chrome, set by site.js from the field beneath it, so the navigation is
   never the same colour as what is behind it. */

.chrome {
    position: fixed;
    inset-block-start: 0;
    inset-inline: 0;
    z-index: var(--z-header);
    --chrome-fg: #ffffff;
    --chrome-fg-2: rgba(255, 255, 255, 0.72);
    --chrome-rule: rgba(255, 255, 255, 0.14);
    --chrome-bg: transparent;
    color: var(--chrome-fg);
    background: var(--chrome-bg);
    border-bottom: var(--hair) solid var(--chrome-rule);
    transition:
        background-color var(--dur) var(--ease),
        border-color var(--dur) var(--ease),
        color var(--dur) var(--ease);
}

.chrome[data-chrome="light"] {
    --chrome-fg: var(--ink-100);
    --chrome-fg-2: var(--graphite);
    --chrome-rule: rgba(16, 21, 29, 0.12);
}

.chrome.is-stuck {
    --chrome-bg: rgba(10, 14, 20, 0.9);
    -webkit-backdrop-filter: saturate(140%) blur(14px);
    backdrop-filter: saturate(140%) blur(14px);
}

.chrome.is-stuck[data-chrome="light"] {
    --chrome-bg: rgba(247, 245, 241, 0.92);
}

.chrome__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-8);
    height: var(--chrome-header);
    transition: height var(--dur-slow) var(--ease);
}

/* --- Brand -------------------------------------------------------------- */
/* Both lockups ship in the document and the surface decides which is shown,
   so the mark is always legible against whatever is behind it and no script
   is required to swap a src. */

/* Same reasoning as the toggle: the lockup is 35px tall, and "go home" should
   not be a smaller target than the links beside it. Flex centring keeps the
   mark exactly where it was; only the hit area grows. */
.brand {
    position: relative;
    display: flex;
    align-items: center;
    min-height: 44px;
    flex: none;
    width: clamp(9rem, 13vw, 12rem);
    line-height: 0;
}

.brand img {
    width: 100%;
    height: auto;
    transition: opacity var(--dur-slow) var(--ease);
}

.brand__paper {
    opacity: 1;
}

.brand__ink {
    position: absolute;
    inset-block-start: 0;
    inset-inline-start: 0;
    opacity: 0;
}

.chrome[data-chrome="light"] .brand__paper {
    opacity: 0;
}

.chrome[data-chrome="light"] .brand__ink {
    opacity: 1;
}

/* --- Navigation --------------------------------------------------------- */

.nav {
    display: flex;
    align-items: center;
    gap: clamp(var(--s-5), 2.2vw, var(--s-10));
}

.nav__link {
    position: relative;
    font-size: var(--t-small);
    font-weight: var(--w-medium);
    letter-spacing: 0.005em;
    color: var(--chrome-fg-2);
    padding-block: var(--s-2);
    transition: color var(--dur) var(--ease);
}

.nav__link::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    inset-block-end: 0;
    height: var(--hair);
    background: currentColor;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--dur) var(--ease-out);
}

.nav__link:hover,
.nav__link[aria-current="page"] {
    color: var(--chrome-fg);
}

.nav__link:hover::after,
.nav__link:focus-visible::after,
.nav__link[aria-current="page"]::after {
    transform: scaleX(1);
}

/* The flagship item is marked by a small square in the accent, not by a pill
   or a colour swap. */
/* --- The industries disclosure ------------------------------------------
   A link plus a small caret button, not a hover menu: hover menus fail
   keyboard and touch users, and the label has to stay a real link to the
   index. The panel is the chrome's own surface — ink, hairline, no radius —
   and below 64rem the overlay presents the plain link instead. */
.nav__group {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--s-1);
}

.nav__disclosure {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    /* A bare glyph in the chrome, not a form control: without these the
       user-agent stylesheet paints the default button face, a white rounded
       box floating in the header. */
    background: none;
    border: 0;
    padding: 0;
    border-radius: 0;
    cursor: pointer;
    font: inherit;
    color: var(--chrome-fg-2);
    transition: color var(--dur) var(--ease);
}

.nav__disclosure:hover,
.nav__disclosure:focus-visible,
.nav__disclosure[aria-expanded="true"] {
    color: var(--chrome-fg);
}

.nav__caret {
    width: 0.42em;
    height: 0.42em;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg) translateY(-15%);
    transition: transform var(--dur) var(--ease);
}

.nav__disclosure[aria-expanded="true"] .nav__caret {
    transform: rotate(225deg) translateY(-15%);
}

.nav__panel {
    display: none;
    position: absolute;
    top: calc(100% + var(--s-3));
    left: 50%;
    transform: translateX(-50%);
    min-width: 18rem;
    background: var(--ink-050);
    border: var(--hair) solid rgba(255, 255, 255, 0.14);
    padding-block: var(--s-2);
    z-index: var(--z-header);
    box-shadow: 0 18px 44px rgba(5, 8, 12, 0.55);
}

/* Opens on hover and on keyboard focus anywhere in the group — pure CSS, so
   the menu works with scripting absent — and stays open when the button has
   been explicitly toggled. */
.nav__group:hover .nav__panel,
.nav__group:focus-within .nav__panel,
.nav__panel.is-open {
    display: block;
}

/* The bridge: an invisible strip covering the gap between the trigger and
   the panel, so the pointer can cross without the hover breaking. */
.nav__panel::before {
    content: "";
    position: absolute;
    inset-inline: 0;
    top: calc(-1 * var(--s-3) - 1px);
    height: calc(var(--s-3) + 1px);
}

.nav__panel-link {
    display: block;
    padding: 0.55rem 1.2rem;
    font-size: var(--t-small);
    color: rgba(255, 255, 255, 0.78);
    transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}

.nav__panel-link:hover,
.nav__panel-link:focus-visible,
.nav__panel-link.is-current {
    color: #ffffff;
    background: rgba(255, 255, 255, 0.05);
}

/* "All Industries" closes the list, set off by a rule. */
.nav__panel-link:last-child {
    margin-top: var(--s-2);
    border-top: var(--hair) solid rgba(255, 255, 255, 0.12);
    padding-top: 0.7rem;
    font-weight: var(--w-semibold);
}

@media (max-width: 64rem) {
    /* The overlay presents the plain link; the disclosure is desktop chrome. */
    .nav__group { display: contents; }
    .nav__disclosure,
    .nav__panel { display: none !important; }
}

.nav__link--flagship {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5em;
}

/* Stagger indices for the overlay, declared here rather than in the template
   so no markup carries a style attribute. */
.nav__link:nth-of-type(1) { --i: 0; }
.nav__link:nth-of-type(2) { --i: 1; }
.nav__link:nth-of-type(3) { --i: 2; }
.nav__link:nth-of-type(4) { --i: 3; }
.nav__link:nth-of-type(5) { --i: 4; }
.nav__link:nth-of-type(6) { --i: 5; }
.nav__link:nth-of-type(7) { --i: 6; }

.nav__link--flagship::before {
    content: "";
    width: 5px;
    height: 5px;
    background: var(--signal-lift);
    flex: none;
    transition: background-color var(--dur) var(--ease);
}

.chrome[data-chrome="light"] .nav__link--flagship::before {
    background: var(--signal);
}

.nav__cta {
    display: none;
}

.chrome__actions {
    display: flex;
    align-items: center;
    gap: var(--s-4);
    flex: none;
}

/* The consultation action in the header is a compact outline that inverts. */
.chrome__cta {
    padding: 0.8125rem var(--s-6);
    font-size: var(--t-micro);
    font-weight: var(--w-semibold);
    letter-spacing: 0.02em;
    color: var(--chrome-fg);
    border: var(--hair) solid var(--chrome-rule);
    position: relative;
    overflow: hidden;
    isolation: isolate;
    white-space: nowrap;
    transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.chrome__cta::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--chrome-fg);
    transform: scaleY(0);
    transform-origin: bottom;
    transition: transform var(--dur) var(--ease-out);
}

.chrome__cta:hover,
.chrome__cta:focus-visible {
    color: var(--ink-050);
    border-color: var(--chrome-fg);
}

.chrome[data-chrome="light"] .chrome__cta:hover,
.chrome[data-chrome="light"] .chrome__cta:focus-visible {
    color: var(--paper);
}

.chrome__cta:hover::after,
.chrome__cta:focus-visible::after {
    transform: scaleY(1);
}

/* --- Menu toggle -------------------------------------------------------- */

/* THE ONLY NAVIGATION BELOW 64rem, SO IT IS SIZED LIKE IT.
   The label and rule box came to 31.5px tall, which is a small thing to hit
   with a thumb on the one control that opens the entire menu on every phone
   and tablet. `min-height` takes the target to 44px inside a 72px bar, so the
   header does not grow and nothing moves: the extra height is hit area above
   and below the label, centred by `align-items`. */
.menu-toggle {
    display: none;
    align-items: center;
    min-height: 44px;
    gap: var(--s-3);
    background: none;
    border: 0;
    padding: var(--s-2) 0;
    margin: 0;
    color: inherit;
    font-family: var(--font-sans);
    font-size: var(--t-micro);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    cursor: pointer;
}

.menu-toggle__bars {
    display: block;
    position: relative;
    width: 1.5rem;
    height: 10px;
    flex: none;
}

.menu-toggle__bars span {
    position: absolute;
    inset-inline: 0;
    height: var(--hair);
    background: currentColor;
    transition: transform var(--dur) var(--ease-out), opacity var(--dur-fast) var(--ease);
}

.menu-toggle__bars span:first-child {
    top: 0;
}

.menu-toggle__bars span:last-child {
    bottom: 0;
}

.menu-toggle[aria-expanded="true"] .menu-toggle__bars span:first-child {
    transform: translateY(4.5px) rotate(45deg);
}

.menu-toggle[aria-expanded="true"] .menu-toggle__bars span:last-child {
    transform: translateY(-4.5px) rotate(-45deg);
}

.menu-toggle__label--close {
    display: none;
}

.menu-toggle[aria-expanded="true"] .menu-toggle__label--open {
    display: none;
}

.menu-toggle[aria-expanded="true"] .menu-toggle__label--close {
    display: inline;
}

/* 10. Footer ============================================================= */
/* --------------------------------------------------------------------------
   An index, not a second closing scene. The chapter above already makes the
   statement and carries the action, so this carries no headline, no repeated
   call to action and no marketing sentence: identity and contact on the left,
   the navigation columns on the right, one utility row along the bottom.
   -------------------------------------------------------------------------- */

.foot {
    background: var(--ink-000);
    color: #ffffff;
    --bg: var(--ink-000);
    --fg: #ffffff;
    --fg-2: var(--haze);
    --fg-3: var(--mist);
    --rule: rgba(255, 255, 255, 0.13);
    --rule-2: rgba(255, 255, 255, 0.3);
    --accent: var(--signal-lift);
    padding-block: clamp(var(--s-12), 5vw, var(--s-20)) var(--s-8);
}

.foot__inner {
    display: grid;
    /* The identity block needs a brand column, not a third of the footer:
       narrowing it hands the width to the five nav tracks, which is what
       stops every second label wrapping onto two ragged lines. */
    grid-template-columns: minmax(13rem, 16rem) minmax(0, 1fr);
    gap: var(--s-12) clamp(var(--s-10), 5vw, var(--s-16));
    padding-bottom: clamp(var(--s-12), 5vw, var(--s-20));
    border-bottom: var(--hair) solid var(--rule);
}

.foot__mark {
    display: block;
    width: clamp(9.5rem, 13vw, 12rem);
}

.foot__contact {
    display: grid;
    gap: var(--s-3);
    margin-top: var(--s-8);
}

.foot__contact-line {
    font-family: var(--font-display);
    font-size: .9rem;
    color: #ffffff;
}

.foot__contact-line:hover {
    color: #ffffff;
}

.foot__place {
    margin-top: var(--s-2);
    font-size: .9rem;
    color: #ffffff;
}

.foot__columns {
    display: grid;
    /* One track per column. Five groups in a four-track grid left Firm
       wrapping alone into a second row beside a field of dead space. */
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: var(--s-10) var(--s-8);
}

.foot__heading {
    font-family: var(--font-sans);
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
    padding-bottom: var(--s-4);
    margin-bottom: var(--s-5);
    border-bottom: var(--hair) solid var(--rule);
}

.foot__list {
    display: grid;
    gap: var(--s-3);
    font-size: var(--t-small);
    line-height: 1.35;
}

.foot__list a {
    color: var(--fg-2);
    transition: color var(--dur) var(--ease);
}

.foot__list a:hover {
    color: #ffffff;
}

.foot__bottom {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: var(--s-4) var(--s-8);
    padding-top: var(--s-8);
    font-size: var(--t-micro);
    color: var(--fg-3);
}

.foot__utility {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-6);
}

.foot__utility a {
    transition: color var(--dur) var(--ease);
}

.foot__utility a:hover {
    color: #ffffff;
}

/* 11. Homepage chapters ================================================== */
/* --------------------------------------------------------------------------
   Nine chapters. Each one is a different composition on a different field, in
   a deliberate order:

     01 ARRIVAL      ink, full viewport, one statement
     02 THE PROBLEM  limestone, sticky rail against stepped rows
     03 THE SHIFT    ink, a stepped scatter resolving into a level ledger
     04 FLAGSHIP     paper, the largest type on the site, plus the engagement arc
     05 CAPABILITIES ink, a hover-driven typographic index
     06 SECTORS      limestone, four rows that open on approach
     07 PRINCIPAL    paper, a signature composition
     08 PUBLICATION  white, one feature and its secondaries
     09 CLOSE        ink, the bookend of chapter 01

   No two of them share a layout, and none of them is a grid of cards.
   -------------------------------------------------------------------------- */

/* --- 01 Arrival --------------------------------------------------------- */

.arrival {
    position: relative;
    display: flex;
    align-items: stretch;
    overflow: clip;
    padding-block: var(--chrome-header) var(--open-pad);
}

/* The field, entirely decorative: a tonal wash, the page's licensed frame
   screened onto it, and a drafting grid at the threshold of visibility. */
.arrival__field {
    position: absolute;
    inset: 0;
    z-index: var(--z-field);
    overflow: hidden;
    /* Directional falloff rather than a centred glow: light arriving from the
       upper right, the way it would on a physical surface. */
    background:
        radial-gradient(150% 100% at 86% -6%, rgba(15, 76, 129, 0.32) 0%, rgba(15, 76, 129, 0.06) 42%, rgba(15, 76, 129, 0) 66%),
        linear-gradient(172deg, var(--ink-100) 0%, var(--ink-000) 78%);
    pointer-events: none;
}

/* A drafting grid on the working column measure. It is the reason the field
   reads as constructed rather than as a gradient. */
.arrival__grid {
    position: absolute;
    inset-block: 0;
    inset-inline: 0;
    max-width: var(--w-wide);
    margin-inline: auto;
    padding-inline: var(--gutter);
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
}

.arrival__grid span {
    border-left: var(--hair) solid rgba(255, 255, 255, 0.028);
}

.arrival__grid span:last-child {
    border-right: var(--hair) solid rgba(255, 255, 255, 0.028);
}

/* The scrim: directional darkening over the left of the frame, painted above
   the photograph so the headline and the action pair sit on quiet ground. The
   photograph's own light survives at the summit edge, which is where the
   composition wants it. */
.field-scrim {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background: linear-gradient(
        97deg,
        rgba(5, 8, 12, 0.66) 0%,
        rgba(5, 8, 12, 0.38) 40%,
        rgba(5, 8, 12, 0.06) 64%,
        rgba(5, 8, 12, 0) 78%
    );
}

/* The ascent, drawn: five elevation contours rising toward the upper right,
   the mark's geometry at landscape scale. Hairline strokes, brightening with
   altitude, the top ridge in the signal blue — the only drawn light in the
   frame. `pathLength="1"` in the markup normalises every ridge to one dash, so
   the draw is a single dashoffset. */
.arrival__contours {
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    width: 100%;
    height: min(62%, 33rem);
    z-index: 0;
    pointer-events: none;
}

.arrival__contours path {
    fill: none;
    /* Bright enough to read as drawn light, not texture: the ridges are the
       composition's signature, and a signature at the threshold of visibility
       is a signature nobody sees. They brighten with altitude. */
    stroke: rgba(255, 255, 255, calc(0.09 + var(--c, 0) * 0.035));
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
    stroke-dasharray: 1;
    stroke-dashoffset: 0;
}

.arrival__contours path:nth-child(1) { --c: 0; }
.arrival__contours path:nth-child(2) { --c: 1; }
.arrival__contours path:nth-child(3) { --c: 2; }
.arrival__contours path:nth-child(4) { --c: 3; }

/* The top ridge carries the light: the signal blue, a heavier stroke, and a
   soft glow lifted from the same hue. */
.arrival__contours path:nth-child(5) {
    --c: 4;
    stroke: rgba(126, 169, 206, 0.72);
    stroke-width: 1.5;
    filter: drop-shadow(0 0 6px rgba(126, 169, 206, 0.55));
}

/* The lit ridge breathes: a slow cycle on its opacity once it has drawn, so
   the field carries one point of quiet life. NOT a transform on the
   photograph — an animated transform on the mix-blended, masked image kicks
   it onto its own composited layer and Chrome stops blending it with the
   field, which reads as the photograph going dark. That drift was tried and
   removed for exactly that reason; do not reintroduce it. */
.js .arrival.is-in .arrival__contours path:nth-child(5) {
    animation:
        arrival-contour-draw 1500ms var(--ease-out) forwards,
        arrival-ridge 6400ms ease-in-out 2450ms infinite;
    animation-delay: calc(var(--c, 0) * 130ms + 420ms), 2450ms;
}

@keyframes arrival-ridge {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.45; }
}

/* Armed only when scripting is present, like the headline: with JavaScript
   blocked the ridges are simply there. The draw runs once, back ridge first,
   after the headline has landed. */
.js .arrival .arrival__contours path {
    stroke-dashoffset: 1;
}

.js .arrival.is-in .arrival__contours path {
    animation: arrival-contour-draw 1500ms var(--ease-out) forwards;
    animation-delay: calc(var(--c, 0) * 130ms + 420ms);
}

@keyframes arrival-contour-draw {
    to {
        stroke-dashoffset: 0;
    }
}

/* The opening is exactly as tall as what it carries.

   It used to be forced to the full viewport, which on any screen left a few
   hundred pixels over: above the headline, between the headline and the rule,
   or below the baseline, depending on how the block was aligned. There is no
   arrangement of two elements that fills a viewport without leftover somewhere,
   so the fill is gone and the leftover with it. The interior mastheads are
   built the same way — their height comes from their content, not from a
   minimum. */
.arrival__inner {
    position: relative;
    z-index: var(--z-content);
    container-type: inline-size;
    width: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    gap: 0;
}

.arrival__title {
    /* 8rem, as set. A viewport-relative clamp resolved to roughly half this on
       a normal desktop window; the small-screen cases are handled by width in
       the responsive layers below, not by shrinking this. */
    margin-block: 8rem;
    font-family: var(--font-display);
    font-size: clamp(2.5rem, 7.8cqw, 7rem);
    line-height: var(--lead-mega);
    letter-spacing: var(--track-mega);
    font-weight: var(--w-semibold);
    color: #ffffff;
}

/* The ascent: each line steps one measure further right than the one above.
   This is the mark's geometry used as a paragraph rule. */
.arrival__line {
    display: block;
    overflow: hidden;
    padding-block: 0.04em;
}

.arrival__line--1 { --i: 0; }

.arrival__line--2 {
    --i: 1;
    padding-inline-start: 0.62em;
}

.arrival__line--3 {
    --i: 2;
    padding-inline-start: 1.24em;
}

.arrival__line-in {
    display: block;
}

/* Armed only when scripting is present, so with JavaScript blocked the
   headline is simply there. */
.js .arrival__line-in {
    transform: translateY(105%);
    transition: transform 720ms var(--ease-out);
    transition-delay: calc(var(--i, 0) * 80ms + 60ms);
}

/* The ascent brightens as it climbs. The first line sets off in half-light,
   the second gains, and the payoff — the accountability line, at the summit
   position — arrives in full white. It used to run the other way, which dimmed
   the one line the whole opening exists to land. */
.arrival__line--1 .arrival__line-in {
    color: rgba(255, 255, 255, 0.76);
}

.arrival__line--2 .arrival__line-in {
    color: rgba(255, 255, 255, 0.9);
}

.arrival__line--3 .arrival__line-in {
    color: #ffffff;
}

/* The one mark of colour in the headline: the full stop where the ascent
   ends, set in the signal blue the beacon and the top ridge carry. */
.arrival__stop {
    color: var(--signal-lift);
}

.js .arrival.is-in .arrival__line-in {
    transform: translateY(0);
}

.arrival__baseline {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    /* Both columns start on the rule. Aligned to the end, the button box sat a
       few pixels below the last line of the sentence — close enough to read as
       a mistake rather than as a decision. */
    align-items: start;
    gap: var(--s-8) var(--gutter);
    padding-top: var(--s-8);
    border-top: var(--hair) solid rgba(255, 255, 255, 0.16);
}

.arrival__lede {
    font-size: var(--t-lede);
    line-height: 1.62;
    color: rgba(255, 255, 255, 0.72);
    max-width: 46ch;
}

.arrival__actions {
    justify-content: flex-end;
}

/* Who the site is for, under the lede at whisper volume. */
.arrival__audience {
    margin-top: var(--s-4);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: rgba(255, 255, 255, 0.55);
    max-width: 52ch;
}

/* --- The principal band (homepage) ---------------------------------------
   A slim paper interlude after the arrival: the portrait at reading size and
   the record in one sentence. The full principal chapter further down keeps
   its role; this is orientation, not biography. */
.founder-band {
    padding-block: clamp(var(--s-10), 6vw, var(--s-12));
}

.founder-band__inner {
    display: grid;
    grid-template-columns: minmax(8rem, 11rem) minmax(0, 1fr);
    gap: clamp(var(--s-6), 4vw, var(--s-10));
    align-items: center;
}

.founder-band__portrait {
    width: 100%;
    height: auto;
    border: var(--hair) solid var(--rule);
}

.founder-band__statement {
    max-width: 52ch;
    color: var(--fg-2);
}

@media (max-width: 40rem) {
    .founder-band__inner {
        grid-template-columns: minmax(0, 1fr);
    }
    .founder-band__portrait {
        max-width: 11rem;
    }
}

/* The questions ledger: the same object as the mastheads' facts row — three
   columns hung under one rule, a short label and a sentence in each. */
.arrival__questions {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--s-8) var(--gutter);
    margin-top: clamp(var(--s-10), 4vw, var(--s-12));
    padding-top: var(--s-8);
    border-top: var(--hair) solid rgba(255, 255, 255, 0.16);
}

.arrival__question a {
    display: grid;
    gap: var(--s-3);
    align-content: start;
}

.arrival__q {
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.24;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
    color: #ffffff;
    transition: color var(--dur) var(--ease);
}

.arrival__question a:hover .arrival__q,
.arrival__question a:focus-visible .arrival__q {
    color: var(--signal-lift);
}

.arrival__a {
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: rgba(255, 255, 255, 0.66);
}

.arrival .btn--secondary {
    --btn-line: rgba(255, 255, 255, 0.34);
    --btn-fg: #ffffff;
    --btn-fill: #ffffff;
}

.arrival .btn--secondary:hover,
.arrival .btn--secondary:focus-visible {
    color: var(--ink-050);
    border-color: #ffffff;
}

/* --- Portrait ------------------------------------------------------------ */
/* The verified portrait on a profile page: content, not a field treatment,
   so it carries real alt text and explicit dimensions. */
.portrait {
    display: block;
    width: min(100%, 18rem);
    height: auto;
    margin-bottom: var(--s-6);
    border: var(--hair) solid var(--rule);
}

/* --- The board report sample ---------------------------------------------
   A document, deliberately: white page, ruled sections, quiet labels. It
   should look like the artifact a director would hold, not like a web
   component. */
.brdoc {
    background: #ffffff;
    color: var(--ink-100);
    border: var(--hair) solid var(--rule-2, rgba(16, 21, 29, 0.2));
    box-shadow: 0 24px 60px rgba(16, 21, 29, 0.12);
    padding: clamp(1.75rem, 5vw, 3.5rem);
    max-width: 54rem;
}

.brdoc__head {
    padding-bottom: var(--s-6);
    border-bottom: 2px solid var(--ink-100);
    margin-bottom: var(--s-8);
}

.brdoc__doc-title {
    font-family: var(--font-display);
    font-size: var(--t-d3);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-tight);
    color: var(--ink-100);
}

.brdoc__doc-meta {
    margin-top: var(--s-2);
    font-size: var(--t-small);
    color: var(--slate);
}

.brdoc__section {
    padding-block: var(--s-6);
    border-top: var(--hair) solid rgba(16, 21, 29, 0.14);
}

.brdoc__section:first-of-type {
    border-top: 0;
}

.brdoc__label {
    font-size: var(--t-nano, 0.72rem);
    font-weight: var(--w-semibold);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--graphite);
    margin-bottom: var(--s-4);
}

.brdoc p,
.brdoc li {
    color: var(--ink-100);
    line-height: var(--lead-loose);
    max-width: 62ch;
}

.brdoc ul {
    display: grid;
    gap: var(--s-3);
    padding-left: 1.1rem;
    list-style: disc;
}

.brdoc__table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--t-small);
}

.brdoc__table th,
.brdoc__table td {
    text-align: left;
    padding: 0.6rem 0.9rem 0.6rem 0;
    border-bottom: var(--hair) solid rgba(16, 21, 29, 0.14);
    vertical-align: top;
}

.brdoc__table th {
    font-size: var(--t-nano, 0.72rem);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--graphite);
}

/* --- The consultation dialog ---------------------------------------------
   The same server-rendered form the contact page carries, opened in place by
   any consultation control. Native <dialog>: Escape and focus containment
   come from the platform. */
.consult {
    width: min(92vw, 44rem);
    max-height: 90dvh;
    overflow-y: auto;
    margin: auto;
    border: none;
    padding: 0;
    background: #ffffff;
    color: var(--ink-100);
    box-shadow: 0 32px 80px rgba(5, 8, 12, 0.5);
}

.consult::backdrop {
    background: rgba(5, 8, 12, 0.62);
}

.consult__inner {
    padding: clamp(1.5rem, 4vw, 2.75rem);
    display: grid;
    gap: var(--s-5);
}

.consult__head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--s-4);
}

.consult__title {
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: 1.12;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
    color: var(--ink-100);
}

.consult__close {
    background: none;
    border: 0;
    padding: 0 0.2rem;
    cursor: pointer;
    font: inherit;
    font-size: 1.8rem;
    line-height: 1;
    color: var(--graphite);
    transition: color var(--dur) var(--ease);
}

.consult__close:hover,
.consult__close:focus-visible {
    color: var(--ink-100);
}

.consult__lede {
    color: var(--slate);
    max-width: 44ch;
}

/* The hook: the in-person invitation, set off with the signal rule so it
   reads as the human line it is. */
.consult__hook {
    max-width: 46ch;
    padding-left: var(--s-4);
    border-left: 2px solid var(--signal);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--graphite);
}

/* --- The offer (vCISO) ---------------------------------------------------
   The person and the promise on one spine: portrait and credentials in the
   narrow column, the offer statement and the ask in the wide one. */
.offer {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-10) var(--gutter);
    align-items: start;
}

.offer__portrait {
    display: block;
    width: min(100%, 17rem);
    height: auto;
    border: var(--hair) solid var(--rule);
    margin-bottom: var(--s-5);
}

.offer .principal__name {
    font-size: var(--t-d2);
}

.offer__facts {
    margin-top: var(--s-5);
    max-width: 24rem;
    display: grid;
    gap: var(--s-3);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.offer__facts li {
    padding-top: var(--s-3);
    border-top: var(--hair) solid var(--rule);
}

.offer__body {
    display: grid;
    gap: var(--s-5);
    align-content: start;
}

.offer__statement {
    font-size: var(--t-lede);
    line-height: 1.55;
    color: var(--fg);
    max-width: 32em;
}

/* --- 02 The problem ----------------------------------------------------- */

.problem__inner {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-16) var(--gutter);
    align-items: start;
}

.problem__rail {
    position: sticky;
    top: calc(var(--chrome-top) + var(--s-10));
    display: grid;
    gap: var(--s-6);
}

.problem__title {
    max-width: 14ch;
}

.problem__rows {
    display: grid;
}

.problem__row {
    border-top: var(--hair) solid var(--rule);
}

.problem__row:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.problem__link {
    display: grid;
    grid-template-columns: 3.5rem minmax(0, 1fr);
    gap: var(--s-4);
    padding-block: clamp(var(--s-6), 2.4vw, var(--s-10));
    transition: padding-inline-start var(--dur-slow) var(--ease-out);
}

.problem__row:hover .problem__link,
.problem__link:focus-visible {
    padding-inline-start: var(--s-4);
}

/* The step: each question sits one increment further right than the last. */
.problem__row:nth-child(2) .problem__link {
    padding-inline-start: var(--s-6);
}

.problem__row:nth-child(3) .problem__link {
    padding-inline-start: var(--s-12);
}

.problem__row:nth-child(2):hover .problem__link {
    padding-inline-start: var(--s-10);
}

.problem__row:nth-child(3):hover .problem__link {
    padding-inline-start: var(--s-16);
}

.problem__index {
    font-size: var(--t-micro);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--track-label);
    color: var(--fg-3);
    padding-top: 0.55em;
    transition: color var(--dur) var(--ease);
}

.problem__row:hover .problem__index {
    color: var(--accent);
}

.problem__q {
    font-family: var(--font-display);
    font-size: var(--t-d2);
    line-height: 1.12;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
    max-width: 20ch;
    transition: color var(--dur) var(--ease);
}

.problem__a {
    display: block;
    margin-top: var(--s-4);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
    max-width: 62ch;
}

.problem__cue {
    display: inline-flex;
    align-items: center;
    gap: var(--s-3);
    margin-top: var(--s-5);
    font-size: var(--t-micro);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--fg-3);
    transition: color var(--dur) var(--ease), gap var(--dur) var(--ease-out);
}

.problem__cue::after {
    content: "";
    width: var(--s-6);
    height: var(--hair);
    background: currentColor;
    transition: width var(--dur-slow) var(--ease-out);
}

.problem__row:hover .problem__cue,
.problem__link:focus-visible .problem__cue {
    color: var(--accent);
}

.problem__row:hover .problem__cue::after {
    width: var(--s-12);
}

/* --- 03 The shift ------------------------------------------------------- */

.shift__head {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: var(--s-8) var(--gutter);
    align-items: end;
}

.shift__title {
    max-width: 18ch;
}

.shift__statement {
    font-size: var(--t-lede);
    line-height: 1.66;
    color: var(--fg-2);
    max-width: 52ch;
}

/* The scatter. Seven fragments on a stepped diagonal: nothing is aligned with
   anything else, which is the point being made. */
.fragments {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--s-10) var(--gutter);
    margin-top: var(--s-20);
}

.fragments__item {
    padding-top: var(--s-4);
    border-top: var(--hair) solid var(--rule);
}

.fragments__item:nth-child(4n+1) { margin-block-start: 0; }
.fragments__item:nth-child(4n+2) { margin-block-start: var(--s-10); }
.fragments__item:nth-child(4n+3) { margin-block-start: var(--s-20); }
.fragments__item:nth-child(4n+4) { margin-block-start: var(--s-24); }

.fragments__term {
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.24;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
    color: var(--fg);
}

.fragments__text {
    margin-top: var(--s-3);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-3);
}

.shift__pivot {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: var(--s-8) var(--gutter);
    align-items: end;
    margin-top: var(--s-32);
    padding-top: var(--s-10);
    border-top: var(--hair) solid var(--rule-2);
}

.shift__pivot-title {
    max-width: 16ch;
}

/* The ledger. Everything the scatter was not: one left margin, one rhythm,
   four rows. */
.level {
    display: grid;
    margin-top: var(--s-12);
}

.level__row {
    display: grid;
    grid-template-columns: 5rem minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-4) var(--gutter);
    align-items: baseline;
    padding-block: clamp(var(--s-6), 2vw, var(--s-8));
    border-top: var(--hair) solid var(--rule);
}

.level__row:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.level__num {
    font-size: var(--t-micro);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--track-label);
    color: var(--accent);
}

.level__term {
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: 1.16;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
}

.level__text {
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
    max-width: 62ch;
}

.shift__foot {
    margin-top: var(--s-10);
}

/* --- 04 Flagship -------------------------------------------------------- */

.flagship__mast {
    display: grid;
    gap: var(--s-8);
}

.flagship__title {
    font-family: var(--font-display);
    font-size: var(--t-mega);
    line-height: 0.96;
    letter-spacing: var(--track-mega);
    font-weight: var(--w-semibold);
    max-width: 14ch;
}

.flagship__body {
    display: grid;
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    gap: var(--s-12) var(--s-16);
    margin-top: var(--s-16);
    align-items: start;
}

.flagship__lede {
    font-size: var(--t-lede-lg);
    line-height: 1.5;
    letter-spacing: var(--track-tight);
    color: var(--fg);
    max-width: 32ch;
}

.flagship__actions {
    margin-top: var(--s-10);
}

.flagship__carries {
    display: grid;
}

.flagship__carries-label {
    font-family: var(--font-sans);
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
    padding-bottom: var(--s-4);
}

.flagship__item {
    display: grid;
    grid-template-columns: 2.75rem minmax(0, 1fr);
    align-items: baseline;
    gap: var(--s-3);
    padding-block: var(--s-4);
    border-top: var(--hair) solid var(--rule);
    font-family: var(--font-display);
    font-size: var(--t-d4);
    letter-spacing: var(--track-tight);
    font-weight: var(--w-medium);
}

.flagship__item:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.flagship__item span:first-child {
    font-family: var(--font-sans);
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--track-label);
    color: var(--fg-3);
}

/* The qualifier, pulled out on the accent rule so it reads as a statement
   rather than as a footnote. */
.flagship__note {
    margin-top: var(--s-20);
    padding-inline-start: var(--s-8);
    border-inline-start: 2px solid var(--accent);
    font-size: var(--t-lede);
    line-height: 1.66;
    color: var(--fg-2);
    max-width: 68ch;
}

/* The engagement arc. One rule, four ticks, four columns of text hanging
   beneath it. A timeline, not a schematic. */
.arc {
    margin-top: var(--chapter-tight);
    padding-top: var(--chapter-tight);
    border-top: var(--hair) solid var(--rule);
}

.arc__head {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: var(--s-6) var(--gutter);
    align-items: end;
}

.arc__track {
    position: relative;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--gutter);
    margin-top: var(--s-16);
    padding-top: var(--s-8);
}

.arc__track::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    height: var(--hair);
    background: var(--rule);
}

.arc__step {
    position: relative;
}

.arc__step::before {
    content: "";
    position: absolute;
    inset-block-start: calc(var(--s-8) * -1);
    inset-inline-start: 0;
    width: var(--s-8);
    height: 2px;
    background: var(--accent);
    transform-origin: left;
}

.js .arc__step::before {
    transform: scaleX(0);
    transition: transform var(--dur-slow) var(--ease-out);
    transition-delay: calc(var(--i, 0) * 120ms);
}

.js .arc__step.is-in::before {
    transform: scaleX(1);
}

.arc__num {
    display: block;
    font-size: var(--t-micro);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--track-label);
    color: var(--fg-3);
}

.arc__title {
    margin-top: var(--s-4);
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.2;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
}

.arc__text {
    margin-top: var(--s-3);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

/* --- 05 Capabilities ---------------------------------------------------- */

.capabilities__head {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: var(--s-8) var(--gutter);
    align-items: end;
    padding-bottom: var(--s-10);
}

.capabilities__title {
    max-width: 18ch;
}

/* THE CAPABILITY INDEX.
   One row per service across the full width: an ordinal, the name at display
   scale, and the group it belongs to set quietly on the right. The group is
   annotation, not a container, so the portfolio reads as one ordered system
   rather than as four repetitions of a block. */

.capindex {
    display: grid;
    border-top: 2px solid var(--rule-2);
}

.capindex__row {
    border-bottom: var(--hair) solid var(--rule);
}

.capindex__link {
    display: grid;
    grid-template-columns: 4.5rem minmax(0, 1fr) auto;
    align-items: baseline;
    gap: var(--s-4) var(--gutter);
    padding-block: clamp(var(--s-4), 1.5vw, var(--s-6));
    transition: padding-inline-start var(--dur-slow) var(--ease-out);
}

.capindex__row:hover .capindex__link,
.capindex__link:focus-visible {
    padding-inline-start: var(--s-5);
}

.capindex__num {
    font-size: var(--t-micro);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--track-label);
    color: var(--fg-3);
    transition: color var(--dur) var(--ease);
}

.capindex__row:hover .capindex__num {
    color: var(--accent);
}

.capindex__name {
    font-family: var(--font-display);
    font-size: var(--t-d2);
    line-height: 1.1;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
    transition: color var(--dur) var(--ease);
}

.capindex__group {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
    white-space: nowrap;
    transition: color var(--dur) var(--ease);
}

.capindex__row:hover .capindex__group,
.capindex__link:focus-visible .capindex__group {
    color: var(--accent);
}

.capabilities__foot {
    margin-top: var(--s-12);
}

/* --- 06 Sectors --------------------------------------------------------- */

.sectors__head {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: var(--s-8) var(--gutter);
    align-items: end;
    padding-bottom: var(--s-12);
}

.sectors__title {
    max-width: 14ch;
}

.sectors__list {
    display: grid;
}

.sector {
    border-top: var(--hair) solid var(--rule);
}

.sector:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.sector__link {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--s-6) var(--gutter);
    padding-block: clamp(var(--s-6), 2.2vw, var(--s-10));
    position: relative;
}

/* The field slides in behind the row rather than the row being a card. */
.sector__link::before {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline: calc(var(--s-6) * -1);
    background: var(--ink-100);
    transform: scaleY(0);
    transform-origin: bottom;
    transition: transform var(--dur-slow) var(--ease-out);
    z-index: 0;
}

/* HOVER IS A CAPABILITY, NOT A WIDTH. The field and the white text it exists to
   carry are one thing, and they have to appear and disappear together. They did
   not: the responsive layer removed the field below 56rem on the theory that a
   narrow screen is a touch screen, and left every hover colour behind it. A
   desktop window at phone width, or a tablet with a pointer, turned the
   headline white on limestone and the row vanished under the cursor.

   `(hover: hover)` asks the question the design actually depends on. Focus is
   deliberately NOT inside it: a keyboard can be attached to anything, so the
   focus state keeps its field at every width. */
.sector__link:focus-visible::before {
    transform: scaleY(1);
}

@media (hover: hover) {
    .sector:hover .sector__link::before {
        transform: scaleY(1);
    }

    .sector:hover .sector__body {
        grid-template-rows: 1fr;
    }

    .sector:hover .sector__name {
        color: #ffffff;
        transform: translateX(var(--s-4));
    }

    .sector:hover .sector__index,
    .sector:hover .sector__meta {
        color: var(--signal-lift);
    }

    .sector:hover .sector__summary {
        color: var(--haze);
    }
}

.sector__name,
.sector__meta,
.sector__body {
    position: relative;
    z-index: 1;
}

.sector__name {
    display: flex;
    align-items: baseline;
    gap: var(--s-5);
    font-family: var(--font-display);
    font-size: var(--t-d1);
    line-height: 1.04;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
    transition: color var(--dur) var(--ease), transform var(--dur-slow) var(--ease-out);
}

.sector__index {
    font-family: var(--font-sans);
    font-size: var(--t-micro);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--track-label);
    color: var(--fg-3);
    flex: none;
}

.sector__meta {
    font-size: var(--t-micro);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--fg-3);
    white-space: nowrap;
    transition: color var(--dur) var(--ease);
}

/* Progressive disclosure with no script: the summary row has zero height
   until the row is approached. */
.sector__body {
    grid-column: 1 / -1;
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--dur-slow) var(--ease-out);
}

.sector__link:focus-visible .sector__body {
    grid-template-rows: 1fr;
}

/* Nothing to hover with, so the summary is simply open. This used to be keyed
   to a breakpoint, which got it right for phones and wrong for every pointer
   device that happened to be narrow. */
@media (hover: none) {
    .sector__body {
        grid-template-rows: 1fr;
    }
}

.sector__summary {
    overflow: hidden;
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
    max-width: 64ch;
}

.sector__link:focus-visible .sector__name {
    color: #ffffff;
    transform: translateX(var(--s-4));
}

/* Frameworks: an index set on rules, not a row of pills. */
.frameworks {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-8) var(--gutter);
    margin-top: var(--chapter-tight);
    align-items: start;
}

.frameworks__list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2) 0;
    align-self: start;
}

.frameworks__list li {
    font-size: var(--t-small);
    font-weight: var(--w-medium);
    color: var(--fg-2);
    padding-inline: var(--s-5);
    border-inline-start: var(--hair) solid var(--rule-2);
    line-height: 1.5;
}

.frameworks__list li:first-child {
    padding-inline-start: 0;
    border-inline-start: 0;
}

/* --- 07 Principal ------------------------------------------------------- */

.principal__body {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-10) var(--s-16);
    margin-top: var(--s-10);
    padding-top: var(--s-8);
    border-top: 2px solid var(--rule-2);
    align-items: start;
}

/* The signature block. The name carries the chapter, so it is the display
   element rather than the firm's positioning paragraph. */
.principal__signature {
    display: grid;
    gap: var(--s-3);
    align-content: start;
    position: sticky;
    top: calc(var(--chrome-top) + var(--s-10));
}

.principal__name {
    font-family: var(--font-display);
    font-size: var(--t-d1);
    line-height: 1.02;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
    max-width: 12ch;
}

.principal__role {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

.principal__statement {
    font-size: var(--t-lede-lg);
    line-height: 1.5;
    letter-spacing: var(--track-tight);
    color: var(--fg);
    max-width: 54ch;
}

.principal__bio {
    display: grid;
    gap: var(--s-5);
    margin-top: var(--s-8);
    padding-top: var(--s-6);
    border-top: var(--hair) solid var(--rule);
    font-size: var(--t-body);
    line-height: var(--lead-loose);
    color: var(--fg-2);
    max-width: 62ch;
}

.principal__foot {
    margin-top: var(--s-6);
}

/* --- 08 Publication ----------------------------------------------------- */

.publication__mast {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: var(--s-6) var(--gutter);
    padding-bottom: var(--s-6);
    border-bottom: 2px solid var(--fg);
}

.publication__title {
    max-width: 18ch;
}

.publication__body {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: var(--s-12) var(--s-16);
    padding-top: var(--s-12);
}

.feature__meta,
.story__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-3);
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--fg-3);
}

.feature__title {
    display: block;
    margin-top: var(--s-5);
    font-family: var(--font-display);
    font-size: var(--t-d1);
    line-height: 1.08;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
    max-width: 20ch;
    transition: color var(--dur) var(--ease);
}

.feature__title:hover {
    color: var(--accent);
}

.feature__summary {
    margin-top: var(--s-6);
    font-size: var(--t-lede);
    line-height: 1.66;
    color: var(--fg-2);
    max-width: 54ch;
}

.stories {
    display: grid;
    align-content: start;
}

.story {
    padding-block: var(--s-6);
    border-top: var(--hair) solid var(--rule);
}

.story:first-child {
    border-top: 0;
    padding-block-start: 0;
}

.story__title {
    display: block;
    margin-top: var(--s-3);
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.24;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
    transition: color var(--dur) var(--ease);
}

.story__title:hover {
    color: var(--accent);
}

.story__summary {
    margin-top: var(--s-3);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-3);
}

.publication__foot {
    margin-top: var(--s-10);
}

/* --------------------------------------------------------------------------
   Everything the interior pages are built from. Same three primitives as the
   homepage — the rule, the ascent, the field — and the same discipline: no
   component draws a box, and every one of them reads its colour from the
   surface it is placed on.
   -------------------------------------------------------------------------- */

/* --- Container aliases --------------------------------------------------- */
/* The interior templates were written against `container`; it is the same
   object as `wrap`, kept so one name change does not touch every view. */

.container {
    width: 100%;
    max-width: var(--w-page);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.container--wide {
    max-width: var(--w-wide);
}

.container--narrow {
    max-width: calc(var(--w-text) + var(--gutter) * 2);
}

/* --- Sections ------------------------------------------------------------ */

.section {
    padding-block: var(--chapter);
    position: relative;
    background-color: var(--bg);
    color: var(--fg);
}

.section--tight {
    padding-block: var(--chapter-tight);
}

/* The masthead already closes on a full measure of space, so the first section
   after it starts tight rather than adding a second one. */
.mast + .section,
.mast + .section-index + .section,
.mast + .article-layout {
    padding-block-start: var(--chapter-tight);
}

.section--ruled {
    border-top: var(--hair) solid var(--rule);
}

/* Legacy field names, expressed through the surface system so they inherit
   every component rule rather than needing their own overrides. */
.section--ink,
.surface--ink,
.surface--brand {
    --bg: var(--ink-050);
    --fg: #ffffff;
    --fg-2: var(--haze);
    --fg-3: var(--mist);
    --rule: rgba(255, 255, 255, 0.15);
    --rule-2: rgba(255, 255, 255, 0.34);
    --accent: var(--signal-lift);
    background-color: var(--bg);
    color: var(--fg);
}

.section--sunken,
.surface--sand {
    --bg: var(--limestone);
    --rule: rgba(16, 21, 29, 0.16);
    --rule-2: rgba(16, 21, 29, 0.34);
    background-color: var(--bg);
    color: var(--fg);
}

/* --- Page masthead ------------------------------------------------------- */
/* The interior signature: a full ink field, the trail as a hairline rail, the
   title at hero scale, and — where a page has framing facts — a hanging
   ledger beneath a full-width rule instead of a panel in a box. */

.mast {
    position: relative;
    overflow: clip;
    /* No floor. A masthead is exactly as tall as what it carries. A minimum
       padded the short pages — legal went from 39% of the viewport to 52% — by
       adding empty field above the content, which is the one thing this site
       must not do. */
    display: flex;
    align-items: flex-end;
    background: var(--ink-050);
    color: #ffffff;
    --fg: #ffffff;
    --fg-2: var(--haze);
    --fg-3: var(--mist);
    --rule: rgba(255, 255, 255, 0.15);
    --rule-2: rgba(255, 255, 255, 0.32);
    --accent: var(--signal-lift);
    --bg: var(--ink-050);
    padding-block: calc(var(--chrome-header) + var(--open-pad)) var(--open-pad);
}

.mast__field {
    position: absolute;
    inset: 0;
    z-index: var(--z-field);
    overflow: hidden;
    background:
        radial-gradient(140% 110% at 90% -8%, rgba(15, 76, 129, 0.3) 0%, rgba(15, 76, 129, 0.05) 44%, rgba(15, 76, 129, 0) 68%),
        linear-gradient(174deg, var(--ink-100) 0%, var(--ink-000) 86%);
    pointer-events: none;
}

/* The drafting grid, on the same working measure as the homepage. It is the
   reason both fields read as constructed rather than as a gradient. */
.mast__grid {
    position: absolute;
    inset-block: 0;
    inset-inline: 0;
    max-width: var(--w-wide);
    margin-inline: auto;
    padding-inline: var(--gutter);
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
}

.mast__grid span {
    border-left: var(--hair) solid rgba(255, 255, 255, 0.028);
}

.mast__grid span:last-child {
    border-right: var(--hair) solid rgba(255, 255, 255, 0.028);
}

.mast__inner {
    position: relative;
    z-index: var(--z-content);
    container-type: inline-size;
}

.mast__title {
    margin-block: 8rem;
    font-size: clamp(2.25rem, 7.4cqw, 6.5rem);
    font-weight: var(--w-semibold);
}

/* --- An article opens like an article ------------------------------------
   Every other page opens on a masthead built to introduce a SECTION: a headline
   at 6.5rem with 8rem of field above and below it, because that page is a
   destination and the headline is the whole message.

   An article is not a destination, it is something to read. Its headline is a
   sentence rather than a label, its byline and date are part of the story
   rather than framing facts, and a reader who followed a link from a search
   result wants the first paragraph, not a second full screen of field before
   it. Opening the same way put the article's own opening line roughly a
   viewport and a half from the top.

   Same ink field, same grid, same photograph rules — nothing here changes what
   a masthead IS, only how much room it takes on the one page type where the
   content below it is the point. Keyed off `data-page-type`, which the layout
   already sets, rather than a `.mast--` variant: the suite refuses those,
   because a light masthead was tried once and read as three different
   websites. */

body[data-page-type="article"] .mast {
    padding-block: calc(var(--chrome-header) + var(--s-10)) var(--s-10);
}

body[data-page-type="article"] .mast__title {
    margin-block: var(--s-6) var(--s-5);
    /* A sentence, set to be read. The section mastheads run to 6.5rem; an
       article headline that long wraps to three lines of display type before
       the reader has reached a word of the article. */
    font-size: clamp(1.875rem, 4.4cqw, 3.25rem);
    max-width: 24ch;
}

body[data-page-type="article"] .mast__baseline {
    margin-top: var(--s-5);
    padding-top: var(--s-5);
}

body[data-page-type="article"] .mast__lede {
    font-size: var(--t-lede);
    max-width: 62ch;
}

body[data-page-type="article"] .mast__facts {
    margin-top: var(--s-5);
    padding-top: var(--s-5);
}

.mast__baseline {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    /* Both columns start on the rule, exactly as they do on the homepage. */
    align-items: start;
    gap: var(--s-8) var(--gutter);
    margin-top: var(--s-8);
    padding-top: var(--s-8);
    border-top: var(--hair) solid var(--rule);
}

.mast__lede {
    font-size: var(--t-lede);
    line-height: 1.62;
    color: rgba(255, 255, 255, 0.74);
    max-width: 54ch;
}

.mast__actions {
    justify-content: flex-end;
}

/* A page with no call to action and nothing else to say has nothing to put in
   the right column, so the lede takes the whole row rather than leaving the
   field half empty. An aside counts as something to say. */
.mast__baseline:not(:has(.mast__actions)):not(:has(.mast__aside)) {
    grid-template-columns: minmax(0, 1fr);
}

.mast__baseline:not(:has(.mast__actions)):not(:has(.mast__aside)) .mast__lede {
    max-width: 78ch;
}

/* --- What has just been published ----------------------------------------
   The Insights opening is taller than the viewport, so nothing on the first
   screen said whether anything had been published at all: the newest article,
   the archive and the subject rail are all below the fold, and a visitor has no
   reason to suspect them.

   This occupies the column a page with a call to action uses for its button,
   which on that page was blank. Nothing the opening already renders moves or
   changes — the headline, the lede, the framing facts and the height are all
   exactly as they were.

   It is quiet on purpose. The headline is set at reading size against a display
   headline four times larger, so it reads as a note pinned to the opening
   rather than a second thing competing with it. */

/* ON THE SAME GRID AS THE FRAMING FACTS BELOW IT.
   `justify-self: end` in a two-column row put its left edge wherever its own
   text happened to end — 128px inside the last facts column, so the opening
   showed three different vertical alignments stacked on top of each other and
   read as disjointed.

   The baseline row therefore takes the facts' three-column grid whenever it
   carries an aside: the lede spans the first two columns, the aside occupies
   the third. Its left edge lands on the third column's, its right edge on the
   container's, and the two rows below share one set of vertical lines. */
/* The aside takes the whole row: the lede has moved up under the title, so
   there is nothing to share it with and no reason to leave two thirds empty. */
.mast__baseline:has(.mast__aside) {
    grid-template-columns: minmax(0, 1fr);
    /* The opening is already taller than the viewport; every gap above this
       block pushes the one element that says something was published further
       off the screen. */
    margin-top: var(--s-6);
    padding-top: var(--s-6);
}

/* Under the title, at reading size and out of the way. The opening's job on
   this page is to say what was published; the lede explains what the section is
   for, which is worth saying once and quietly. */
.mast__lede--quiet {
    margin-top: var(--s-5);
    max-width: 74ch;
    font-size: var(--t-body);
    color: var(--fg-2);
}

/* PROMINENT ENOUGH TO BE SEEN, not so loud it argues with the headline.
   The first version was set at reading size with no surface of its own, and it
   read as a footnote pinned to the opening: technically present, effectively
   invisible against a display headline four times its size.

   Three things give it presence without a second display face on the screen: a
   short accent rule that starts the block, the headline at `--t-d3` — the same
   size the archive index uses for an article, so it reads as an article rather
   than a caption — and an explicit action. The accent rule is the loudest thing
   in the opening apart from the headline itself, which is the point: it is the
   only element on the first screen that says something was published. */
/* ONE DEFINITION. This was written twice — a base and a later "make it
   prominent" override — and the override was inserted ABOVE the base, so the
   base won and the headline stayed at reading size while the CSS claimed
   otherwise. */
.mast__aside {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    column-gap: var(--gutter);
    /* A FIELD CHANGE, NOT A BORDER OR A SHADOW. The design system rules both of
       those out for depth and says to change the field instead, so the block
       sits on a slightly lifted plane: enough to separate it from the
       photograph behind it, not enough to become a card on a page that has
       none. */
    background: rgba(255, 255, 255, 0.05);
    border-top: 3px solid var(--accent);
    padding: var(--s-4) var(--s-5) var(--s-4);
}

.mast__aside-label {
    grid-column: 1;
    margin: 0 0 var(--s-2);
    font-size: var(--t-nano);
    font-weight: var(--w-bold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--accent);
}

.mast__aside-title {
    grid-column: 1;
    margin: 0;
    font-family: var(--font-display);
    /* Display size. The point of the block is that somebody sees it. */
    font-size: var(--t-d2);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-tight);
    line-height: 1.14;
    text-wrap: pretty;
}

.mast__aside-title a {
    color: var(--fg);
    text-decoration: none;
    background-image: linear-gradient(var(--accent), var(--accent));
    background-repeat: no-repeat;
    background-position: 0 100%;
    background-size: 0 var(--hair);
    transition: background-size var(--ease-quick);
}

.mast__aside-title a:hover {
    background-size: 100% var(--hair);
}

.mast__aside-meta {
    grid-column: 1;
    margin: var(--s-2) 0 0;
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

/* THE ACTION USES THE WIDTH. The block spans the whole row, so putting every
   part of it on the left left two thirds of a lifted plane empty and the thing
   read as unfinished. It sits on the baseline of the headline instead. */
.mast__aside-action {
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: center;
    display: inline-block;
    font-size: var(--t-small);
    font-weight: var(--w-semibold);
    color: var(--fg);
    text-decoration: none;
    white-space: nowrap;
    padding-bottom: 0.55em;
    background-image: linear-gradient(var(--accent), var(--accent));
    background-repeat: no-repeat;
    background-position: left bottom;
    background-size: 100% var(--hair);
    transition: background-size var(--dur) var(--ease);
}

.mast__aside-action::after {
    content: " \2192";
}

.mast__aside-action:hover {
    background-size: 100% 2px;
}

/* Only the ink masthead needs the inverted outline; on the light tones the
   button's own surface-derived colours are already right. */
.mast .btn--secondary {
    --btn-line: rgba(255, 255, 255, 0.34);
    --btn-fg: #ffffff;
    --btn-fill: #ffffff;
}

.mast .btn--secondary:hover,
.mast .btn--secondary:focus-visible {
    color: var(--ink-050);
    border-color: #ffffff;
}

/* The framing facts, hung under one rule. */
.mast__facts {
    display: grid;
    /* One row, as many columns as there are facts. A fixed three-column
       template left a fourth fact wrapping onto a row of its own, which read
       as an afterthought rather than a ledger. Column flow sizes the row to
       its content: three facts get thirds, four get quarters. */
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: var(--s-8) var(--gutter);
    margin-top: var(--s-8);
    padding-top: var(--s-8);
    border-top: var(--hair) solid var(--rule);
}

.mast__fact dt {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

.mast__fact dd {
    margin: var(--s-3) 0 0;
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

/* --- Breadcrumbs --------------------------------------------------------- */

.breadcrumbs ol {
    display: flex;
    align-items: center;
    gap: var(--s-2) var(--s-3);
    font-size: .75rem;
    font-weight: var(--w-medium);
    color: var(--fg-3);
}

.breadcrumbs li + li::before {
    content: "/";
    margin-inline-end: var(--s-3);
    color: var(--rule-2);
}

.breadcrumbs a:hover {
    color: var(--fg);
}

.breadcrumbs--inline {
    margin-bottom: var(--s-10);
    padding-bottom: var(--s-4);
    border-bottom: var(--hair) solid var(--rule);
}

/* --- In-page index ------------------------------------------------------- */

.section-index {
    position: sticky;
    top: var(--chrome-header);
    z-index: 20;
    background: var(--ink-000);
    color: #ffffff;
    border-block: var(--hair) solid rgba(255, 255, 255, 0.12);
}

.section-index__inner {
    display: flex;
    align-items: center;
    gap: var(--s-6);
    height: 3.25rem;
    overflow-x: auto;
    scrollbar-width: none;
}

.section-index__inner::-webkit-scrollbar {
    display: none;
}

.section-index__label {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--mist);
    white-space: nowrap;
    flex: none;
}

.section-index__link {
    position: relative;
    font-size: var(--t-micro);
    font-weight: var(--w-medium);
    color: rgba(255, 255, 255, 0.66);
    white-space: nowrap;
    flex: none;
    padding-block: var(--s-2);
    transition: color var(--dur) var(--ease);
}

.section-index__link::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    inset-block-end: 0;
    height: var(--hair);
    background: var(--signal-lift);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--dur) var(--ease-out);
}

.section-index__link:hover,
.section-index__link[aria-current="true"] {
    color: #ffffff;
}

.section-index__link:hover::after,
.section-index__link[aria-current="true"]::after {
    transform: scaleX(1);
}

/* --- Section headers and shared grids ------------------------------------ */

.section-header {
    display: grid;
    align-content: start;
    gap: var(--s-5);
    max-width: 34ch;
}

.section-header--wide {
    max-width: 52ch;
}

@media (min-width: 56.0625rem) {
    /* ONE SPINE, 4fr / 7fr. `.grid--split`, `.sticky-split` and
       `.index-list__link` all split there, and this header split at 5fr / 6fr
       — so a section whose header sat above a list or a split grid started its
       second column 117px to the right of the column it introduced. Three
       origins were visible on one screen. The ratio is a site-wide decision,
       not a per-component one, and there is now one of them. */
    :not(.head-row) > .section-header--wide {
        max-width: none;
        grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
        column-gap: var(--gutter);
        align-items: start;
    }

    /* The label runs across the top; the heading and the sentence share the
       row beneath it. Hanging the sentence off the label's row instead left it
       floating beside a caption with the heading orphaned underneath. */
    :not(.head-row) > .section-header--wide > .label {
        grid-column: 1 / -1;
        grid-row: 1;
    }

    :not(.head-row) > .section-header--wide > h2 {
        grid-column: 1;
        grid-row: 2;
    }

    :not(.head-row) > .section-header--wide > p {
        grid-column: 2;
        grid-row: 2;
        max-width: 56ch;
    }
}

/* Above a full-width block — a form, a table — the header has the whole column
   to work with, so it is not capped at a rail measure that makes the sentence
   look truncated a third of the way across. */
.section-header--full {
    max-width: none;
}

.section-header--full p {
    max-width: 68ch;
}

.section-header p {
    font-size: var(--t-lede);
    line-height: 1.62;
    color: var(--fg-2);
}

.head-row {
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    justify-content: space-between;
    gap: var(--s-6) var(--gutter);
    padding-bottom: var(--s-8);
    border-bottom: var(--hair) solid var(--rule);
}

.grid {
    display: grid;
    gap: var(--s-12) var(--gutter);
}

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

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

.grid--split {
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
}

.sticky-split {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-12) var(--gutter);
    align-items: start;
}

.sticky-split__aside,
.grid--split > .section-header {
    position: sticky;
    top: calc(var(--chrome-top) + var(--s-10));
}

.stack-6 { display: grid; gap: var(--s-6); }
.stack-8 { display: grid; gap: var(--s-8); }
.stack-12 { display: grid; gap: var(--s-12); }

/* --- Typographic utilities used by the interior pages -------------------- */

.eyebrow {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

.subheading {
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.2;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
}

/* The direct answer to the question a section asks. Set larger than body and
   never more than a few lines, because it is the thing being answered. */
.answer {
    font-size: var(--t-lede);
    line-height: 1.6;
    color: var(--fg);
    max-width: 62ch;
}

.statement {
    font-family: var(--font-display);
    font-size: var(--t-d2);
    line-height: 1.22;
    letter-spacing: var(--track-display);
    font-weight: var(--w-medium);
    max-width: 30ch;
}

.text-muted { color: var(--fg-3); }

.mt-5 { margin-top: var(--s-5); }

/* The one link affordance: a label over a rule that draws in. */
.link-arrow {
    display: inline-block;
    font-size: var(--t-small);
    font-weight: var(--w-semibold);
    color: var(--fg);
    padding-bottom: 0.55em;
    background-image: linear-gradient(var(--accent), var(--accent)), linear-gradient(var(--rule-2), var(--rule-2));
    background-size: 0% var(--hair), 100% var(--hair);
    background-position: left bottom, left bottom;
    background-repeat: no-repeat;
    transition: background-size var(--dur-slow) var(--ease-out), color var(--dur) var(--ease);
}

.link-arrow:hover,
.link-arrow:focus-visible {
    color: var(--accent);
    background-size: 100% var(--hair), 100% var(--hair);
}

.link-arrow--back::before {
    content: "\2190";
    margin-inline-end: 0.5em;
}

/* --- Editorial split (the leadgap composition) --------------------------- */

.leadgap__inner {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-12) var(--gutter);
    align-items: start;
}

.leadgap__aside {
    position: sticky;
    top: calc(var(--chrome-top) + var(--s-10));
    display: grid;
    gap: var(--s-6);
}

.leadgap__statement {
    font-size: var(--t-lede);
    line-height: 1.62;
    color: var(--fg-2);
}

.leadgap__list {
    display: grid;
}

.leadgap__item {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-2) var(--gutter);
    padding-block: var(--s-6);
    border-top: var(--hair) solid var(--rule);
}

.leadgap__item:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.leadgap__term {
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.24;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
}

.leadgap__text {
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

/* --- Qualifier: a hanging statement, not a tinted box -------------------- */

.qualifier {
    padding-top: var(--s-5);
    border-top: var(--hair) solid var(--rule);
}

.qualifier--emphasis {
    border-top-width: 2px;
    border-top-color: var(--accent);
}

.qualifier__title {
    font-family: var(--font-sans);
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

.qualifier__text {
    margin-top: var(--s-4);
    font-size: var(--t-body);
    line-height: var(--lead-loose);
    color: var(--fg-2);
    max-width: 66ch;
}

/* --- Checklist ----------------------------------------------------------- */

.checklist {
    display: grid;
}

.checklist li {
    position: relative;
    padding-block: var(--s-4);
    padding-inline-start: var(--s-8);
    border-top: var(--hair) solid var(--rule);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.checklist li:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.checklist li::before {
    content: "";
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: 1.55em;
    width: var(--s-4);
    height: var(--hair);
    background: var(--accent);
}

/* --- Responsibility model ------------------------------------------------ */
/* Thirteen items on a rule grid. The anchor is not a bigger box: it is the one
   item set at display scale and given the accent rule. */

.respmodel {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--gutter);
}

.respmodel__cell {
    padding-block: var(--s-6);
    border-top: var(--hair) solid var(--rule);
}

.respmodel__cell--anchor {
    grid-column: 1 / -1;
    border-top: 2px solid var(--accent);
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-3) var(--gutter);
    align-items: baseline;
    padding-block: var(--s-8);
}

.respmodel__index {
    display: block;
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--track-label);
    color: var(--fg-3);
}

.respmodel__cell--anchor .respmodel__index {
    color: var(--accent);
}

.respmodel__title {
    margin-top: var(--s-3);
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.22;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
}

.respmodel__cell--anchor .respmodel__title {
    font-size: var(--t-d2);
    letter-spacing: var(--track-display);
    grid-row: 2;
}

.respmodel__body {
    margin-top: var(--s-3);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.respmodel__cell--anchor .respmodel__body {
    grid-column: 2;
    grid-row: 2;
    margin-top: 0;
    font-size: var(--t-lede);
    line-height: 1.6;
}

/* --- Verdict: two columns, one decision --------------------------------- */

.verdict {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-12) var(--s-16);
}

.verdict__column {
    border-top: 2px solid var(--rule-2);
    padding-top: var(--s-5);
}

.verdict__column--yes {
    border-top-color: var(--accent);
}

.verdict__label {
    display: flex;
    align-items: baseline;
    gap: var(--s-3);
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

.verdict__mark {
    font-size: var(--t-micro);
    letter-spacing: var(--track-label);
    color: var(--accent);
}

.verdict__mark--no {
    color: var(--fg-3);
}

.verdict__list {
    display: grid;
    margin-top: var(--s-4);
}

.verdict__item {
    display: grid;
    grid-template-columns: 2rem minmax(0, 1fr);
    gap: var(--s-3);
    padding-block: var(--s-4);
    border-top: var(--hair) solid var(--rule);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.verdict__num {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    color: var(--fg-3);
    padding-top: 0.35em;
}

/* --- Trigger matrix ------------------------------------------------------ */

.matrix {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--gutter);
}

.matrix__cell {
    padding-block: var(--s-8);
    border-top: var(--hair) solid var(--rule);
}

.matrix__num {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--track-label);
    color: var(--accent);
}

.matrix__title {
    margin-top: var(--s-4);
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: 1.14;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
}

.matrix__body {
    margin-top: var(--s-4);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

/* --- Stage timeline ------------------------------------------------------ */

.stages {
    display: grid;
}

/* A LEDGER, NOT FIVE NARROW COLUMNS.
   Five phases across the width gave every one a 250px measure, so each of them
   broke into eight short lines while the top half of the section sat empty.
   One row per phase uses the whole width and reads at a normal measure. */
.stage {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 3fr) minmax(0, 6fr);
    gap: var(--s-3) var(--gutter);
    align-items: baseline;
    padding-block: var(--s-6);
    border-top: var(--hair) solid var(--rule);
}

.stage:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.stage > div {
    display: grid;
    gap: var(--s-2);
    align-content: start;
}

.stage__num {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--track-label);
    color: var(--fg-3);
}

.stage__timing {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--accent);
}

.stage__title {
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: 1.18;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
}

.stage__body {
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

/* Legacy horizontal sequence, same object at a smaller scale. */
.stageline {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--gutter);
}

.stageline__step {
    padding-top: var(--s-5);
    border-top: var(--hair) solid var(--rule);
}

.stageline__num {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--track-label);
    color: var(--accent);
}

.stageline__title {
    margin-top: var(--s-4);
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.2;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
}

.stageline__text {
    margin-top: var(--s-3);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

/* --- Comparison ---------------------------------------------------------- */

.compare {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 4fr) minmax(0, 4fr);
    column-gap: var(--gutter);
}

/* EVERY CELL IS PLACED EXPLICITLY.
   The markup is a flat sequence — two headings, then dimension/vCISO/CISO
   repeating — so with only the headings placed by hand, auto-placement dropped
   the first dimension into the empty cell beside them and shifted every answer
   in the table one column to the left: the first vCISO answer rendered under
   the dimension, and the first full-time cell rendered empty.

   The spacer holds row 1, column 1, and each cell type names its own column, so
   the first free row for each is row 2 and the table cannot slip again. */
.compare::before {
    content: "";
    grid-row: 1;
    grid-column: 1;
}

.compare__head {
    grid-row: 1;
    grid-column: 2;
    padding-bottom: var(--s-4);
    border-bottom: 2px solid var(--accent);
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg);
}

.compare__head--b {
    grid-column: 3;
    border-bottom-color: var(--rule-2);
    color: var(--fg-3);
}

.compare__cell {
    grid-column: 2;
}

.compare__cell--b {
    grid-column: 3;
}

.compare__dimension {
    grid-column: 1;
    padding-block: var(--s-5);
    border-top: var(--hair) solid var(--rule);
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.24;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
}

.compare__cell {
    padding-block: var(--s-5);
    border-top: var(--hair) solid var(--rule);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.compare__cell--b {
    color: var(--fg-3);
}

/* --- Definition lists ---------------------------------------------------- */

.definitions {
    display: grid;
}

.definitions > div {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-2) var(--gutter);
    padding-block: var(--s-5);
    border-top: var(--hair) solid var(--rule);
}

.definitions > div:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.definitions dt {
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.24;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
}

.definitions dd {
    margin: 0;
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

/* --- Capability ledger --------------------------------------------------- */

.capability {
    display: grid;
}

.capability__row {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-5) var(--gutter);
    padding-block: var(--s-8);
    border-top: var(--hair) solid var(--rule);
}

.capability__row:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.capability__name {
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: 1.14;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
}

.capability__summary {
    margin-top: var(--s-3);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-3);
}

.capability__services {
    display: grid;
    align-content: start;
}

.capability__services a {
    display: block;
    padding-block: var(--s-3);
    border-top: var(--hair) solid var(--rule);
    font-family: var(--font-display);
    font-size: var(--t-d4);
    letter-spacing: var(--track-tight);
    font-weight: var(--w-medium);
    color: var(--fg-2);
    transition: color var(--dur) var(--ease), transform var(--dur-slow) var(--ease-out);
}

.capability__services li:first-child a {
    border-top: 0;
}

.capability__services a:hover {
    color: var(--fg);
    transform: translateX(var(--s-3));
}

/* --- Index list ---------------------------------------------------------- */

.index-list {
    display: grid;
}

/* THE CUE IS NOT A COLUMN. It was a third `auto` track, so it took its own
   width plus a gutter out of the row before the 4fr / 7fr split was measured —
   this list declared the site spine and then landed 29px to the left of it. It
   is an affordance at the row's edge, not content, so it hangs off the row
   instead of sizing it, and the two text columns get the full measure. */
.index-list__link {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    align-items: baseline;
    gap: var(--s-2) var(--gutter);
    padding-block: var(--s-6);
    border-top: var(--hair) solid var(--rule);
    transition: padding-inline-start var(--dur-slow) var(--ease-out);
}

.index-list__item:last-child .index-list__link {
    border-bottom: var(--hair) solid var(--rule);
}

.index-list__link:hover {
    padding-inline-start: var(--s-4);
}

.index-list__name {
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: 1.14;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
    transition: color var(--dur) var(--ease);
}

.index-list__link:hover .index-list__name {
    color: var(--accent);
}

.index-list__summary {
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
    /* Clearance for the cue, taken inside the track so the column origin does
       not move. Padding on the link itself would shrink the grid's content box
       and walk the split back off the spine. */
    padding-inline-end: var(--s-8);
}

/* Set like the summary so its first line box lands on the summary's, which is
   where it sat when it was a grid item on the baseline. */
.index-list__cue {
    position: absolute;
    inset-inline-end: 0;
    top: var(--s-6);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-3);
    transition: transform var(--dur) var(--ease-out);
}

.index-list__link:hover .index-list__cue {
    transform: translateX(var(--s-2));
    color: var(--accent);
}

/* --- FAQ ----------------------------------------------------------------- */

.faq {
    display: grid;
}

.faq__item {
    border-top: var(--hair) solid var(--rule);
}

.faq__item:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.faq__question {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-6);
    padding-block: var(--s-5);
    cursor: pointer;
    list-style: none;
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.3;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
    transition: color var(--dur) var(--ease);
}

.faq__question::-webkit-details-marker {
    display: none;
}

.faq__question::after {
    content: "";
    flex: none;
    width: var(--s-4);
    height: var(--s-4);
    background:
        linear-gradient(currentColor, currentColor) center/100% var(--hair) no-repeat,
        linear-gradient(currentColor, currentColor) center/var(--hair) 100% no-repeat;
    transition: transform var(--dur) var(--ease-out);
    transform: translateY(0.35em);
}

.faq__item[open] .faq__question::after {
    transform: translateY(0.35em) rotate(90deg);
    background:
        linear-gradient(currentColor, currentColor) center/100% var(--hair) no-repeat;
}

.faq__question:hover {
    color: var(--accent);
}

.faq__answer {
    display: grid;
    gap: var(--s-4);
    padding-bottom: var(--s-6);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
    max-width: 72ch;
}

/* --- Ecosystem ----------------------------------------------------------- */

.ecosystem__hub {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-3) var(--gutter);
    align-items: baseline;
    padding-bottom: var(--s-8);
    border-bottom: 2px solid var(--accent);
}

.ecosystem__hub-title {
    font-family: var(--font-display);
    font-size: var(--t-d2);
    line-height: 1.1;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
}

.ecosystem__hub-body {
    font-size: var(--t-lede);
    line-height: 1.6;
    color: var(--fg-2);
}

.ecosystem__nodes {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    column-gap: var(--gutter);
}

.ecosystem__node {
    padding-block: var(--s-6);
    border-top: var(--hair) solid var(--rule);
}

.ecosystem__node-title {
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.22;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
}

.ecosystem__node-body {
    margin-top: var(--s-3);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.ecosystem__link {
    display: inline-block;
    margin-top: var(--s-4);
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--accent);
}

.ecosystem__link:hover {
    color: var(--fg);
}

/* --- Obligation map ------------------------------------------------------ */

.ob-map {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 2fr) minmax(0, 5fr);
    align-items: center;
    gap: var(--gutter);
}

.ob-map__label,
.ob-map__target-title {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
    padding-bottom: var(--s-4);
}

.ob-map__list {
    display: grid;
}

.ob-map__item {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-4);
    padding-block: var(--s-4);
    border-top: var(--hair) solid var(--rule);
}

.ob-map__item:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.ob-map__name {
    font-family: var(--font-display);
    font-size: var(--t-d4);
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
}

.ob-map__kind {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--fg-3);
}

.ob-map__wires {
    width: 100%;
    height: 12rem;
    overflow: visible;
}

.ob-map__wire {
    fill: none;
    stroke: var(--rule-2);
    stroke-width: 0.4;
    vector-effect: non-scaling-stroke;
}

.ob-map__pulse {
    fill: none;
    stroke: var(--accent);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}

.ob-map__target {
    border-top: 2px solid var(--accent);
    padding-top: var(--s-5);
}

.ob-map__target-title {
    padding-bottom: 0;
    color: var(--accent);
}

.ob-map__target-body {
    margin-top: var(--s-3);
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: 1.2;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
}

/* --- Publication: cards, lists and the article page --------------------- */

.insight-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--s-12) var(--gutter);
}

.insight-card {
    display: grid;
    align-content: start;
}

.insight-card__figure {
    display: block;
    margin-bottom: var(--s-6);
}

.insight-card__topic {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

.insight-card__title {
    margin-top: var(--s-3);
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: 1.16;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
}

.insight-card__title a:hover {
    color: var(--accent);
}

.insight-card__summary {
    margin-top: var(--s-4);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.insight-card__byline {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-3);
    margin-top: var(--s-5);
    padding-top: var(--s-4);
    border-top: var(--hair) solid var(--rule);
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--fg-3);
}

/* The generated editorial mark. Brand geometry, one hue, no text. */
.article-graphic {
    display: block;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--limestone);
}

.article-graphic--lead {
    aspect-ratio: 21 / 9;
}

.article-graphic__field {
    width: 100%;
    height: 100%;
    display: block;
}

.article-graphic__peak {
    fill: var(--limestone-deep);
}

.article-graphic__peak--front {
    fill: var(--ink-200);
}

.article-graphic--tone-1 { background: var(--signal-wash); }
.article-graphic--tone-1 .article-graphic__peak { fill: #cfe0ee; }
.article-graphic--tone-1 .article-graphic__peak--front { fill: var(--signal-deep); }

.article-graphic--tone-2 { background: var(--ink-100); }
.article-graphic--tone-2 .article-graphic__peak { fill: rgba(255, 255, 255, 0.08); }
.article-graphic--tone-2 .article-graphic__peak--front { fill: rgba(255, 255, 255, 0.2); }

.article-graphic--tone-3 { background: var(--limestone-deep); }
.article-graphic--tone-3 .article-graphic__peak { fill: #cdc6b6; }
.article-graphic--tone-3 .article-graphic__peak--front { fill: var(--ink-100); }

/* The lead story on the insights index. */







.article-list {
    display: grid;
}

.article-preview {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 8fr);
    gap: var(--s-3) var(--gutter);
    padding-block: var(--s-8);
    border-top: var(--hair) solid var(--rule);
}

.article-preview:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.article-preview__category,
.article-preview__meta {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--fg-3);
}

.article-preview__title {
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: 1.16;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
}

.article-preview__title a:hover {
    color: var(--accent);
}

.article-preview__summary {
    margin-top: var(--s-4);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
    max-width: 70ch;
}

.article-preview__meta {
    margin-top: var(--s-4);
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-4);
}




.pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-4);
    padding-top: var(--s-8);
    border-top: var(--hair) solid var(--rule);
}

/* Position, in the pagination's own quiet type. It is the middle child of the
   space-between row, which is why the empty placeholder spans exist. */
.pagination__range {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
    color: var(--fg-3);
}
/* --- The article itself -------------------------------------------------- */

.article-layout__inner {
    display: grid;
    grid-template-columns: minmax(0, 8fr) minmax(0, 3fr);
    gap: var(--s-16);
    align-items: start;
}

/* The body leads and the rail supports it, whatever the source order: the
   rail comes first in the document so that a small screen gets the contents
   before the article, and last in the composition so that reading starts at
   the left margin. */
.article-body {
    grid-column: 1;
    grid-row: 1;
}

.article-rail {
    grid-column: 2;
    grid-row: 1;
}

/* Article prose. The one place on the site set larger than body copy, because
   it is the only place somebody reads a thousand words in a row. */
.article-body .prose {
    max-width: 68ch;
    font-size: 1.125rem;
    line-height: 1.78;
    color: var(--fg);
}

.article-body .prose > * + * {
    margin-top: var(--s-6);
}

.article-body .prose h2 {
    margin-top: var(--s-16);
    padding-top: var(--s-5);
    border-top: var(--hair) solid var(--rule);
    font-size: var(--t-d2);
    line-height: 1.16;
    letter-spacing: var(--track-display);
    color: var(--fg);
}

.article-body .prose h3 {
    margin-top: var(--s-10);
    font-size: var(--t-d3);
    line-height: 1.24;
    color: var(--fg);
}

.article-body .prose blockquote {
    padding-inline-start: var(--s-8);
    border-inline-start: 2px solid var(--accent);
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: 1.32;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-medium);
    color: var(--fg);
}

.prose {
    max-width: 68ch;
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.prose > * + * {
    margin-top: var(--s-5);
}

.prose h2 {
    margin-top: var(--s-12);
    font-size: var(--t-d3);
    color: var(--fg);
}

.prose h3 {
    margin-top: var(--s-8);
    font-size: var(--t-d4);
    color: var(--fg);
}

.prose ul,
.prose ol {
    display: grid;
    gap: var(--s-2);
    padding-inline-start: var(--s-6);
    list-style: disc;
}

.prose ol { list-style: decimal; }

.prose a {
    color: var(--accent);
    text-decoration: underline;
    text-underline-offset: 0.2em;
}

/* The measure belongs to the prose, not to the section. Capping the section
   left it 72ch wide at the left edge of the page, with its own container
   centring inside that — so the legal pages started 120px left of every other
   page on the site. */
/* The legal pages read at the same left margin as every other page. They used
   to centre inside a narrow container, which put the text 370px right of the
   masthead above it and made the page look like it belonged to another site.

   Legal prose has to stay at a reading measure, so the width the measure does
   not use carries the document's contents rather than being left blank. */
.legal-body__inner {
    display: grid;
    grid-template-columns: minmax(0, 8fr) minmax(0, 3fr);
    gap: var(--s-12) var(--s-16);
    align-items: start;
}

.legal-body .prose {
    max-width: 68ch;
}

.legal-body__rail {
    position: sticky;
    top: calc(var(--chrome-top) + var(--s-10));
}

.legal-body__rail .article-rail__toc {
    counter-reset: legal;
}

.legal-body__rail .article-rail__toc li {
    display: grid;
    grid-template-columns: 2rem minmax(0, 1fr);
    gap: var(--s-2);
    counter-increment: legal;
}

.legal-body__rail .article-rail__toc li::before {
    content: counter(legal, decimal-leading-zero);
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--track-label);
    color: var(--fg-3);
    padding-top: 0.15em;
}

@media (max-width: 56rem) {
    .legal-body__inner {
        grid-template-columns: minmax(0, 1fr);
    }

    .legal-body__rail {
        position: static;
        order: -1;
        padding-bottom: var(--s-8);
        border-bottom: var(--hair) solid var(--rule);
    }
}

.callout,
.key-points {
    padding-top: var(--s-5);
    border-top: 2px solid var(--accent);
}

.callout__title,
.key-points__title {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
    margin-bottom: var(--s-4);
}

.key-points ul {
    display: grid;
    gap: var(--s-3);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.article-rail {
    position: sticky;
    top: calc(var(--chrome-top) + var(--s-10));
    display: grid;
    gap: var(--s-10);
}

.article-rail__title {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
    padding-bottom: var(--s-4);
    border-bottom: var(--hair) solid var(--rule);
    margin-bottom: var(--s-4);
}

.article-rail__toc,
.article-rail__links {
    display: grid;
    gap: var(--s-3);
    font-size: var(--t-small);
    color: var(--fg-2);
}

.article-rail__toc a:hover,
.article-rail__links a:hover {
    color: var(--accent);
}

.article-rail__meta {
    font-size: var(--t-micro);
    line-height: var(--lead-loose);
    color: var(--fg-3);
}

/* --- The briefing note ---------------------------------------------------
   An article on this site is read by somebody deciding something, or defending
   a decision they already took. That is a briefing note, not a blog post, and
   three things follow from it.

   THE ANSWER IS FIRST. A reader with thirty seconds gets the conclusion before
   the argument, and an answer engine has one unambiguous passage to lift. It
   sits under a 2px accent rule, the same signal `.key-points` uses, because it
   is the same kind of object: the thing you would say if you could only say
   one.

   SECTIONS ARE NUMBERED. Not decoration: the contents rail and the prose refer
   to each other by number, and the number hangs in the margin so the left edge
   of the reading measure stays straight.

   THE EVIDENCE STANDS BESIDE THE ARGUMENT. Sources used to be a numbered list
   at the foot, which is where a reader arrives after deciding whether to
   believe it. In the rail they are visible for the whole read.
   -------------------------------------------------------------------------- */

.answer {
    max-width: 68ch;
    margin-bottom: var(--s-10);
    padding-top: var(--s-4);
    border-top: 2px solid var(--accent);
}

.answer__label {
    margin: 0 0 var(--s-3);
    font-size: var(--t-nano);
    font-weight: var(--w-bold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--accent);
}

.answer__text {
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--t-d3);
    font-weight: var(--w-medium);
    line-height: 1.35;
    letter-spacing: var(--track-tight);
    color: var(--fg);
    text-wrap: pretty;
}

/* The number hangs, so the headings and the paragraphs share one left edge. */
.prose h2 {
    position: relative;
}

.prose__num {
    position: absolute;
    inset-inline-start: calc(var(--s-8) * -1);
    font-family: var(--font-display);
    font-weight: var(--w-bold);
    font-size: var(--t-small);
    line-height: 2.1;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}

.article-rail__toc a {
    display: grid;
    grid-template-columns: 1.4rem 1fr;
    gap: var(--s-2);
    align-items: baseline;
}

.article-rail__num {
    font-family: var(--font-display);
    font-weight: var(--w-bold);
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}

.evidence {
    display: grid;
    gap: var(--s-4);
    margin: 0;
    padding-inline-start: 0;
    list-style: none;
}

.evidence__item {
    display: grid;
    gap: var(--s-1);
}

/* The publisher first: a reader weighs "NIST" before they read a title. */
.evidence__publisher {
    font-size: var(--t-nano);
    font-weight: var(--w-bold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--fg-3);
}

.evidence__doc {
    font-size: var(--t-small);
    line-height: 1.35;
    color: var(--fg-2);
    text-decoration: none;
    background-image: linear-gradient(var(--accent), var(--accent));
    background-repeat: no-repeat;
    background-position: 0 100%;
    background-size: 0 var(--hair);
    transition: background-size var(--ease-quick);
}

.evidence__doc:hover {
    color: var(--fg);
    background-size: 100% var(--hair);
}

.article-sources__title {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
    margin-bottom: var(--s-5);
}

.article-sources ol {
    display: grid;
    gap: var(--s-3);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.article-sources a {
    color: var(--accent);
}

/* --- Miscellaneous page furniture ---------------------------------------- */

.tag-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2) 0;
    list-style: none;
    padding-inline-start: 0;
}

.tag-list li {
    font-size: var(--t-small);
    font-weight: var(--w-medium);
    color: var(--fg-2);
    padding-inline: var(--s-5);
    border-inline-start: var(--hair) solid var(--rule-2);
    line-height: 1.5;
}

.tag-list li:first-child {
    padding-inline-start: 0;
    border-inline-start: 0;
}

.table-scroll {
    overflow-x: auto;
}

.figure figcaption {
    margin-top: var(--s-4);
    font-size: var(--t-micro);
    color: var(--fg-3);
}

.cta-inline {
    display: grid;
    gap: var(--s-4);
    padding-top: var(--s-6);
    border-top: 2px solid var(--accent);
    max-width: 62ch;
}

.cta-inline__title {
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: 1.2;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
}

.cta-inline p {
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.contact-details {
    display: grid;
    gap: var(--s-5);
}

.contact-details > div {
    padding-top: var(--s-4);
    border-top: var(--hair) solid var(--rule);
}

.contact-details__label {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
    margin-bottom: var(--s-2);
}

.contact-details a:hover {
    color: var(--accent);
}

/* Legacy before/after ledger, kept for the page that still uses it. */
.ledger {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    gap: var(--gutter);
    align-items: start;
}

.ledger__label {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
    padding-bottom: var(--s-4);
    border-bottom: var(--hair) solid var(--rule);
    margin-bottom: var(--s-5);
}

.ledger__side--after .ledger__label {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

.ledger__list {
    display: grid;
    gap: var(--s-4);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.ledger__rule {
    width: var(--hair);
    align-self: stretch;
    background: var(--rule);
}

/* Legacy structures still referenced by a page or two. */
.pillars {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--gutter);
}

.pillar {
    padding-block: var(--s-6);
    border-top: var(--hair) solid var(--rule);
}

.pillar--lead {
    border-top: 2px solid var(--accent);
}

.pillar__mark {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-label);
    color: var(--fg-3);
}

.pillar__title {
    margin-top: var(--s-3);
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: 1.16;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
}

.pillar__body {
    margin-top: var(--s-4);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.process {
    display: grid;
    gap: var(--gutter);
}

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

.process__step {
    padding-top: var(--s-5);
    border-top: var(--hair) solid var(--rule);
}

.process__number {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--track-label);
    color: var(--accent);
}

.process__title {
    margin-top: var(--s-4);
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.2;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
}

.process__body {
    margin-top: var(--s-3);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.rows {
    display: grid;
}

.rows > * {
    display: grid;
    grid-template-columns: 4rem minmax(0, 1fr);
    gap: var(--s-3) var(--gutter);
    align-items: baseline;
    padding-block: var(--s-6);
    border-top: var(--hair) solid var(--rule);
}

.rows > * > div {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-3) var(--gutter);
    align-items: baseline;
}

.rows > *:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.rows--plain > * {
    grid-template-columns: minmax(0, 1fr);
}

.rows__number {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--track-label);
    color: var(--accent);
}

.rows__title {
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.24;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
}

.rows__body {
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

/* Service architecture partial. */
/* The badge labels the flagship, so it sits directly above it. The partial
   wraps the title and the summary in a span; `display: contents` dissolves
   that wrapper so all three are grid items and the badge can no longer be
   stranded a column away from the thing it names. */
.arch__lead {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-3) var(--gutter);
    align-items: start;
    padding-bottom: var(--s-8);
    border-bottom: 2px solid var(--accent);
}

.arch__lead > span:not(.arch__badge) {
    display: contents;
}

.arch__badge {
    grid-column: 1;
    grid-row: 1;
}

.arch__lead-title {
    grid-column: 1;
    grid-row: 2;
}

.arch__lead-body {
    grid-column: 2;
    grid-row: 1 / span 2;
}

/* The partial builds these from spans, which are inline by default: without
   this the title, the summary and the tier role all ran together on one line. */
.arch__badge,
.arch__lead-title,
.arch__lead-body,
.arch__tier-title,
.arch__tier-role {
    display: block;
}

.arch__lead-title {
    font-family: var(--font-display);
    font-size: var(--t-d2);
    line-height: 1.1;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
}

.arch__lead-body {
    font-size: var(--t-lede);
    line-height: 1.6;
    color: var(--fg-2);
}

.arch__tiers {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--gutter);
}

.arch__tier {
    padding-block: var(--s-6);
    border-top: var(--hair) solid var(--rule);
}

.arch__tier {
    display: grid;
    align-content: start;
}

.arch__tier-role {
    min-height: 2.8em;
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    line-height: 1.4;
    text-transform: uppercase;
    color: var(--fg-3);
}

.arch__tier-title {
    margin-top: 0;
    font-family: var(--font-display);
    font-size: var(--t-d4);
    line-height: 1.22;
    letter-spacing: var(--track-tight);
    font-weight: var(--w-semibold);
}

.arch__tier-list a {
    display: block;
    padding-block: var(--s-2);
    color: var(--fg-2);
    transition: color var(--dur) var(--ease), transform var(--dur-slow) var(--ease-out);
}

.arch__tier-list a:hover {
    color: var(--fg);
    transform: translateX(var(--s-2));
}

.arch__tier-list {
    display: grid;
    gap: var(--s-2);
    margin-top: var(--s-4);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

.arch__badge {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--accent);
}

.arch__note {
    margin-top: var(--s-8);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-3);
    max-width: 72ch;
}

.arch__bracket {
    display: none;
}

/* The service flagship band, reused from the homepage flagship language. */
.flagband__inner {
    display: grid;
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    gap: var(--s-12) var(--s-16);
    align-items: start;
}

.flagband__eyebrow {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

.flagband__eyebrow::before {
    content: "";
    width: var(--s-8);
    height: var(--hair);
    background: var(--rule-2);
    flex: none;
}

.flagband__title {
    margin-top: var(--s-5);
    font-family: var(--font-display);
    font-size: var(--t-d1);
    line-height: 1.04;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
    max-width: 16ch;
}

.flagband__lede {
    margin-top: var(--s-6);
    font-size: var(--t-lede);
    line-height: 1.62;
    color: var(--fg-2);
    max-width: 52ch;
}

.flagband__actions {
    margin-top: var(--s-8);
}

.flagband__subhead {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
    padding-bottom: var(--s-4);
}

.flagband__list {
    display: grid;
}

.flagband__list li {
    padding-block: var(--s-4);
    border-top: var(--hair) solid var(--rule);
    font-family: var(--font-display);
    font-size: var(--t-d4);
    letter-spacing: var(--track-tight);
    font-weight: var(--w-medium);
}

.flagband__list li:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.flagband__note {
    margin-top: var(--s-6);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-3);
}

/* --- Forms --------------------------------------------------------------- */

.form__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    /* Start, not stretch: one field carrying a hint made every control in its
       row grow to match, which pushed the underline of an empty input 130px
       below its label and made the field look like it was not there. */
    align-items: start;
    gap: var(--s-6) var(--gutter);
}

.field {
    display: grid;
    align-content: start;
    gap: var(--s-2);
}

.field--full,
.field--consent {
    grid-column: 1 / -1;
}

/* `display: none`, not off-screen. Positioned at -9999px the honeypot was
   still in the layout, still focusable and still in the accessibility tree —
   `aria-hidden` on it made the announcement worse, not better, because a
   keyboard user could land in a field the form wants nobody to touch. A
   `display: none` input is still submitted, so a bot that fills every field
   still trips it. */
.field--trap {
    display: none;
}

.field__label {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

.field__optional {
    text-transform: none;
    letter-spacing: 0;
    font-weight: var(--w-regular);
}

/* A FIELD HAS TO LOOK LIKE A FIELD.
   These were underline-only and transparent, which on a flat field gave no
   affordance at all: a caption with a hairline floating under it. A hairline
   box with square corners is the same vocabulary the rest of the site uses and
   it reads unambiguously as somewhere to type. */
.field__control {
    width: 100%;
    min-height: 3rem;
    padding: 0.75rem var(--s-4);
    background: var(--paper-pure);
    border: var(--hair) solid var(--rule-2);
    border-radius: 0;
    color: var(--fg);
    font-family: var(--font-sans);
    font-size: var(--t-body);
    line-height: 1.5;
    transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.field__control::placeholder {
    color: var(--fg-3);
}

.field__control:hover {
    border-color: var(--fg-3);
}

.field__control:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: inset 0 0 0 1px var(--accent);
}

textarea.field__control {
    min-height: 7.5rem;
    resize: vertical;
}

select.field__control {
    -webkit-appearance: none;
    appearance: none;
    background-image:
        linear-gradient(45deg, transparent 50%, currentColor 50%),
        linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position: right 1.15rem center, right 0.8rem center;
    background-size: 0.35rem 0.35rem, 0.35rem 0.35rem;
    background-repeat: no-repeat;
    padding-inline-end: var(--s-10);
}

.field__hint {
    font-size: var(--t-micro);
    color: var(--fg-3);
}

.field__error {
    font-size: var(--t-micro);
    font-weight: var(--w-medium);
    color: var(--error);
}

.field--invalid .field__control {
    border-color: var(--error);
    box-shadow: inset 0 0 0 1px var(--error);
}

.field--consent {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--s-4);
    align-items: start;
    padding-top: var(--s-4);
    border-top: var(--hair) solid var(--rule);
}

.field--consent input {
    width: 1.15rem;
    height: 1.15rem;
    margin-top: 0.15rem;
    accent-color: var(--signal);
    flex: none;
}

.field--consent .field__label {
    font-size: var(--t-small);
    font-weight: var(--w-regular);
    letter-spacing: 0;
    text-transform: none;
    color: var(--fg-2);
}

/* The submit action gets its own air: it sat directly against the consent
   checkbox, which read as part of the same control. */
.form > div:last-child {
    margin-top: var(--s-8);
}

.form-status {
    padding: var(--s-5) 0 var(--s-5) var(--s-6);
    border-inline-start: 2px solid var(--error);
    margin-bottom: var(--s-8);
}

.form-status--notice {
    border-inline-start-color: var(--success);
}

.form-status__title {
    font-family: var(--font-display);
    font-size: var(--t-d4);
    font-weight: var(--w-semibold);
}

.form-status ul {
    display: grid;
    gap: var(--s-2);
    margin-top: var(--s-3);
    font-size: var(--t-small);
    color: var(--fg-2);
}

/* --- The retired hero model --------------------------------------------- */
/* `flow` is no longer used on the homepage. It stays as a plain three-column
   sequence for any page that still includes the partial. */

.flow__stages {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--gutter);
}

.flow__stage {
    padding-top: var(--s-5);
    border-top: var(--hair) solid var(--rule);
}

.flow__stage--core {
    border-top: 2px solid var(--accent);
}

.flow__label {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

.flow__items {
    display: grid;
    gap: var(--s-2);
    margin-top: var(--s-4);
    font-size: var(--t-small);
    color: var(--fg-2);
}

.flow__title {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
    margin-bottom: var(--s-5);
}

/* PAGE-COMPONENTS-ANCHOR-3 */

/* 12. Utilities ========================================================== */

.visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.text-quiet { color: var(--fg-3); }
.text-secondary { color: var(--fg-2); }
.text-small { font-size: var(--t-small); }
.text-micro { font-size: var(--t-micro); }

.mt-3 { margin-top: var(--s-3); }
.mt-4 { margin-top: var(--s-4); }
.mt-6 { margin-top: var(--s-6); }
.mt-8 { margin-top: var(--s-8); }
.mt-10 { margin-top: var(--s-10); }
.mt-12 { margin-top: var(--s-12); }
.mt-16 { margin-top: var(--s-16); }

.stack-3 { display: grid; gap: var(--s-3); }
.stack-4 { display: grid; gap: var(--s-4); }
.stack-6 { display: grid; gap: var(--s-6); }
.stack-8 { display: grid; gap: var(--s-8); }

.justify-end { justify-content: flex-end; }

/* 13. Material =========================================================== */
/* --------------------------------------------------------------------------
   SURVEY.

   The Heights mark is a hard-edged summit. The site's artwork is that summit
   described the way elevation actually is — as a topographic survey: contour
   lines around a peak, every fourth drawn heavier as an index contour, which is
   the convention on a printed map.

   `summit-contours.svg` is applied as a MASK rather than as a background image,
   so a single 2 KB file takes the colour of whatever surface it sits on and no
   section needs its own artwork.

   IT SURVIVES ON THE LIGHT FIELDS ONLY. The dark openings carry a licensed
   photograph now, and a contour drawing under it was one texture too many, so
   the element that drew it there was removed rather than left in the sheet
   describing a layer no page emits. What remains is debossed into limestone,
   sunken and sand sections, which have no photograph of their own.

   Grain is the reason a flat field reads as a surface rather than as a colour
   value; it is a data URI, so none of this costs a second request.
   -------------------------------------------------------------------------- */

:root {
    /* Fine fractal noise. The one thing flat vector work lacks and printed
       matter has. */
    --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    --contours: url("/images/summit-contours.svg");
}

/* --- Grain --------------------------------------------------------------- */

.field-grain {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-image: var(--grain);
    opacity: var(--grain-strength, 0.055);
    /* Screen, not overlay: overlay preserves blacks, so on a near-black field
       it did nothing at all. Screen lifts the noise just enough to be felt
       rather than seen. */
    mix-blend-mode: screen;
}

/* --- Edge light ---------------------------------------------------------- */
/* A hairline along the top edge of a dark field, so the section reads as a
   plane catching light rather than as a rectangle of colour. */

.field-edge {
    position: absolute;
    inset-inline: 0;
    inset-block-start: 0;
    height: 1px;
    z-index: 0;
    pointer-events: none;
    background: linear-gradient(
        90deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 0.16) 34%,
        rgba(255, 255, 255, 0.05) 72%,
        rgba(255, 255, 255, 0) 100%
    );
}

/* --- The light fields ----------------------------------------------------
   The same survey, debossed rather than lit: ink at a fraction of the strength,
   so a limestone section reads as paper with an impression in it. The docs call
   the industries section out as the one carrying no visual field of its own —
   this is what gives it one. */

.surface--limestone,
.section--sunken,
.surface--sand {
    position: relative;
    isolation: isolate;
}

.surface--limestone::before,
.section--sunken::before,
.surface--sand::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-color: var(--ink-000);
    opacity: 0.055;
    -webkit-mask-image: var(--contours);
    mask-image: var(--contours);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: 150% auto;
    mask-size: 150% auto;
    -webkit-mask-position: 22% 62%;
    mask-position: 22% 62%;
}

/* The sectors chapter takes the summit itself, since it is the one section the
   image requirements name as carrying no field. */
.sectors::before {
    -webkit-mask-size: 128% auto;
    mask-size: 128% auto;
    -webkit-mask-position: 84% 30%;
    mask-position: 84% 30%;
    opacity: 0.07;
}


/* 14. The page figure ==================================================== */
/* --------------------------------------------------------------------------
   Every page draws one, generated from its own content (see
   app/partials/page_figure.php), so no two pages carry the same drawing. It
   sits off the right edge of the opening, cropped by the viewport.
   -------------------------------------------------------------------------- */

.page-figure {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-end: -10%;
    width: min(46rem, 62%);
    aspect-ratio: 1;
    transform: translateY(-50%);
    z-index: 0;
    pointer-events: none;
    color: var(--figure-tint, #ffffff);
    opacity: var(--figure-strength, 0.22);
}

.page-figure svg {
    width: 100%;
    height: 100%;
    display: block;
}

@media (max-width: 56rem) {
    .page-figure {
        inset-inline-end: -28%;
        width: 34rem;
        opacity: 0.14;
    }
}


/* 15. Page components, continued ========================================= */
/* --------------------------------------------------------------------------
   These are top-level rules that were dropped when the responsive layers were
   re-ordered: the script that sorted the @media blocks kept the blocks and
   discarded the plain rules sitting between them. That took out the contact
   page's two-column layout, the services portfolio grid, the About page's
   blocks and the interior field treatments, which is why those pages lost
   their structure.
   -------------------------------------------------------------------------- */

.portfolio__grid {
    display: grid;
}

.portfolio__group {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--s-5) var(--gutter);
    padding-block: var(--s-10);
    border-top: var(--hair) solid var(--rule);
    align-items: start;
}

.portfolio__group:last-child {
    border-bottom: var(--hair) solid var(--rule);
}

.portfolio__group--featured {
    border-top: 2px solid var(--accent);
}

.portfolio__name {
    font-family: var(--font-display);
    font-size: var(--t-d2);
    line-height: 1.1;
    letter-spacing: var(--track-display);
    font-weight: var(--w-semibold);
    max-width: 16ch;
}

.portfolio__summary {
    grid-column: 1;
    margin-top: var(--s-4);
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-3);
    max-width: 40ch;
}

.portfolio__services {
    grid-column: 2;
    grid-row: 1 / span 2;
    display: grid;
    align-content: start;
}

.portfolio__group--featured .portfolio__services {
    grid-row: 1;
}

.portfolio__services a {
    display: block;
    padding-block: var(--s-4);
    border-top: var(--hair) solid var(--rule);
    font-family: var(--font-display);
    font-size: var(--t-d3);
    line-height: 1.2;
    letter-spacing: var(--track-display);
    font-weight: var(--w-medium);
    color: var(--fg-2);
    transition: color var(--dur) var(--ease), transform var(--dur-slow) var(--ease-out);
}

.portfolio__services li:first-child a {
    border-top: 0;
    padding-block-start: 0;
}

.portfolio__services a:hover,
.portfolio__services a:focus-visible {
    color: var(--fg);
    transform: translateX(var(--s-3));
}



.ledger__side {
    display: grid;
    align-content: start;
}

.ledger__list--before li,
.ledger__list--after li {
    padding-block: var(--s-3);
    border-top: var(--hair) solid var(--rule);
}

.ledger__list--before li:first-child,
.ledger__list--after li:first-child {
    border-top: 0;
}

.ledger__side--after .ledger__list li {
    color: var(--fg);
}

.principal__figure {
    display: grid;
    gap: var(--s-4);
}

.principal__expertise {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2) 0;
    margin-top: var(--s-6);
}

.principal__expertise li {
    font-size: var(--t-small);
    color: var(--fg-2);
    padding-inline: var(--s-5);
    border-inline-start: var(--hair) solid var(--rule-2);
    line-height: 1.5;
}

.principal__expertise li:first-child {
    padding-inline-start: 0;
    border-inline-start: 0;
}

.article-rail__block {
    display: grid;
}

.ob-map__sources {
    display: grid;
    align-content: start;
}

.flagband__lead {
    display: grid;
    align-content: start;
}

.flagband__detail {
    display: grid;
    align-content: start;
}

.capability__head {
    display: grid;
    align-content: start;
}

.article-layout {
    padding-block: var(--chapter);
}

.stageline--light .stageline__num {
    color: var(--accent);
}

.section--ink,
.surface--ink,
.surface--brand,
.mast {
    position: relative;
    isolation: isolate;
}

.section--ink::before,
.surface--ink::before,
.surface--brand::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(120% 90% at 84% 0%, rgba(15, 76, 129, 0.22) 0%, rgba(15, 76, 129, 0) 60%),
        linear-gradient(180deg, var(--ink-100) 0%, var(--ink-000) 92%);
    pointer-events: none;
}

.section--ink::after,
.surface--ink::after,
.surface--brand::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: rgba(255, 255, 255, 0.016);
    clip-path: polygon(38% 100%, 76% 0, 100% 26%, 100% 100%);
    pointer-events: none;
}

.arrival::before,
.arrival::after {
    display: none;
}

.surface--limestone::after,
.section--sunken::after,
.surface--sand::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(90% 70% at 88% 0%, rgba(16, 21, 29, 0.03) 0%, rgba(16, 21, 29, 0) 62%);
    pointer-events: none;
}

.contact-layout {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
    gap: var(--s-12) var(--s-16);
    align-items: start;
}

.contact-layout__rail {
    position: sticky;
    top: calc(var(--chrome-top) + var(--s-10));
    padding-top: var(--s-5);
    border-top: 2px solid var(--accent);
}

.contact-details__title {
    font-family: var(--font-sans);
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
    margin-bottom: var(--s-6);
}

.contact-details a {
    font-family: var(--font-display);
    font-size: var(--t-d4);
    letter-spacing: var(--track-tight);
    font-weight: var(--w-medium);
    transition: color var(--dur) var(--ease);
}

.contact-details address {
    font-size: var(--t-small);
    line-height: var(--lead-loose);
    color: var(--fg-2);
}

/* 16. Field photography ================================================== */
/* --------------------------------------------------------------------------
   A purchased photograph, used as the opening's field rather than as a picture
   in a box. It holds the right of the composition and fades out across the
   middle, so the headline always sits on clean ink and never on a busy part of
   the image — no dark overlay needed, and the contrast of the type is not at
   the mercy of whichever image a page carries.
   -------------------------------------------------------------------------- */

.field-photo {
    position: absolute;
    inset-block: 0;
    inset-inline-end: 0;
    width: 62%;
    height: 100%;
    object-fit: cover;
    object-position: var(--photo-pos, center);
    z-index: 0;
    pointer-events: none;
    /* Graded to the palette rather than dropped in as shot: the field is ink and
       one blue, and an unfiltered stock photograph is the fastest way to make a
       restrained page look like a template. Contrast holds the blacks so the
       image joins the field instead of sitting on top of it. */
    opacity: var(--photo-opacity, 0.8);
    filter: var(--photo-filter, saturate(0.6) contrast(1.06));
    /* Screened onto the ink, not laid over it. Every frame in the set is a dark
       ground with light drawn on it: screened, the ground disappears into the
       field and only the light survives, which is the difference between a
       photograph pasted on a page and a photograph the page is made of. It is
       also what stops a half-opacity image reading as grey haze. */
    mix-blend-mode: screen;
    /* The fade is a mask, not a gradient laid over the top, so the image loses
       nothing to a scrim on the side where it is fully visible.

       TWO MASKS, INTERSECTED. One ramp alone left the photograph with a hard
       top and bottom edge cutting across the field: it dissolved on the left
       and then stopped dead at the section boundary. The second ramp takes the
       top and bottom away as well, so the frame has no edge anywhere except
       the viewport's own. The horizontal ramp is also longer and starts
       softer, so nothing about the transition is a visible line. */
    -webkit-mask-image:
        linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.04) 16%, rgba(0, 0, 0, 0.22) 38%, rgba(0, 0, 0, 0.62) 64%, rgba(0, 0, 0, 0.92) 86%, #000 100%),
        linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.55) 12%, #000 30%, #000 68%, rgba(0, 0, 0, 0.5) 90%, transparent 100%);
    mask-image:
        linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.04) 16%, rgba(0, 0, 0, 0.22) 38%, rgba(0, 0, 0, 0.62) 64%, rgba(0, 0, 0, 0.92) 86%, #000 100%),
        linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.55) 12%, #000 30%, #000 68%, rgba(0, 0, 0, 0.5) 90%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-composite: intersect;
}

/* --- Per-page framing -----------------------------------------------------
   Each page shows a different part of its own frame, so the openings read as
   one system rather than one image reused. The grade pulls each toward the
   palette, which is ink, paper and one blue: the set arrives in acid orange,
   alarm red and mint green, and dropped in unfiltered they fight each other
   across the site. */

[data-page-type='home'] .field-photo {
    /* The dial centred behind the headline. This is the client's call: it puts
       the padlock motif in frame, which the original brief ruled out, and it is
       the framing they chose. */
    --photo-pos: 58% 50%;
    --photo-filter: saturate(0.62) contrast(1.1);
    --photo-opacity: 0.92;
}

[data-page-type='vciso'] .field-photo {
    --photo-pos: 62% 50%;
    --photo-filter: saturate(0.6) contrast(1.06);
    --photo-opacity: 0.5;
}

[data-page-type='services-index'] .field-photo {
    --photo-pos: 60% 52%;
    --photo-filter: saturate(0.55) contrast(1.06);
    --photo-opacity: 0.88;
}

[data-page-type='industries-index'] .field-photo {
    /* The orange is held right down; at full strength it is the loudest thing
       on any page of the site. */
    --photo-pos: 50% 58%;
    --photo-filter: saturate(0.3) contrast(1.12);
    --photo-opacity: 0.62;
}

[data-page-type='about'] .field-photo {
    --photo-pos: 46% 50%;
    --photo-filter: saturate(0.6) contrast(1.05);
    --photo-opacity: 0.5;
}

[data-page-type='insights'] .field-photo {
    /* Red held down for the same reason. */
    --photo-pos: 0% 48%;
    --photo-filter: saturate(0.42) contrast(1.08);
    --photo-opacity: 0.72;
}

[data-page-type='contact'] .field-photo {
    /* Right of the band: "DATA PROTECTION" is printed across its middle, and a
       word inside a photograph is copy nobody wrote. */
    --photo-pos: 100% 50%;
    --photo-filter: saturate(0.4) contrast(1.05);
    --photo-opacity: 0.85;
}

/* Below the split the opening is one column, so the photograph sits behind the
   whole width and has to come down accordingly. Placed last so it wins over the
   per-page values above. */
@media (max-width: 56rem) {
    [data-page-type] .field-photo {
        width: 100%;
        --photo-opacity: 0.45;
        -webkit-mask-image:
            linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.18) 24%, rgba(0, 0, 0, 0.7) 58%, #000 82%, rgba(0, 0, 0, 0.55) 100%),
            linear-gradient(90deg, transparent 0%, #000 22%, #000 78%, transparent 100%);
        mask-image:
            linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.18) 24%, rgba(0, 0, 0, 0.7) 58%, #000 82%, rgba(0, 0, 0, 0.55) 100%),
            linear-gradient(90deg, transparent 0%, #000 22%, #000 78%, transparent 100%);
        -webkit-mask-composite: source-in;
        mask-composite: intersect;
    }
}

/* 17. The publication index ============================================== */
/* --------------------------------------------------------------------------
   The Insights index is a publication front page, not a blog template. Three
   objects do the whole job:

     .latest     the newest article set as a front page: the largest type on
                 the page, its framing facts hung under a full-width rule. The
                 same composition as the masthead and the homepage flagship,
                 so the page belongs to the site rather than to a CMS theme.
     .artindex   the archive as a typographic index, one rule per article.
                 It replaced a three-column card grid whose tiles were
                 generated geometry: a picture that says nothing above a
                 headline that says everything is worse than no picture, and
                 the ragged card heights broke every baseline on the page.
     .topicrail  what has been published, by subject, with counts. Numbers a
                 reader can act on, not a row of decorative pills.

   None of the three carries an image, and that is deliberate: this page has a
   photograph in its masthead and nothing below it should compete.
   -------------------------------------------------------------------------- */

/* --- The newest article -------------------------------------------------- */
/* The chapter is deliberately short. It introduces one article; the page is an
   index, and the index has to be on screen. */

.latest {
    padding-block: var(--s-16) var(--s-12);
}

.latest__title {
    margin-block: var(--s-5) 0;
    font-family: var(--font-display);
    /* Big enough to lead the page, not big enough to be the page. At the
       previous size a three-line headline and its summary filled the viewport
       on their own, so the archive below it was invisible until you scrolled:
       one article was standing in front of every other article. */
    font-size: clamp(1.75rem, 1rem + 1.9vw, 2.75rem);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-tight);
    line-height: 1.06;
    text-wrap: balance;
    max-width: 34ch;
}

.latest__title a {
    color: inherit;
    text-decoration: none;
}

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

.latest__baseline {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: var(--s-5) var(--gutter);
    margin-block-start: var(--s-6);
    padding-block-end: var(--s-6);
    border-block-end: var(--hair) solid var(--rule);
}

.latest__summary {
    /* Three lines at most. A summary is a reason to open the article, not a
       substitute for opening it, and an unbounded one pushed the archive off
       the screen. */
    margin: 0;
    max-width: 68ch;
    font-size: var(--t-small);
    line-height: 1.55;
    color: var(--fg-2);
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
}

.latest__action {
    justify-self: end;
}

/* The framing facts, hung under the rule rather than boxed beside the text.
   Four at most, so they stay on one row at every width that has the room. */
.latest__facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: var(--s-5) var(--gutter);
    margin-block-start: var(--s-6);
}

.latest__facts dt {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

.latest__facts dd {
    margin: var(--s-2) 0 0;
    font-size: var(--t-small);
    color: var(--fg);
}

.latest__facts a {
    color: inherit;
}

/* --- The archive index --------------------------------------------------- */
/* THE RULE IS THE INTERACTION, AND NOTHING MOVES. The row used to indent on
   hover, which slid the date, the subject, the headline and the summary to the
   right together. An index exists to hold one straight left margin; an
   interaction that breaks that margin breaks the only thing the layout is for.
   So the row's own hairline does the work: it thickens to the accent and draws
   in from the left. It is the site's primary object doing the site's primary
   job, and it costs one pseudo-element. */

.artindex {
    list-style: none;
    margin: 0;
    padding: 0;
    border-block-start: var(--hair) solid var(--rule);
}

.artindex__row {
    position: relative;
    border-block-end: var(--hair) solid var(--rule);
}

.artindex__row::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    inset-block-end: calc(var(--hair) * -1);
    height: 2px;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: 0 50%;
    transition: transform var(--dur) var(--ease-out);
}

.artindex__row:hover::after,
.artindex__row:focus-within::after {
    transform: scaleX(1);
}

.artindex__link {
    display: grid;
    /* The date column is a margin, not a column of content: wide enough for
       "30 September 2026" on one line and no wider. */
    grid-template-columns: minmax(0, 10.5rem) minmax(0, 1fr) 1.25rem;
    align-items: start;
    gap: var(--s-5);
    padding-block: var(--s-6);
    color: inherit;
    text-decoration: none;
}

/* The date hangs on the headline's cap line rather than floating above it.
   0.22rem is this face's half-leading at the headline's size; it is a
   measurement, not a nudge. */
.artindex__meta {
    display: grid;
    gap: var(--s-1);
    padding-block-start: 0.22rem;
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

.artindex__topic {
    color: var(--accent);
}

.artindex__body {
    display: grid;
    gap: var(--s-2);
    min-width: 0;
}

.artindex__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--t-d3);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-tight);
    line-height: 1.14;
    color: var(--fg);
    /* NOT `balance`. Balance is for display type in a narrow measure; in a
       column this wide it broke one-line headlines into two ragged ones. */
    text-wrap: pretty;
}

.artindex__link:hover .artindex__title,
.artindex__link:focus-visible .artindex__title {
    color: var(--accent);
}

/* Two lines. A summary in an index is a reason to open the article, and an
   unbounded one gave every row a different height and destroyed the rhythm
   the rules are there to create. */
.artindex__summary {
    max-width: 74ch;
    font-size: var(--t-small);
    line-height: 1.5;
    color: var(--fg-2);
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}

.artindex__author {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

/* The cue sits against the headline, on its cap line, not centred in a row
   whose height it has nothing to do with. It is drawn from two rules rather
   than an icon font or a file. */
.artindex__cue {
    position: relative;
    width: 1.25rem;
    height: 1.25rem;
    margin-block-start: 0.15rem;
    color: var(--fg-3);
    transition: transform var(--dur) var(--ease), color var(--dur) var(--ease);
}

.artindex__cue::before,
.artindex__cue::after {
    content: "";
    position: absolute;
    inset-inline-end: 0.3rem;
    width: 0.5rem;
    height: var(--hair);
    background: currentColor;
}

.artindex__cue::before {
    top: calc(50% - 0.17rem);
    transform: rotate(45deg);
    transform-origin: 100% 50%;
}

.artindex__cue::after {
    top: calc(50% + 0.17rem);
    transform: rotate(-45deg);
    transform-origin: 100% 50%;
}

.artindex__link:hover .artindex__cue,
.artindex__link:focus-visible .artindex__cue {
    color: var(--accent);
    transform: translateX(0.3rem);
}

/* --- The topic rail ------------------------------------------------------ */

.topicrail {
    margin-block-start: var(--s-8);
    border-block-start: var(--hair) solid var(--rule);
}

.topicrail__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-4);
    padding-block: var(--s-3);
    border-block-end: var(--hair) solid var(--rule);
}

.topicrail__row dt {
    font-size: var(--t-small);
    color: var(--fg);
}

/* Numbers, so no label tracking: `--track-nano` set "14" as "1 4". */
.topicrail__row dd {
    margin: 0;
    font-variant-numeric: tabular-nums;
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: 0;
    color: var(--fg-3);
}

/* The total belongs on the ledger it totals, in the ledger's own type. Set as
   a heading it was the loudest thing in the section, which put a count above
   the articles it was counting. */
.topicrail__row--total {
    margin-block-start: var(--s-2);
    border-block-end: 0;
    border-block-start: var(--hair) solid var(--rule-2);
    padding-block-start: var(--s-4);
}

.topicrail__row--total dt {
    font-size: var(--t-nano);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-nano);
    text-transform: uppercase;
    color: var(--fg-3);
}

.topicrail__row--total dd {
    color: var(--fg);
}

/* --- The empty index ----------------------------------------------------- */
/* An empty archive is a real state, so it gets a composition rather than a
   heading left on its own above the footer. */

.standby {
    max-width: 46rem;
}

.standby__title {
    margin-block: var(--s-6) 0;
    font-family: var(--font-display);
    font-size: var(--t-d1);
    font-weight: var(--w-semibold);
    letter-spacing: var(--track-tight);
    line-height: 1.05;
}

.standby__body {
    margin-block: var(--s-6) 0;
    max-width: 54ch;
    font-size: var(--t-d4);
    color: var(--fg-2);
}

.standby__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-6) var(--s-10);
    margin-block-start: var(--s-8);
    padding-block-start: var(--s-8);
    border-block-start: var(--hair) solid var(--rule);
}

@media (max-width: 56rem) {
    .latest__baseline {
        grid-template-columns: minmax(0, 1fr);
        align-items: start;
    }

    .latest__action {
        justify-self: start;
    }

    .artindex__link {
        grid-template-columns: minmax(0, 1fr) 1.5rem;
        gap: var(--s-4);
    }

    /* The date and subject move above the headline rather than into a column
       too narrow to hold either. */
    /* `min-width: 0` because a grid item defaults to `min-content` and will
       not shrink below its longest word. Without it "30 SEPTEMBER 2026" beside
       an uppercase, wide-tracked subject overran 360px — and `overflow-x: clip`
       on the body hid the overrun instead of letting it scroll, so the subject
       was silently cut off the right edge. Wrapping is the correct answer at
       this width; clipping is not. */
    .artindex__meta {
        grid-column: 1 / -1;
        /* Flex, not grid, because the point here is that these three can WRAP.
           `flex-wrap` on a grid container is inert, and `grid-auto-flow: column`
           forces one row however narrow the screen gets. */
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        justify-content: flex-start;
        gap: var(--s-2) var(--s-4);
        min-width: 0;
        padding-block-start: 0;
    }

    .artindex__meta > * {
        min-width: 0;
    }
}

/* 18. Responsive ========================================================= */

/* --- 1280 and below: the wide grid tightens ----------------------------- */
/* --------------------------------------------------------------------------
   RESPONSIVE LAYERS, WIDEST FIRST.
   Order is load-bearing: these all match at a phone width, so a broader block
   placed after a narrower one silently overrides it. They were interleaved —
   72rem, 56rem and 44rem all sat after the 37.5rem block — which is why phone
   values appeared to have no effect.
   -------------------------------------------------------------------------- */

@media (max-width: 80rem) {
    .foot__inner {
        grid-template-columns: minmax(0, 1fr);
    }

    .foot__columns {
        /* Five groups over three tracks wraps 3 + 2; over four it wrapped
           4 + 1, which is the lone-orphan layout again. */
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}
@media (max-width: 72rem) {
    .respmodel,
    .matrix,
    .pillars,
    .arch__tiers,
    .insight-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .stageline,
    .ecosystem__nodes,
    .process--4 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--s-8) var(--gutter);
    }

    .article-layout__inner {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--s-12);
    }

    .article-body,
    .article-rail {
        grid-column: 1;
        grid-row: auto;
    }

    .article-rail {
        position: static;
    }
}
@media (max-width: 64rem) {
    :root {
        --chrome-header: 4.5rem;
    }

    /* The opening must not be taller than the screen it opens on. */
    .mast {
        padding-block: calc(var(--chrome-header) + var(--s-6)) var(--s-8);
    }

    /* The opening is compact at tablet: at 1024 the headline, the baseline and
       the questions together ran past an 800px screen. */
    .arrival {
        padding-block: var(--chrome-header) var(--s-8);
    }

    /* THE MASTHEAD IS REDUCED WITH THE ARRIVAL, NOT LEFT BEHIND. Every
       override for `.mast__title` changed only `font-size`, so it kept 8rem
       above and below at every width — 256px of dead margin on a phone, which
       is most of why an interior opening ran past the screen. */
    .arrival__title,
    .mast__title {
        margin-block: clamp(1.5rem, 3.5vh, 2.5rem);
    }

    /* The two buttons claim 640px of the row at this width, which squeezed the
       sentence beside them into a 254px column and eight short lines. Below the
       full width the row stacks. */
    .arrival__baseline {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--s-5) var(--gutter);
        padding-top: var(--s-6);
    }

    .arrival__actions {
        justify-content: flex-start;
    }

    .arrival__questions {
        margin-top: var(--s-6);
        padding-top: var(--s-5);
        gap: var(--s-5) var(--gutter);
    }

    .arrival {
        padding-block: calc(var(--chrome-header) + var(--s-8)) var(--s-8);
    }

    .mast__title {
        font-size: clamp(2rem, 7.2cqw, 3.25rem);
    }

    .mast__baseline,
    .mast__facts {
        margin-top: var(--s-6);
        padding-top: var(--s-5);
    }

    .mast__lede {
        font-size: var(--t-body);
    }

    .menu-toggle {
        display: inline-flex;
    }

    .menu-toggle[hidden] {
        display: none;
    }

    /* Without scripting there is no disclosure to drive, so the navigation
       stays a plain wrapped list inside a header that grows to hold it. */
    html:not(.js) .chrome {
        position: static;
    }

    html:not(.js) .chrome__inner {
        height: auto;
        flex-wrap: wrap;
        padding-block: var(--s-4);
    }

    html:not(.js) .nav {
        flex-wrap: wrap;
        width: 100%;
        gap: var(--s-4);
    }

    /* The overlay is the same markup as the desktop bar; only its
       presentation changes, so nothing is duplicated in the document. */
    .js .nav {
        position: fixed;
        inset: 0;
        z-index: var(--z-overlay);
        --bg: var(--ink-000);
        --fg: #ffffff;
        --fg-2: var(--haze);
        --fg-3: var(--mist);
        --rule: rgba(255, 255, 255, 0.14);
        --rule-2: rgba(255, 255, 255, 0.32);
        --accent: var(--signal-lift);
        display: grid;
        align-content: start;
        justify-items: start;
        gap: 0;
        padding: calc(var(--chrome-header) + var(--s-12)) var(--gutter) var(--s-16);
        background: var(--ink-000);
        color: #ffffff;
        overflow-y: auto;
        opacity: 0;
        visibility: hidden;
        transform: translateY(-1.5rem);
        transition:
            opacity var(--dur-slow) var(--ease-out),
            transform var(--dur-slow) var(--ease-out),
            visibility 0s linear var(--dur-slow);
    }

    .js .nav[data-collapsed="false"] {
        opacity: 1;
        visibility: visible;
        transform: translateY(0);
        transition-delay: 0s;
    }

    .js .nav__link {
        width: 100%;
        padding-block: var(--s-5);
        border-top: var(--hair) solid rgba(255, 255, 255, 0.14);
        font-family: var(--font-display);
        font-size: clamp(1.75rem, 1.1rem + 3vw, 2.75rem);
        line-height: 1.1;
        letter-spacing: var(--track-display);
        font-weight: var(--w-semibold);
        color: #ffffff;
        opacity: 0;
        transform: translateY(0.75rem);
        transition:
            opacity var(--dur-slow) var(--ease-out),
            transform var(--dur-slow) var(--ease-out);
        transition-delay: calc(var(--i, 0) * 45ms);
    }

    .js .nav[data-collapsed="false"] .nav__link {
        opacity: 1;
        transform: translateY(0);
        transition-delay: calc(var(--i, 0) * 45ms + 90ms);
    }

    .js .nav__link:last-of-type {
        border-bottom: var(--hair) solid rgba(255, 255, 255, 0.14);
    }

    .js .nav__link::after {
        display: none;
    }

    .js .nav__link--flagship::before {
        width: 8px;
        height: 8px;
        background: var(--signal-lift);
        align-self: center;
    }

    .js .nav__cta {
        display: block;
        margin-top: var(--s-10);
        width: 100%;
        opacity: 0;
        transform: translateY(0.75rem);
        transition:
            opacity var(--dur-slow) var(--ease-out),
            transform var(--dur-slow) var(--ease-out);
        transition-delay: 330ms;
    }

    .js .nav[data-collapsed="false"] .nav__cta {
        opacity: 1;
        transform: translateY(0);
    }

    .nav__cta .btn {
        width: 100%;
    }

    /* Whatever field the header is over, once the overlay is open the header
       is on ink and must be light. */
    .chrome.is-menu-open {
        --chrome-fg: #ffffff;
        --chrome-fg-2: rgba(255, 255, 255, 0.72);
        --chrome-rule: rgba(255, 255, 255, 0.14);
        --chrome-bg: transparent;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }

    .chrome.is-menu-open .brand__paper { opacity: 1; }
    .chrome.is-menu-open .brand__ink { opacity: 0; }

    /* The overlay is a positioned sibling inside the header, so the mark and
       the control that closes it have to be lifted above it explicitly or the
       panel paints straight over both. */
    .js .chrome.is-menu-open .brand,
    .js .chrome.is-menu-open .chrome__actions {
        position: relative;
        z-index: calc(var(--z-overlay) + 1);
    }

    /* The desktop consultation button is redundant beside the menu button. */
    .chrome__cta {
        display: none;
    }
}
@media (max-width: 56rem) {
    .problem__inner,
    .shift__head,
    .shift__pivot,
    .flagship__body,
    .capabilities__head,
    .sectors__head,
    .principal__body,
    .publication__body,
    .arc__head,
    .frameworks {
        grid-template-columns: minmax(0, 1fr);
    }

    .problem__rail,
    .principal__signature {
        position: static;
    }

    .problem__title,
    .shift__title,
    .shift__pivot-title,
    .flagship__title,
    .capabilities__title,
    .sectors__title,
    .publication__title,
    .arrival__title,
    .principal__statement,
    .flagship__lede {
        max-width: none;
    }

    .fragments {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--s-8) var(--gutter);
    }

    .fragments__item:nth-child(n) {
        margin-block-start: 0;
    }

    .fragments__item:nth-child(2n) {
        margin-block-start: var(--s-10);
    }

    .shift__pivot {
        margin-top: var(--s-20);
    }

    .level__row {
        grid-template-columns: 3rem minmax(0, 1fr);
    }

    .level__text {
        grid-column: 2;
    }

    .arc__track {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--s-10) var(--gutter);
    }

    .arc__track::before {
        display: none;
    }

    .arc__step {
        padding-top: var(--s-6);
        border-top: var(--hair) solid var(--rule);
    }

    .arc__step::before {
        inset-block-start: -1px;
        height: 2px;
    }

    .capindex__link {
        grid-template-columns: 3rem minmax(0, 1fr);
        gap: var(--s-2) var(--s-4);
    }

    .capindex__group {
        grid-column: 2;
        white-space: normal;
    }

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

    .sector__meta {
        display: none;
    }

    /* The field and the summary are keyed to `(hover: hover)` now, beside the
       rules they belong with, rather than removed here by width. Taking the
       field away at a breakpoint while the white text it carried stayed was
       what made the row disappear under the cursor. */

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

    .arrival__baseline {
        grid-template-columns: minmax(0, 1fr);
        align-items: start;
    }

    .arrival__questions {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--s-6);
    }

    .arrival__actions {
        justify-content: flex-start;
    }

    .arrival__line--2 { padding-inline-start: 0.7em; }
    .arrival__line--3 { padding-inline-start: 1.4em; }
}
@media (max-width: 56rem) {
    .mast__baseline {
        grid-template-columns: minmax(0, 1fr);
        align-items: start;
    }

    /* `:has()` outranks the plain selector above, so the three-column rule that
       aligns the aside with the framing facts on a wide screen followed it down
       here and squeezed the aside into a 103px column — a headline broken over
       six lines. Below this width the facts stack too, so there is no column to
       align to and both parts take the full measure. */
    .mast__baseline:has(.mast__aside) {
        grid-template-columns: minmax(0, 1fr);
    }

    .mast__baseline:has(.mast__aside) .mast__lede {
        grid-column: 1;
    }

    .mast__aside {
        grid-column: 1;
    }

    .mast__actions {
        justify-content: flex-start;
    }

    .mast__facts {
        /* Back to row flow: the wide layout flows one column per fact, which
           on a narrow screen would squeeze every fact into one row. */
        grid-auto-flow: row;
        grid-template-columns: minmax(0, 1fr);
        gap: var(--s-6);
    }

    .mast__fact {
        display: grid;
        gap: var(--s-2);
        padding-top: var(--s-4);
        border-top: var(--hair) solid var(--rule);
    }

    .mast__fact:first-child {
        padding-top: 0;
        border-top: 0;
    }

    .leadgap__inner,
    .sticky-split,
    .grid--split,
    .grid--2,
    .grid--3,
    .offer,
    .flagband__inner,
    .arch__lead,
    .ecosystem__hub,
    .definitions > div,
    .capability__row,
    .leadgap__item,
    .respmodel__cell--anchor,
    .verdict,
    .article-preview {
        grid-template-columns: minmax(0, 1fr);
    }

    /* A COLLAPSED GRID HAS TO RELEASE WHAT IT PLACED. Collapsing `.arch__lead`
       to one column left its three children holding explicit coordinates for
       the two-column layout that no longer existed — the badge at (1,1), the
       title at (1,2) and the summary spanning (2, 1-2). The summary was placed
       into an implicit second column and drawn straight over the other two, so
       the flagship's label, its name and its description printed on top of one
       another.

       Placement and template are one decision. Where the template goes, the
       coordinates go with it, and the three stack in the order they are
       written. */
    .arch__badge,
    .arch__lead-title,
    .arch__lead-body {
        grid-column: 1;
        grid-row: auto;
    }

    .leadgap__aside,
    .sticky-split__aside,
    .grid--split > .section-header {
        position: static;
    }

    .respmodel__cell--anchor .respmodel__title,
    .respmodel__cell--anchor .respmodel__body {
        grid-column: 1;
        grid-row: auto;
    }

    .respmodel__cell--anchor .respmodel__body {
        margin-top: var(--s-3);
    }

    .index-list__link {
        grid-template-columns: minmax(0, 1fr);
    }

    .index-list__name {
        /* The cue still hangs at the row's edge here, so the name keeps its
           clearance the way the summary does. */
        padding-inline-end: var(--s-8);
    }

    .index-list__summary {
        grid-column: 1;
    }

    /* The comparison becomes two stacked answers per dimension, each labelled
       by the side it belongs to, rather than a table squeezed to a third of
       its width. */
    .compare {
        grid-template-columns: minmax(0, 1fr);
    }

    .compare::before {
        display: none;
    }

    .compare__head {
        display: none;
    }

    .compare__dimension,
    .compare__cell,
    .compare__cell--b {
        grid-column: 1;
    }

    .compare__dimension {
        border-top: 2px solid var(--rule-2);
        padding-bottom: var(--s-2);
    }

    .compare__cell {
        border-top: 0;
        padding-block: var(--s-2);
    }

    .compare__cell::before {
        content: attr(data-side);
        display: block;
        margin-bottom: var(--s-1);
        font-size: var(--t-nano);
        font-weight: var(--w-semibold);
        letter-spacing: var(--track-nano);
        text-transform: uppercase;
        color: var(--accent);
    }

    .compare__cell--b::before {
        color: var(--fg-3);
    }

    .compare__cell--b {
        padding-bottom: var(--s-6);
    }

    /* The obligation map stacks: regimes, then the point they resolve to. The
       connector layer is decorative and has nothing to connect once the two
       halves are above one another. */
    .ob-map {
        grid-template-columns: minmax(0, 1fr);
    }

    .ob-map__wires {
        display: none;
    }

    .ob-map__target {
        margin-top: var(--s-8);
    }
}
@media (max-width: 56rem) {
@media (max-width: 56rem) {
    .portfolio__group {
        grid-template-columns: minmax(0, 1fr);
    }

    .portfolio__services {
        grid-column: 1;
        grid-row: auto;
    }

    .portfolio__summary {
        grid-column: 1;
    }
}
@media (max-width: 56rem) {
    .contact-layout {
        grid-template-columns: minmax(0, 1fr);
    }

    .contact-layout__rail {
        position: static;
    }
}
@media (max-width: 44rem) {
    .respmodel,
    .matrix,
    .pillars,
    .arch__tiers,
    .insight-grid,
    .stageline,
    .ecosystem__nodes,
    .process--3,
    .process--4,
    .flow__stages,
    .form__grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .rows > *,
    .rows > * > div,
    .stage {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--s-2);
    }

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

    .ledger__rule {
        display: none;
    }

    .head-row {
        align-items: start;
    }

    .verdict__item {
        grid-template-columns: 1.5rem minmax(0, 1fr);
    }

    .article-body {
        font-size: 1.0625rem;
    }
}
@media (max-width: 37.5rem) {
    /* Every standalone control clears 44px on a phone. */
    .menu-toggle {
        min-height: 44px;
    }

    /* An opening must not be taller than the screen it opens on. At tablet
       spacing the mastheads ran to 1.2–1.4 phone screens, so a visitor saw the
       headline and nothing else. */
    .mast {
        min-height: 0;
        padding-block: calc(var(--chrome-header) + var(--s-6)) var(--s-8);
    }

    .mast__baseline,
    .mast__facts {
        margin-top: var(--s-6);
        padding-top: var(--s-5);
    }

    .mast__facts {
        gap: var(--s-5);
    }

    .mast__lede {
        font-size: var(--t-body);
    }

    .arrival__title,
    .mast__title {
        margin-block: clamp(1.75rem, 4vh, 2.5rem);
    }

    .arrival__questions {
        margin-top: var(--s-6);
        padding-top: var(--s-5);
        gap: var(--s-5);
    }

    .arrival__baseline {
        gap: var(--s-5) var(--gutter);
        padding-top: var(--s-6);
    }

    .breadcrumbs--inline {
        margin-bottom: var(--s-5);
    }

    .breadcrumbs a,
    .breadcrumbs span,
    .ecosystem__link,
    .checklist a,
    .tag-list a,
    .frameworks__list a,
    .principal__expertise a,
    .index-list__link,
    .foot__list a,
    .foot__utility a,
    .article-rail__toc a,
    .article-rail__links a,
    .legal-body__rail a,
    .contact-details a,
    .foot__contact-line {
        display: inline-block;
        padding-block: 0.6rem;
    }

    .foot__list,
    .article-rail__toc,
    .article-rail__links {
        gap: 0;
    }

    :root {
        --t-mega: clamp(2.375rem, 1.1rem + 8.4vw, 3.5rem);
    }

    /* On a phone the stepped indent is dropped, so the headlines set to the
       page measure rather than to a fill target. */
    .arrival__title,
    .mast__title {
        font-size: clamp(2.25rem, 10cqw, 3.5rem);
    }

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

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

    .arrival__inner {
        justify-content: flex-end;
        gap: var(--s-12);
    }

    .arrival__title {
        max-width: none;
    }

    .arrival__line--2,
    .arrival__line--3 {
        padding-inline-start: 0;
    }

    /* On a phone the stepped indent costs more than it says, so the ascent is
       carried by the rule beneath the block instead. */
    .arrival__line--2 .arrival__line-in,
    .arrival__line--3 .arrival__line-in {
        color: rgba(255, 255, 255, 0.72);
    }

    .btn {
        width: 100%;
    }

    .btn-row {
        gap: var(--s-3);
    }

    .problem__link {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--s-2);
    }

    .problem__row:nth-child(n) .problem__link {
        padding-inline-start: 0;
    }

    .problem__index {
        padding-top: 0;
    }

    .fragments {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--s-8);
    }

    .fragments__item:nth-child(n) {
        margin-block-start: 0;
    }

    .level__row {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--s-2);
    }

    .level__text {
        grid-column: 1;
    }

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

    .flagship__note {
        margin-top: var(--s-12);
        padding-inline-start: var(--s-5);
    }

    .sector__name {
        font-size: var(--t-d2);
    }

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

    .foot {
        padding-block: var(--s-12) var(--s-8);
    }
}
@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;
        transition-delay: 0ms !important;
        scroll-behavior: auto !important;
    }

    .js [data-reveal],
    .arrival__line-in,
    .arc__step::before {
        opacity: 1 !important;
        transform: none !important;
    }

    /* The contour draw waits on an animation-delay, which the duration
       override above does not collapse — so without this, a reduced-motion
       visitor watches an empty field for a second. The ridges are simply
       there. */
    .js .arrival .arrival__contours path {
        stroke-dashoffset: 0 !important;
        animation: none !important;
    }
}
@media print {
    .chrome,
    .foot,
    .skip-link {
        display: none;
    }

    body {
        background: #ffffff;
        color: #000000;
    }
}
