/* ============================================================================
   Kwomo Digital V2 — design tokens
   Translated directly from DESIGN.md (the approved production design target).
   Values trace to Direction A · Refinement 03 except where DESIGN.md records
   an approved correction (see --kw-meta-faint).

   Portability note: these are plain CSS custom properties on :root so the whole
   token layer lifts into a WordPress theme stylesheet unchanged.
   ========================================================================= */

:root {
  /* --- Colour: grounds ---------------------------------------------------- */
  --kw-paper-cream: #f4f1ea;
  --kw-warm-band: #efebe1;
  --kw-ink: #16170f;
  --kw-deep-ink: #14150e;

  /* --- Colour: accents ---------------------------------------------------- */
  --kw-green: #1e6b45;
  --kw-mint: #8fd3ae; /* dark grounds only — The Two-Ground Rule */

  /* --- Colour: text ramp (light ground) ----------------------------------- */
  --kw-body-primary: #26271f;
  --kw-body-secondary: #3f4037;
  --kw-label-muted: #4b4c42;
  --kw-marquee-quiet: #5a5b50;
  /* Approved accessibility correction. Refinement 03 used #8A8B7E, which
     measures 2.90:1 on --kw-warm-band and fails WCAG AA. #6A6B5E holds the
     identical warm-grey hue at 4.55:1 / 4.80:1. */
  --kw-meta-faint: #6a6b5e;

  /* --- Colour: text ramp (dark ground) ------------------------------------ */
  --kw-dark-body: #dddcd1;
  --kw-dark-meta: #a9aa9e;

  /* Neutral fills for unpopulated media figures. Scaffolds, not surfaces. */
  --kw-media-placeholder: #e6e1d6;
  --kw-media-placeholder-dark: #1f211a;

  /* --- Hairlines ---------------------------------------------------------- */
  /* Dividers are ink/cream at low alpha, never separate colour tokens. */
  --kw-rule-ink-08: rgb(22 23 15 / 0.08);
  --kw-rule-ink-10: rgb(22 23 15 / 0.1);
  --kw-rule-ink-12: rgb(22 23 15 / 0.12);
  --kw-rule-ink-15: rgb(22 23 15 / 0.15);
  --kw-rule-ink-20: rgb(22 23 15 / 0.2);
  --kw-rule-cream-12: rgb(244 241 234 / 0.12);
  --kw-rule-cream-14: rgb(244 241 234 / 0.14);
  --kw-rule-cream-18: rgb(244 241 234 / 0.18);
  --kw-hairline: 1px;
  --kw-rule-active: 2px; /* The Hairline Rule: 2px is active-state only */

  /* --- Shape -------------------------------------------------------------- */
  --kw-radius: 0; /* The Square Corner Rule — radius is 0 everywhere */
  --kw-radius-full: 50%; /* cursor dot only */

  /* --- Type families ------------------------------------------------------ */
  --kw-font-sans: 'Instrument Sans', ui-sans-serif, system-ui, -apple-system,
    'Segoe UI', Roboto, Arial, sans-serif;
  --kw-font-serif: 'Instrument Serif', ui-serif, Georgia, 'Times New Roman', serif;
  --kw-font-mono: ui-monospace, Menlo, Consolas, 'Liberation Mono', monospace;

  /* --- Type weights ------------------------------------------------------- */
  --kw-weight-regular: 400;
  --kw-weight-medium: 500;
  --kw-weight-wordmark: 600; /* The Weight Ceiling Rule: wordmark is the sole 600 */

  /* --- Fluid type scale --------------------------------------------------- */
  --kw-size-display: clamp(42px, 8.1vw, 146px);
  --kw-size-statement: clamp(36px, 6.2vw, 104px);
  --kw-size-headline: clamp(32px, 5.4vw, 90px);
  --kw-size-headline-feature: clamp(30px, 5vw, 80px);
  --kw-size-heading-small: clamp(19px, 2vw, 30px);
  --kw-size-marquee-primary: clamp(24px, 3.1vw, 52px);
  --kw-size-marquee-secondary: clamp(19px, 2.3vw, 38px);
  --kw-size-headline-founder: clamp(30px, 4.4vw, 72px);
  --kw-size-headline-process: clamp(28px, 4.4vw, 72px);
  /* Closing CTA display. A step under Display: 8vw against the hero's 8.1vw. */
  --kw-size-cta: clamp(40px, 8vw, 146px);
  --kw-size-cta-lead: clamp(18px, 1.7vw, 26px);
  --kw-size-footer-statement: clamp(28px, 6vw, 108px);
  --kw-size-quote: clamp(20px, 2.3vw, 34px);
  --kw-size-statement-sm: clamp(22px, 2.7vw, 42px);
  --kw-size-title: clamp(22px, 2.8vw, 44px);
  --kw-size-project-title: clamp(23px, 2.7vw, 44px);
  --kw-size-layer-title: clamp(17px, 1.6vw, 25px);
  --kw-size-process-summary: clamp(17px, 1.4vw, 23px);
  --kw-size-caption: 13px;
  --kw-size-caption-lg: 14px;
  --kw-size-body: clamp(17px, 1.35vw, 21px);
  /* A hair tighter than Body — the artboard's value in narrower columns. */
  --kw-size-body-narrow: clamp(17px, 1.3vw, 21px);
  /* Inline statement set beside metadata, as in the Founder closing row. */
  --kw-size-statement-inline: clamp(16px, 1.5vw, 22px);
  --kw-size-body-accent: clamp(21px, 2.4vw, 36px);
  --kw-size-cap-lead: clamp(21px, 2.3vw, 34px);
  --kw-size-body-sm: 16px;
  /* DESIGN.md's Body Small. Northrose referenced a --kw-size-body-small that
     was never defined and silently inherited 16px against the locked 15px;
     Phase 6 repointed it here. */
  --kw-size-detail: 15px;
  --kw-size-ui: 14px;
  --kw-size-label: 11px;
  --kw-size-label-fine: 10px; /* tertiary editorial metadata only — never functional UI */

  /* --- Type metrics ------------------------------------------------------- */
  --kw-leading-display: 0.9;
  --kw-leading-statement: 0.92;
  --kw-leading-headline: 0.94;
  --kw-leading-headline-feature: 0.98;
  /* Founder and Process headings share the artboard's 0.98 leading. */
  --kw-leading-headline-tight: 0.98;
  /* Indent ladder: one step is 1.6vw, capped at 34px. Depth 0-4. */
  --kw-indent-step: clamp(0px, 1.6vw, 34px);
  --kw-leading-body: 1.6;
  --kw-leading-body-accent: 1.24;

  --kw-tracking-display: -0.045em;
  --kw-tracking-display-accent: -0.02em;
  --kw-tracking-headline: -0.042em;
  --kw-tracking-headline-feature: -0.038em;
  --kw-tracking-heading-small: -0.03em;
  --kw-tracking-marquee-primary: -0.04em;
  --kw-tracking-title: -0.038em;
  --kw-tracking-wordmark: -0.025em;
  --kw-tracking-label: 0.16em;
  --kw-tracking-label-fine: 0.14em;

  /* --- Spatial system ----------------------------------------------------- */
  --kw-container: 1580px;
  --kw-gutter: clamp(20px, 4vw, 64px);
  --kw-section-y-compact: clamp(68px, 10vw, 150px);
  --kw-stack-sm: clamp(12px, 1.6vw, 24px);

  /* Hero line indents (composition-specific, from the locked hero) */
  --kw-hero-indent-2: clamp(0px, 11vw, 200px);
  --kw-hero-indent-4: clamp(0px, 25vw, 400px);

  /* --- Motion ------------------------------------------------------------- */
  --kw-ease-reveal: cubic-bezier(0.22, 0.61, 0.36, 1);
  --kw-ease-rise: cubic-bezier(0.19, 0.72, 0.26, 1);
  --kw-dur-state: 0.45s;
  /* Capability row colour/rule. The locked artboard's value. */
  --kw-dur-state-mid: 0.5s;
  /* Capability row inset. Matches the artboard's padding-left duration. */
  --kw-dur-state-slow: 0.6s;
  /* Panel content swap on selection change. */
  --kw-dur-panel: 200ms;
  --kw-dur-rise: 0.85s;

  /* --- Focus -------------------------------------------------------------- */
  --kw-focus-color: var(--kw-green);
  --kw-focus-width: 2px;
  --kw-focus-offset: 3px;

  /* --- Controls ----------------------------------------------------------- */
  --kw-target-min: 48px; /* minimum interactive target */
  --kw-header-h: 74px; /* measured header height; used for scroll-margin */
}

/* Dark grounds re-point the text ramp so components inherit correct colours
   without each component re-declaring them. Used by Northrose and the closing
   CTA in later phases; declared here so the token layer is complete. */
.kw-ground-dark {
  --kw-body-primary: var(--kw-dark-body);
  --kw-body-secondary: var(--kw-dark-body);
  --kw-label-muted: var(--kw-dark-meta);
  --kw-meta-faint: var(--kw-dark-meta);
  --kw-focus-color: var(--kw-mint);
  background: var(--kw-deep-ink);
  color: var(--kw-paper-cream);
}


/* ============================================================================
   Self-hosted type. Only the weights and styles DESIGN.md actually uses.

   Instrument Sans ships as a variable font: one file covers 400–600, so the
   three weights the design uses (400 body, 500 display/headings, 600 wordmark)
   cost a single request rather than three.

   Instrument Serif is loaded in italic only — the locked design never uses the
   roman cut, and never uses Instrument Sans italic.
   ========================================================================= */

/* --- Instrument Sans — variable, 400..600, latin ------------------------- */
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('../fonts/instrument-sans-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;
}

/* --- Instrument Sans — variable, 400..600, latin-ext --------------------- */
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('../fonts/instrument-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- Instrument Serif — italic only, latin -------------------------------- */
@font-face {
  font-family: 'Instrument Serif';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/instrument-serif-italic-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;
}

/* --- Instrument Serif — italic only, latin-ext ---------------------------- */
@font-face {
  font-family: 'Instrument Serif';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/instrument-serif-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* ============================================================================
   Base layer — reset, document defaults, shared primitives.
   Framework-agnostic: no preprocessor, no utility classes, no build-time magic.
   ========================================================================= */

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

html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-size-adjust: 100%;
}

/* Smooth scrolling is motion: it belongs behind the reduced-motion gate.
   Refinement 03 declared it globally, which its own reduced-motion block did
   not cover (that block only zeroed animation/transition durations). */
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  background: var(--kw-paper-cream);
  color: var(--kw-ink);
  font-family: var(--kw-font-sans);
  font-weight: var(--kw-weight-regular);
  /* overflow-x guard: the hero's indented lines can exceed the viewport at
     narrow widths before the indents collapse to 0. */
  overflow-x: hidden;
}

::selection {
  background: var(--kw-green);
  color: var(--kw-paper-cream);
}

a {
  color: inherit;
  text-decoration: none;
}

:focus-visible {
  outline: var(--kw-focus-width) solid var(--kw-focus-color);
  outline-offset: var(--kw-focus-offset);
}

/* Remove the outline only where a component paints its own equivalent. */
:focus:not(:focus-visible) {
  outline: none;
}

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

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  border-radius: var(--kw-radius);
  padding: 0;
}

h1,
h2,
h3,
p,
figure,
blockquote,
ul,
ol {
  margin: 0;
}

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

/* Anchored sections must clear the sticky header. */
[id] {
  scroll-margin-top: calc(var(--kw-header-h) + var(--kw-stack-sm));
}

/* --- Shared primitives ---------------------------------------------------- */

.kw-container {
  max-width: var(--kw-container);
  margin-inline: auto;
  padding-inline: var(--kw-gutter);
}

/* Monospace metadata — the instrument register.
   11px is the functional floor; --kw-size-label-fine (10px) is reserved for
   genuinely tertiary editorial metadata and is never used for navigation,
   controls, labels, or content required to operate the page. */
.kw-label {
  font-family: var(--kw-font-mono);
  font-size: var(--kw-size-label);
  font-weight: var(--kw-weight-regular);
  letter-spacing: var(--kw-tracking-label);
  text-transform: uppercase;
  color: var(--kw-label-muted);
}

/* Screen-reader-only, for text that must exist in the accessibility tree
   without appearing visually. */
.kw-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
  /* A hidden heading otherwise keeps the UA's 700, which this system owns no
     face for. Nothing here renders, so this changes no pixels — it just stops
     a stray weight existing in the document. */
  font-weight: inherit;
}

/* Skip link — visible only on focus. */
.kw-skip-link {
  position: absolute;
  top: 0;
  left: var(--kw-gutter);
  z-index: 100;
  transform: translateY(-120%);
  background: var(--kw-ink);
  color: var(--kw-paper-cream);
  padding: 12px 20px;
  font-size: var(--kw-size-ui);
  font-weight: var(--kw-weight-medium);
  transition: transform var(--kw-dur-state) var(--kw-ease-reveal);
}

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

/* --- Scroll reveal --------------------------------------------------------
   A scroll-linked rise, implemented entirely in CSS via a view() timeline.

   Three properties make this safe:
   - Content is visible by default. The animation is layered on top of an
     already-painted element, never used to hide it.
   - It is gated behind @supports, so browsers without scroll-driven animations
     simply show the content. No JavaScript is involved at any point, so it
     also works with JS disabled.
   - It is inside a reduced-motion query, so it never runs for visitors who
     have asked for less movement.

   `animation-range` ends the rise while the element is still low in the
   viewport, so content has settled well before it is read. */

@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .kw-reveal {
      animation: kw-reveal-rise linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 60%;
    }

    @keyframes kw-reveal-rise {
      from {
        opacity: 0.55;
        transform: translate3d(0, 14px, 0);
      }
      to {
        opacity: 1;
        transform: none;
      }
    }
  }
}

/* --- Buttons -------------------------------------------------------------- */
/* Square, hairline or solid, colour/border transitions only. No fills on
   hover beyond the documented ones, no radius, no shadow. */

.kw-btn {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  min-height: var(--kw-target-min);
  padding: 17px 30px;
  border-radius: var(--kw-radius);
  font-size: var(--kw-size-ui);
  font-weight: var(--kw-weight-medium);
  /* No line-height override: the locked buttons inherit `normal`, and forcing
     1 shortened them by 4px against the design. */
  cursor: pointer;
}

.kw-btn__arrow {
  font-family: var(--kw-font-serif);
  font-style: italic;
  line-height: 1;
}

.kw-btn--primary {
  background: var(--kw-ink);
  color: var(--kw-paper-cream);
  transition: background var(--kw-dur-state) ease;
}

.kw-btn--primary:hover {
  background: var(--kw-green);
}

.kw-btn--ghost {
  border: var(--kw-hairline) solid var(--kw-rule-ink-20);
  color: var(--kw-ink);
  transition:
    border-color var(--kw-dur-state) ease,
    color var(--kw-dur-state) ease;
}

.kw-btn--ghost:hover {
  border-color: var(--kw-ink);
  color: var(--kw-green);
}


/* ============================================================================
   Header — translated directly from SiteHeader.astro.
   ========================================================================= */

.kw-header {
    position: sticky;
    top: 0;
    z-index: 80;
    background: rgb(244 241 234 / 0.92);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-bottom: var(--kw-hairline) solid var(--kw-rule-ink-10);
  }

  .kw-header__bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: clamp(16px, 3vw, 48px);
    padding-block: 15px;
  }

  /* --- Wordmark ----------------------------------------------------------- */

  .kw-wordmark {
    display: flex;
    align-items: baseline;
    gap: 9px;
    flex: 0 0 auto;
    /* The text box alone is 20px tall — under the 24px pointer-target floor.
       Padding grows the hit area; the matching negative margin cancels its
       contribution to layout, so the header bar keeps its locked height. */
    padding-block: 4px;
    margin-block: -4px;
    font-size: 17px;
    font-weight: var(--kw-weight-wordmark);
    letter-spacing: var(--kw-tracking-wordmark);
    transition: color var(--kw-dur-state) ease;
  }

  .kw-wordmark:hover {
    color: var(--kw-green);
  }

  .kw-wordmark__mark {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-weight: var(--kw-weight-regular);
    font-size: 14px;
    color: var(--kw-green);
  }

  /* --- Primary navigation -------------------------------------------------- */

  .kw-nav {
    flex: 1;
    display: flex;
    justify-content: center;
    max-width: 620px;
  }

  .kw-nav__list {
    display: flex;
    flex: 1;
  }

  .kw-nav__item {
    flex: 1;
    display: flex;
  }

  .kw-nav__link {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 6px 4px 7px;
    border-top: var(--kw-rule-active) solid transparent;
    color: var(--kw-marquee-quiet);
    transition:
      color var(--kw-dur-state) ease,
      border-color var(--kw-dur-state) ease;
  }

  .kw-nav__link:hover {
    color: var(--kw-ink);
    border-top-color: var(--kw-green);
  }

  /* Active section — set by the scroll-spy via aria-current="location", so the
     state is announced, not merely coloured. */
  .kw-nav__link[aria-current='location'] {
    color: var(--kw-ink);
    border-top-color: var(--kw-green);
  }

  .kw-nav__index {
    font-family: var(--kw-font-mono);
    /* 11px, not the 10px of the locked prototype: navigation is functional UI
       and is excluded from the 10px editorial tier by the agreed type policy. */
    font-size: var(--kw-size-label);
    letter-spacing: var(--kw-tracking-label);
    color: var(--kw-meta-faint);
    transition: color var(--kw-dur-state) ease;
  }

  .kw-nav__link:hover .kw-nav__index,
  .kw-nav__link[aria-current='location'] .kw-nav__index {
    color: var(--kw-green);
  }

  .kw-nav__label {
    font-size: var(--kw-size-ui);
    font-weight: var(--kw-weight-medium);
    letter-spacing: -0.01em;
  }

  /* --- Header actions ------------------------------------------------------ */

  .kw-header__actions {
    display: flex;
    align-items: center;
    gap: 14px;
    flex: 0 0 auto;
  }

  .kw-header__enquire {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding-block: 11px;
    border-bottom: var(--kw-rule-active) solid var(--kw-green);
    font-size: var(--kw-size-ui);
    font-weight: var(--kw-weight-medium);
    transition: color var(--kw-dur-state) ease;
  }

  .kw-header__enquire:hover {
    color: var(--kw-green);
  }

  .kw-header__toggle {
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: var(--kw-hairline) solid var(--kw-rule-ink-15);
    font-family: var(--kw-font-mono);
    /* 11px: this is a control, not editorial metadata. */
    font-size: var(--kw-size-label);
    letter-spacing: 0.12em;
    color: var(--kw-ink);
    cursor: pointer;
    transition:
      border-color var(--kw-dur-state) ease,
      color var(--kw-dur-state) ease;
  }

  .kw-header__toggle:hover {
    border-color: var(--kw-green);
    color: var(--kw-green);
  }

  /* --- Index sheet --------------------------------------------------------- */

  .kw-index-sheet {
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-10);
    background: var(--kw-paper-cream);
  }

  .kw-index-sheet[hidden] {
    display: none;
  }

  .kw-index-sheet__inner {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: clamp(28px, 4vw, 72px);
    align-items: start;
    padding-block: clamp(28px, 4vw, 60px) clamp(32px, 4vw, 56px);
  }

  .kw-index-sheet__nav ul {
    display: grid;
    gap: 2px;
  }

  .kw-index-sheet__link {
    display: flex;
    align-items: baseline;
    gap: 18px;
    padding-block: 10px;
    border-bottom: var(--kw-hairline) solid var(--kw-rule-ink-10);
    font-size: clamp(28px, 4vw, 58px);
    font-weight: var(--kw-weight-medium);
    letter-spacing: -0.04em;
    line-height: 1.02;
    transition: color var(--kw-dur-state) ease;
  }

  .kw-index-sheet__link:hover {
    color: var(--kw-green);
  }

  .kw-index-sheet__link--cta {
    border-bottom: 0;
  }

  .kw-index-sheet__link--cta em {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-weight: var(--kw-weight-regular);
    color: var(--kw-green);
  }

  .kw-index-sheet__index {
    font-family: var(--kw-font-mono);
    font-size: var(--kw-size-label);
    letter-spacing: var(--kw-tracking-label-fine);
    color: var(--kw-green);
  }

  .kw-index-sheet__aside {
    display: grid;
    gap: 26px;
    max-width: 420px;
    align-content: start;
  }

  .kw-index-sheet__note {
    font-size: 17px;
    line-height: var(--kw-leading-body);
    color: var(--kw-body-primary);
  }

  .kw-index-sheet__contact {
    font-size: 15px;
    color: var(--kw-body-secondary);
    width: fit-content;
    border-bottom: var(--kw-hairline) solid var(--kw-rule-ink-20);
    transition: color var(--kw-dur-state) ease;
  }

  .kw-index-sheet__contact:hover {
    color: var(--kw-green);
  }

  .kw-index-sheet__meta {
    margin: 0;
  }

  /* --- Responsive ---------------------------------------------------------- */

  /* Below the tablet threshold the inline nav gives way to the index sheet,
     exactly as the companion sheet composes it: wordmark + IDX only, with
     navigation reachable as a full sheet under one thumb. */
  @media (max-width: 900px) {
    .kw-nav,
    .kw-header__enquire {
      display: none;
    }

    .kw-header__bar {
      padding-block: 13px;
    }
  }

  @media (max-width: 900px) {
    .kw-index-sheet__inner {
      grid-template-columns: 1fr;
      gap: clamp(24px, 6vw, 40px);
    }
  }

/* ============================================================================
   Hero — translated directly from Hero.astro.
   ========================================================================= */

.kw-hero {
    padding-block: clamp(48px, 8vw, 120px) clamp(36px, 5vw, 80px);
  }

  /* --- Eyebrow metadata ----------------------------------------------------- */

  .kw-hero__meta {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 24px;
    padding-bottom: clamp(28px, 5vw, 72px);
  }

  /* --- Display heading ------------------------------------------------------ */

  .kw-hero__heading {
    font-size: var(--kw-size-display);
    font-weight: var(--kw-weight-medium);
    line-height: var(--kw-leading-display);
    letter-spacing: var(--kw-tracking-display);
    /* Optical tightening at display scale without crushing glyph shapes. */
    text-wrap: balance;
  }

  /*
    Each line is its own mask so the rise reads as a masked line, as composed.

    Clipping fix: Refinement 03 used padding-bottom:0.2em with margin-bottom:
    -0.18em, leaving a 0.02em net gain that still cropped descenders at
    line-height 0.9 — the "g" in "organisations" and "grow on." lost their tails.
    Here the padding fully clears the descender and the negative margin cancels
    it exactly, so descenders render while layout height is unchanged.
  */
  .kw-hero__line {
    display: block;
    overflow: hidden;
    padding-bottom: 0.3em;
    margin-bottom: -0.3em;
  }

  .kw-hero__line--mid {
    padding-left: var(--kw-hero-indent-2);
  }

  .kw-hero__line--deep {
    padding-left: var(--kw-hero-indent-4);
  }

  .kw-hero__line--green {
    color: var(--kw-green);
  }

  .kw-hero__accent {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-weight: var(--kw-weight-regular);
    letter-spacing: var(--kw-tracking-display-accent);
  }

  /*
    Entrance motion.

    Transform-only and fully opaque from the first painted frame, so the H1 is
    never hidden behind an opacity gate and never waits on JavaScript. The line
    starts 38% down inside its own mask, which leaves the majority of every
    glyph painted immediately — the LCP candidate resolves at first paint rather
    than at animation end.

    This preserves the rising-line character of the locked hero without
    reproducing its 104% travel, which put the entire heading off-screen until
    a script ran.
  */
  .kw-hero__rise {
    display: block;
    will-change: transform;
    animation: kw-hero-rise var(--kw-dur-rise) var(--kw-ease-rise) both;
    animation-delay: var(--kw-rise-delay, 0ms);
  }

  @keyframes kw-hero-rise {
    from {
      transform: translate3d(0, 38%, 0);
    }
    to {
      transform: translate3d(0, 0, 0);
    }
  }

  /* --- Lead + actions ------------------------------------------------------- */

  .kw-hero__foot {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: flex-end;
    gap: clamp(28px, 4vw, 64px);
    margin-top: clamp(36px, 5vw, 88px);
  }

  .kw-hero__lead {
    max-width: 540px;
    font-size: var(--kw-size-body);
    line-height: var(--kw-leading-body);
    color: var(--kw-body-primary);
    text-wrap: pretty;
  }

  .kw-hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
  }

  /* --- Media slot ----------------------------------------------------------- */

  .kw-hero__figure {
    margin-top: clamp(44px, 7vw, 104px);
    overflow: hidden;
    border: var(--kw-hairline) solid var(--kw-rule-ink-08);
  }

  /*
    Production placeholder — the neutral Media Figure treatment from DESIGN.md,
    not the prototype's striped fill.

    Geometry is the literal locked value from Refinement 03. The rendered
    composition is the source of truth, not the "21:9" caption: at 1440 the
    locked box renders nearer 2.27:1, so deriving the container from the label
    would have changed the section's height by ~60px.

    A fixed height is fully layout-stable — the box is reserved before any
    asset loads, so there is no CLS to trade away. When real media arrives it
    adapts to this container via object-fit and art direction; the container
    does not adapt to the media.
  */
  .kw-hero__media {
    /* content-box, matching the locked design, which has no box-sizing reset.
       The declared height is the content box and the 22px inset adds to it, so
       the slot renders 620px at 1440 rather than 576px. Overriding the global
       border-box here is what makes the declaration below literally equivalent
       to Refinement 03 rather than merely similar. */
    box-sizing: content-box;
    height: clamp(260px, 40vw, 600px);
    background: var(--kw-media-placeholder);
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    padding: 22px;
  }

  .kw-hero__media-note {
    color: var(--kw-label-muted);
  }

  /* --- Responsive ----------------------------------------------------------- */

  /*
    Mobile is the authored recomposition from the companion sheet, not a stack:
    the heading re-breaks to five lines with the italic accent holding its own
    line, and the indent stagger halves.
  */
  @media (max-width: 640px) {
    /*
      No font-size override here by design. The locked display clamp already
      floors at 42px, which at 390px is within 1px of the companion sheet's
      "holds at 11vw" intent (42.9px) — so the authored scale is preserved
      without inventing a step below the locked minimum.
    */

    /* "ambitious organisations" becomes two lines. */
    .kw-hero__accent {
      display: block;
    }

    .kw-hero__line--mid {
      padding-left: 0;
    }

    .kw-hero__line--deep {
      padding-left: 0;
    }

    .kw-hero__meta {
      gap: 8px 20px;
    }

    .kw-hero__foot {
      align-items: flex-start;
    }

    .kw-hero__actions {
      width: 100%;
      flex-direction: column;
      align-items: stretch;
    }

    .kw-hero__actions .kw-btn {
      justify-content: center;
    }

    .kw-hero__media {
      /* No height or padding override: the locked clamp floors at 260px and
         the 22px inset is constant across widths in Refinement 03. Only the
         caption stacks, so the two labels do not collide at this measure. */
      flex-direction: column;
      align-items: flex-start;
      justify-content: flex-end;
      gap: 6px;
    }
  }

  /* Between 641px and the desktop composition, halve the indent stagger so the
     lines still step without pushing the display type off-measure. */
  @media (min-width: 641px) and (max-width: 1024px) {
    .kw-hero__line--mid {
      padding-left: calc(var(--kw-hero-indent-2) / 2);
    }

    .kw-hero__line--deep {
      padding-left: calc(var(--kw-hero-indent-4) / 2);
    }
  }

  /* --- Reduced motion -------------------------------------------------------- */

  @media (prefers-reduced-motion: reduce) {
    .kw-hero__rise {
      animation: none;
      transform: none;
      will-change: auto;
    }
  }

/* ============================================================================
   Client proof — translated directly from ClientMarquee.astro.
   ========================================================================= */

.kw-proof {
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-10);
    border-bottom: var(--kw-hairline) solid var(--kw-rule-ink-10);
    background: var(--kw-warm-band);
    padding-block: clamp(30px, 4vw, 54px);
    overflow: hidden;
  }

  .kw-proof__head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 24px;
    flex-wrap: wrap;
    margin-bottom: clamp(24px, 3vw, 42px);
  }

  .kw-proof__heading {
    font-size: var(--kw-size-heading-small);
    font-weight: var(--kw-weight-medium);
    letter-spacing: var(--kw-tracking-heading-small);
  }

  .kw-proof__heading em {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-weight: var(--kw-weight-regular);
  }

  .kw-proof__reach {
    margin: 0;
  }

  /* --- Rows ---------------------------------------------------------------- */

  .kw-proof__row {
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-12);
  }

  .kw-proof__row--bottom {
    border-bottom: var(--kw-hairline) solid var(--kw-rule-ink-12);
  }

  .kw-marquee {
    display: flex;
    width: max-content;
    /* transform-only movement: no layout, no paint of surrounding content */
    will-change: transform;
  }

  .kw-marquee--left {
    padding-block: clamp(12px, 1.4vw, 20px);
  }

  .kw-marquee--right {
    padding-block: clamp(10px, 1.2vw, 17px);
    padding-left: clamp(40px, 7vw, 140px);
  }

  .kw-marquee__item {
    display: flex;
    align-items: baseline;
    gap: clamp(14px, 1.4vw, 22px);
    padding-inline: clamp(22px, 2.6vw, 44px);
    border-left: var(--kw-hairline) solid var(--kw-rule-ink-12);
    font-size: var(--kw-size-marquee-primary);
    font-weight: var(--kw-weight-medium);
    letter-spacing: var(--kw-tracking-marquee-primary);
    white-space: nowrap;
    color: var(--kw-ink);
    transition: color 0.5s ease;
  }

  .kw-marquee__index {
    font-family: var(--kw-font-mono);
    font-size: var(--kw-size-label-fine);
    letter-spacing: var(--kw-tracking-label);
    color: var(--kw-meta-faint);
  }

  .kw-marquee__item--serif {
    gap: clamp(12px, 1.2vw, 18px);
    border-left: 0;
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-weight: var(--kw-weight-regular);
    font-size: var(--kw-size-marquee-secondary);
    letter-spacing: -0.02em;
    color: var(--kw-marquee-quiet);
  }

  .kw-marquee__sector {
    font-family: var(--kw-font-mono);
    font-style: normal;
    font-size: var(--kw-size-label-fine);
    letter-spacing: var(--kw-tracking-label-fine);
    text-transform: uppercase;
    color: var(--kw-meta-faint);
  }

  /* --- Foot ---------------------------------------------------------------- */

  .kw-proof__foot {
    display: flex;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
    margin-top: clamp(14px, 1.8vw, 24px);
  }

  .kw-proof__foot .kw-label {
    color: var(--kw-meta-faint);
  }

  /* --- Motion --------------------------------------------------------------
     Movement is added only when the visitor has not asked for reduced motion.
     Without it the rows simply sit still, fully legible — the content is never
     gated behind the animation. */

  @media (prefers-reduced-motion: no-preference) {
    .kw-marquee--left {
      animation: kw-marquee-left 112s linear infinite;
    }

    .kw-marquee--right {
      animation: kw-marquee-right 148s linear infinite;
    }

    /* "Movement holds on hover" — the promise the foot label makes. */
    .kw-proof:hover .kw-marquee,
    .kw-proof:focus-within .kw-marquee {
      animation-play-state: paused;
    }

    /* Mobile: one row at half cadence, per the companion sheet. */
    @media (max-width: 640px) {
      .kw-marquee--left {
        animation-duration: 224s;
      }
    }
  }

  @keyframes kw-marquee-left {
    from {
      transform: translate3d(0, 0, 0);
    }
    to {
      transform: translate3d(-50%, 0, 0);
    }
  }

  @keyframes kw-marquee-right {
    from {
      transform: translate3d(-50%, 0, 0);
    }
    to {
      transform: translate3d(0, 0, 0);
    }
  }

  /* --- Responsive ----------------------------------------------------------
     Mobile drops to a single row rather than shrinking both, so the band stays
     calm at small sizes instead of becoming a dense ticker. */

  @media (max-width: 640px) {
    .kw-proof__row--bottom {
      display: none;
    }

    .kw-proof__row--top {
      border-bottom: var(--kw-hairline) solid var(--kw-rule-ink-12);
    }

    .kw-proof__foot {
      /* The hover note is meaningless without a pointer. */
      justify-content: flex-start;
    }

    .kw-proof__motion-note {
      display: none;
    }
  }

/* ============================================================================
   Positioning — translated directly from Positioning.astro.
   ========================================================================= */

.kw-positioning {
    padding-block: clamp(76px, 11vw, 180px);
  }

  .kw-positioning__heading {
    margin-bottom: clamp(30px, 5vw, 72px);
    font-size: var(--kw-size-statement);
    font-weight: var(--kw-weight-medium);
    line-height: var(--kw-leading-statement);
    letter-spacing: var(--kw-tracking-headline);
    /* The 14ch measure is what makes the statement break as composed. */
    max-width: 14ch;
  }

  .kw-positioning__heading em {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-weight: var(--kw-weight-regular);
  }

  /*
    The asymmetry is the section: the heading sits hard left at a short measure,
    the body is pushed right and held to 1060px. Nothing else happens here.
  */
  .kw-positioning__body {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: clamp(24px, 4vw, 72px);
    max-width: 1060px;
    margin-left: auto;
  }

  .kw-positioning__para {
    font-size: var(--kw-size-body);
    line-height: 1.62;
    color: var(--kw-body-primary);
    text-wrap: pretty;
  }

  .kw-positioning__para--secondary {
    color: var(--kw-body-secondary);
  }

  /*
    Mobile recomposition: the two paragraphs stop being columns and become a
    single reading column, and the heading's measure widens slightly so it does
    not break into a narrow stack of two-word lines at 390px.
  */
  @media (max-width: 640px) {
    .kw-positioning__heading {
      max-width: 11ch;
      margin-bottom: clamp(24px, 8vw, 40px);
    }

    .kw-positioning__body {
      grid-template-columns: 1fr;
      gap: clamp(18px, 5vw, 28px);
      margin-left: 0;
    }
  }

/* ============================================================================
   Contextual cursor — translated directly from ContextCursor.astro.
   ========================================================================= */

.kw-cursor {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 9000;
    /* Never blocks a click, a hover or a text selection. */
    pointer-events: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 74px;
    height: 74px;
    border-radius: var(--kw-radius-full);
    background: var(--kw-green);
    color: var(--kw-paper-cream);
    font-family: var(--kw-font-mono);
    font-size: var(--kw-size-label);
    letter-spacing: var(--kw-tracking-label-fine);
    opacity: 0;
    transition: opacity 0.3s ease;
    will-change: transform;
  }

  .kw-cursor[hidden] {
    display: none;
  }

  .kw-cursor[data-visible='true'] {
    opacity: 1;
  }

/* ============================================================================
   WordPress integration adjustments.
   These selectors accommodate native theme output without changing the locked
   component geometry or visual language.
   ========================================================================= */

.custom-logo-link {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  min-height: 28px;
}

.custom-logo {
  width: auto;
  height: auto;
  max-width: min(220px, 35vw);
  max-height: 32px;
}

.admin-bar .kw-header {
  top: var(--wp-admin--admin-bar--height, 32px);
}

@media screen and (max-width: 782px) {
  .admin-bar .kw-header {
    top: 46px;
  }
}

/* ============================================================================
   Northrose — locked Astro component source.
   ========================================================================= */
.kw-northrose {
    padding-block: var(--kw-section-y-compact);
  }

  /* --- Eyebrow -------------------------------------------------------------- */

  .kw-northrose__eyebrow {
    display: flex;
    align-items: center;
    gap: 16px;
  }

  .kw-northrose__eyebrow-lead {
    color: var(--kw-mint);
  }

  .kw-northrose__eyebrow-meta {
    color: var(--kw-dark-meta);
  }

  .kw-northrose__rule {
    flex: 1;
    height: var(--kw-hairline);
    background: var(--kw-rule-cream-18);
  }

  /* --- Heading -------------------------------------------------------------- */

  .kw-northrose__heading {
    margin-top: clamp(26px, 4vw, 54px);
    font-size: var(--kw-size-headline-feature);
    font-weight: var(--kw-weight-medium);
    line-height: var(--kw-leading-headline-feature);
    letter-spacing: var(--kw-tracking-headline-feature);
    max-width: 21ch;
  }

  .kw-northrose__heading em {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-weight: var(--kw-weight-regular);
  }

  /* --- Intro: supporting copy + facts --------------------------------------- */

  .kw-northrose__intro {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: clamp(24px, 3vw, 56px);
    align-items: end;
    margin-top: clamp(34px, 5vw, 72px);
  }

  .kw-northrose__supporting {
    font-size: var(--kw-size-body);
    line-height: 1.62;
    color: var(--kw-dark-body);
    max-width: 52ch;
    text-wrap: pretty;
  }

  .kw-northrose__facts {
    /* dl carries a 1em block margin by default and is not in the base reset.
       The artboard has none. */
    margin: 0;
    display: grid;
    align-content: end;
  }

  .kw-northrose__fact {
    display: flex;
    justify-content: space-between;
    gap: 20px;
    padding-block: 11px;
    border-top: var(--kw-hairline) solid var(--kw-rule-cream-12);
  }

  .kw-northrose__fact-key {
    color: var(--kw-dark-meta);
  }

  .kw-northrose__fact-value {
    margin: 0;
    color: var(--kw-paper-cream);
    text-align: right;
  }

  /* --- Media ---------------------------------------------------------------- */

  .kw-northrose__figure {
    margin-top: clamp(30px, 4vw, 60px);
    overflow: hidden;
    border: var(--kw-hairline) solid var(--kw-rule-cream-14);
  }

  /*
    Neutral production placeholders on the dark ground — not the prototype's
    striped fill. Geometry is the locked value, and content-box matches the
    locked box model (Refinement 03 has no box-sizing reset), so the declared
    height and the 24px inset compose exactly as they do in the artboard.

    Fixed geometry reserves its own space, so real assets swap in with no
    layout shift and no change to the composition.
  */
  .kw-northrose__media {
    box-sizing: content-box;
    background: var(--kw-media-placeholder-dark);
    display: flex;
    align-items: flex-end;
  }

  .kw-northrose__media--primary {
    height: clamp(280px, 44vw, 660px);
    justify-content: space-between;
    gap: 16px;
    padding: 24px;
  }

  .kw-northrose__media--secondary {
    aspect-ratio: 4 / 3;
    padding: 14px;
    border: var(--kw-hairline) solid var(--kw-rule-cream-12);
    transition: border-color var(--kw-dur-state) ease;
  }

  .kw-northrose__slot:hover .kw-northrose__media--secondary {
    border-color: var(--kw-mint);
  }

  .kw-northrose__media-note {
    color: var(--kw-dark-meta);
  }

  .kw-northrose__slots {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: clamp(12px, 1.6vw, 24px);
    margin-top: clamp(12px, 1.6vw, 24px);
  }

  .kw-northrose__slot {
    margin: 0;
  }

  .kw-northrose__slot-caption {
    margin-top: 9px;
    font-size: var(--kw-size-caption);
    color: var(--kw-dark-meta);
  }

  /* --- Scope + close -------------------------------------------------------- */

  .kw-northrose__scope {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: clamp(24px, 4vw, 64px);
    align-items: start;
    margin-top: clamp(36px, 5vw, 76px);
  }

  .kw-northrose__scope-label {
    color: var(--kw-mint);
    padding-bottom: 14px;
  }

  .kw-northrose__caps {
    border-top: var(--kw-hairline) solid var(--kw-rule-cream-14);
  }

  .kw-northrose__cap {
    display: flex;
    align-items: baseline;
    gap: 18px;
    padding-block: 12px;
    border-bottom: var(--kw-hairline) solid var(--kw-rule-cream-12);
  }

  .kw-northrose__cap-index {
    font-family: var(--kw-font-mono);
    font-size: var(--kw-size-label);
    letter-spacing: var(--kw-tracking-label-fine);
    color: var(--kw-mint);
    min-width: 24px;
  }

  .kw-northrose__cap-label {
    font-size: var(--kw-size-detail);
    color: var(--kw-dark-body);
  }

  /* Reserved for confirmed period data; empty until then. */
  .kw-northrose__cap-period {
    margin-left: auto;
    white-space: nowrap;
    color: var(--kw-dark-meta);
  }

  .kw-northrose__close {
    display: grid;
    gap: 22px;
    align-content: start;
  }

  .kw-northrose__quote {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-size: var(--kw-size-body-accent);
    line-height: var(--kw-leading-body-accent);
    letter-spacing: -0.015em;
    color: var(--kw-paper-cream);
    max-width: 26ch;
  }

  .kw-northrose__cta {
    display: inline-flex;
    align-items: center;
    gap: 14px;
    width: fit-content;
    padding-bottom: 9px;
    border-bottom: var(--kw-rule-active) solid var(--kw-mint);
    font-size: var(--kw-size-detail);
    font-weight: var(--kw-weight-medium);
    transition: color var(--kw-dur-state) ease;
  }

  .kw-northrose__cta:hover {
    color: var(--kw-mint);
  }

  /* --- Responsive ------------------------------------------------------------
     Mobile recomposition: the eyebrow's second half drops below its rule rather
     than being squeezed, the intro stops trying to bottom-align two unequal
     columns, and the three secondary slots become a single readable column. */

  @media (max-width: 640px) {
    .kw-northrose__eyebrow {
      flex-wrap: wrap;
      gap: 8px 16px;
    }

    .kw-northrose__rule {
      order: 3;
      flex-basis: 100%;
    }

    .kw-northrose__intro {
      grid-template-columns: 1fr;
      align-items: start;
      gap: clamp(24px, 7vw, 36px);
    }

    .kw-northrose__slots {
      grid-template-columns: 1fr;
    }

    .kw-northrose__scope {
      grid-template-columns: 1fr;
    }
  }

/* ============================================================================
   Capabilities — locked Astro component source.
   ========================================================================= */
.kw-caps-section {
    padding-block: clamp(76px, 11vw, 170px);
  }

  .kw-caps-section__eyebrow {
    display: flex;
    align-items: center;
    gap: 16px;
  }

  .kw-caps-section__rule {
    flex: 1;
    height: var(--kw-hairline);
    background: var(--kw-rule-ink-15);
  }

  .kw-caps-section__heading {
    margin-block: clamp(26px, 4vw, 54px) clamp(36px, 5vw, 80px);
    font-size: var(--kw-size-headline);
    font-weight: var(--kw-weight-medium);
    line-height: var(--kw-leading-headline);
    letter-spacing: var(--kw-tracking-headline);
    max-width: 16ch;
  }

  /* --- The two-column composition -------------------------------------------
     Exactly two grid items, so auto-fit resolves to the locked 626 / 626. */

  .kw-caps {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: clamp(24px, 4vw, 72px);
    align-items: start;
    /* fieldset resets */
    margin: 0;
    padding: 0;
    border: 0;
    min-inline-size: 0;
  }

  /* The radios are the state machine; they are never seen. */
  .kw-caps__input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  .kw-caps__list {
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-15);
  }

  .kw-caps__label {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 18px;
    align-items: baseline;
    padding-block: clamp(20px, 2.4vw, 34px);
    border-bottom: var(--kw-hairline) solid var(--kw-rule-ink-15);
    border-left: var(--kw-rule-active) solid transparent;
    color: var(--kw-meta-faint);
    cursor: pointer;
    /* 0.5s colour and rule, 0.6s inset below — the artboard's own values. */
    transition:
      color var(--kw-dur-state-mid) ease,
      border-color var(--kw-dur-state-mid) ease;
  }

  /*
    The artboard insets the active row by animating padding-left. That animates
    layout on every frame, so the inset rides on transform instead — applied to
    the index and title only, which is where the movement reads. The state label
    sits in the right-hand track and does not move under padding-left either, so
    the result is equivalent and nothing reflows.
  */
  .kw-caps__index,
  .kw-caps__title {
    transition: transform var(--kw-dur-state-slow) cubic-bezier(0.22, 0.61, 0.36, 1);
  }

  .kw-caps__index,
  .kw-caps__state {
    font-family: var(--kw-font-mono);
    /* 11px, not the artboard's 10px: these sit inside a control, and the 10px
       tier stays reserved for tertiary editorial metadata. */
    font-size: var(--kw-size-label);
    letter-spacing: var(--kw-tracking-label);
    color: var(--kw-meta-faint);
    transition: color var(--kw-dur-state-mid) ease;
  }

  .kw-caps__state {
    text-transform: uppercase;
    letter-spacing: var(--kw-tracking-label-fine);
  }

  .kw-caps__title {
    font-size: var(--kw-size-title);
    font-weight: var(--kw-weight-medium);
    letter-spacing: var(--kw-tracking-title);
    line-height: 1.02;
  }

  .kw-caps__state-on {
    display: none;
  }

  /* --- Selected, hover and focus states -------------------------------------
     Each radio governs the row and panel that share its index. Written out
     because a sibling combinator cannot infer that pairing. */

  .kw-caps__label:hover {
    color: var(--kw-ink);
  }

  #kw-cap-01:checked ~ .kw-caps__list .kw-caps__label:nth-child(1),
  #kw-cap-02:checked ~ .kw-caps__list .kw-caps__label:nth-child(2),
  #kw-cap-03:checked ~ .kw-caps__list .kw-caps__label:nth-child(3) {
    color: var(--kw-ink);
    border-left-color: var(--kw-green);
  }

  #kw-cap-01:checked ~ .kw-caps__list .kw-caps__label:nth-child(1) .kw-caps__index,
  #kw-cap-01:checked ~ .kw-caps__list .kw-caps__label:nth-child(1) .kw-caps__title,
  #kw-cap-02:checked ~ .kw-caps__list .kw-caps__label:nth-child(2) .kw-caps__index,
  #kw-cap-02:checked ~ .kw-caps__list .kw-caps__label:nth-child(2) .kw-caps__title,
  #kw-cap-03:checked ~ .kw-caps__list .kw-caps__label:nth-child(3) .kw-caps__index,
  #kw-cap-03:checked ~ .kw-caps__list .kw-caps__label:nth-child(3) .kw-caps__title {
    transform: translateX(clamp(12px, 1.2vw, 20px));
  }

  #kw-cap-01:checked ~ .kw-caps__list .kw-caps__label:nth-child(1) .kw-caps__index,
  #kw-cap-02:checked ~ .kw-caps__list .kw-caps__label:nth-child(2) .kw-caps__index,
  #kw-cap-03:checked ~ .kw-caps__list .kw-caps__label:nth-child(3) .kw-caps__index {
    color: var(--kw-green);
  }

  #kw-cap-01:checked ~ .kw-caps__list .kw-caps__label:nth-child(1) .kw-caps__state-on,
  #kw-cap-02:checked ~ .kw-caps__list .kw-caps__label:nth-child(2) .kw-caps__state-on,
  #kw-cap-03:checked ~ .kw-caps__list .kw-caps__label:nth-child(3) .kw-caps__state-on {
    display: inline;
  }

  #kw-cap-01:checked ~ .kw-caps__list .kw-caps__label:nth-child(1) .kw-caps__state-off,
  #kw-cap-02:checked ~ .kw-caps__list .kw-caps__label:nth-child(2) .kw-caps__state-off,
  #kw-cap-03:checked ~ .kw-caps__list .kw-caps__label:nth-child(3) .kw-caps__state-off {
    display: none;
  }

  /* Focus lands on the visually-hidden radio, so the label paints the ring. */
  #kw-cap-01:focus-visible ~ .kw-caps__list .kw-caps__label:nth-child(1),
  #kw-cap-02:focus-visible ~ .kw-caps__list .kw-caps__label:nth-child(2),
  #kw-cap-03:focus-visible ~ .kw-caps__list .kw-caps__label:nth-child(3) {
    outline: var(--kw-focus-width) solid var(--kw-focus-color);
    outline-offset: var(--kw-focus-offset);
  }

  /* --- Panels ---------------------------------------------------------------
     One region. All three panels share it; only the selected one displays, so
     the region's height is the selected panel's height and the selector column
     beside it never moves. */

  /*
    All three panels share one grid cell, so the region is always as tall as
    the tallest panel and the section height never changes when the selection
    does. The bodies differ in length; without this the section would grow and
    shrink by ~67px as capabilities are chosen, which is the reflow the locked
    composition avoids.

    visibility (not display) keeps the cell occupied while still removing the
    inactive panels from the accessibility tree and the tab order.
  */
  .kw-caps__panels {
    display: grid;
    min-height: clamp(300px, 30vw, 420px);
  }

  .kw-caps__panel {
    grid-area: 1 / 1;
    display: grid;
    gap: 22px;
    align-content: start;
    visibility: hidden;
    opacity: 0;
    /* No transition on the way out: the outgoing panel clears instantly so the
       two never overlap in the shared cell. Only the incoming one eases in. */
  }

  #kw-cap-01:checked ~ .kw-caps__panels .kw-caps__panel:nth-child(1),
  #kw-cap-02:checked ~ .kw-caps__panels .kw-caps__panel:nth-child(2),
  #kw-cap-03:checked ~ .kw-caps__panels .kw-caps__panel:nth-child(3) {
    visibility: visible;
    opacity: 1;
    transition: opacity var(--kw-dur-panel) ease;
  }

  .kw-caps__panel-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 16px;
    padding-bottom: 10px;
    border-bottom: var(--kw-hairline) solid var(--kw-rule-ink-15);
    font-family: var(--kw-font-mono);
    font-size: var(--kw-size-label);
    letter-spacing: var(--kw-tracking-label);
    text-transform: uppercase;
  }

  .kw-caps__counter {
    color: var(--kw-green);
  }

  .kw-caps__panel-label {
    color: var(--kw-meta-faint);
  }

  .kw-caps__figure {
    margin: 0;
    overflow: hidden;
    border: var(--kw-hairline) solid var(--kw-rule-ink-08);
  }

  /* Neutral production placeholder at the locked 16:10 geometry. content-box
     matches the artboard's box model so the inset composes identically. */
  .kw-caps__media {
    box-sizing: content-box;
    aspect-ratio: 16 / 10;
    background: var(--kw-media-placeholder);
    display: flex;
    align-items: flex-end;
    padding: 16px;
  }

  .kw-caps__lead {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-size: var(--kw-size-cap-lead);
    line-height: 1.22;
    letter-spacing: -0.015em;
  }

  .kw-caps__body {
    font-size: var(--kw-size-body-sm);
    line-height: 1.66;
    color: var(--kw-body-secondary);
    max-width: 54ch;
    text-wrap: pretty;
  }

  .kw-caps__labels {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 22px;
    padding-top: 14px;
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-15);
  }

  /* Not chips: bare letterspaced labels in a row, no fill, no radius, no border. */
  .kw-caps__chip {
    letter-spacing: 0.12em;
    color: var(--kw-label-muted);
  }

  /* --- Mobile ---------------------------------------------------------------
     Only here does the composition become an accordion, per the companion
     sheet. `display: contents` dissolves both wrappers so the labels and panels
     become siblings in one column, and `order` interleaves them so each panel
     follows its own row. Same markup, same radios, same keyboard model. */

  @media (max-width: 760px) {
    .kw-caps {
      grid-template-columns: 1fr;
      gap: 0;
    }

    .kw-caps__list,
    .kw-caps__panels {
      display: contents;
    }

    .kw-caps__label:nth-child(1) {
      order: 1;
      border-top: var(--kw-hairline) solid var(--kw-rule-ink-15);
    }
    .kw-caps__panel:nth-child(1) {
      order: 2;
    }
    .kw-caps__label:nth-child(2) {
      order: 3;
    }
    .kw-caps__panel:nth-child(2) {
      order: 4;
    }
    .kw-caps__label:nth-child(3) {
      order: 5;
    }
    .kw-caps__panel:nth-child(3) {
      order: 6;
    }

    /* Back into normal flow for the accordion: each panel sits under its own
       row, and only the selected one is rendered at all. */
    .kw-caps__panel {
      grid-area: auto;
      display: none;
      visibility: visible;
      padding-block: clamp(18px, 5vw, 28px);
      border-bottom: var(--kw-hairline) solid var(--kw-rule-ink-15);
    }

    #kw-cap-01:checked ~ .kw-caps__panels .kw-caps__panel:nth-child(1),
    #kw-cap-02:checked ~ .kw-caps__panels .kw-caps__panel:nth-child(2),
    #kw-cap-03:checked ~ .kw-caps__panels .kw-caps__panel:nth-child(3) {
      display: grid;
    }
  }

  /* --- Reduced motion -------------------------------------------------------- */

  /* Motion is suppressed, but every state change still happens instantly —
     hover, focus, click and tap all keep working. */
  @media (prefers-reduced-motion: reduce) {
    .kw-caps__label,
    .kw-caps__index,
    .kw-caps__title,
    #kw-cap-01:checked ~ .kw-caps__panels .kw-caps__panel:nth-child(1),
    #kw-cap-02:checked ~ .kw-caps__panels .kw-caps__panel:nth-child(2),
    #kw-cap-03:checked ~ .kw-caps__panels .kw-caps__panel:nth-child(3) {
      transition: none;
    }
  }

/* ============================================================================
   SelectedWork — locked Astro component source.
   ========================================================================= */
.kw-work {
    padding-block: var(--kw-section-y-compact);
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-10);
  }

  .kw-work__eyebrow {
    display: flex;
    align-items: center;
    gap: 16px;
  }

  .kw-work__rule {
    flex: 1;
    height: var(--kw-hairline);
    background: var(--kw-rule-ink-15);
  }

  .kw-work__heading {
    margin-block: clamp(26px, 4vw, 54px) clamp(36px, 5vw, 80px);
    font-size: var(--kw-size-headline);
    font-weight: var(--kw-weight-medium);
    line-height: var(--kw-leading-headline);
    letter-spacing: var(--kw-tracking-headline);
    max-width: 17ch;
  }

  .kw-work__list {
    display: grid;
    gap: clamp(44px, 7vw, 120px);
  }

  /* --- Asymmetry ------------------------------------------------------------
     The uneven measures and alignments are the composition, not an accident.
     Each project takes its own width and side from the data. */

  .kw-project {
    max-width: var(--kw-project-width);
  }

  .kw-project--end {
    margin-left: auto;
  }

  .kw-project__link {
    display: grid;
    gap: 18px;
  }

  /* --- Media ---------------------------------------------------------------- */

  .kw-project__figure {
    margin: 0;
    overflow: hidden;
    border: var(--kw-hairline) solid var(--kw-rule-ink-08);
  }

  /*
    Neutral production placeholder. When a real image replaces the inner div it
    inherits this box: fixed ratio, object-fit: cover, and intrinsic width/height
    from the data so nothing shifts. Work imagery is below the fold and should
    load lazily — the hero remains the only eager media on this page.
  */
  .kw-project__media {
    box-sizing: content-box;
    aspect-ratio: var(--kw-project-ratio);
    background: var(--kw-media-placeholder);
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    padding: 18px;
    transition: transform 1.1s cubic-bezier(0.22, 0.61, 0.36, 1);
    will-change: transform;
  }

  /* Restrained drift, transform-only: no layout, no reflow, nothing to repaint
     outside the clipped figure. */
  .kw-project__link:hover .kw-project__media,
  .kw-project__link:focus-visible .kw-project__media {
    transform: scale(1.035);
  }

  .kw-project__media-note {
    color: var(--kw-label-muted);
  }

  /* --- Metadata -------------------------------------------------------------
     Always visible. The artboard fades this in on hover; carrying project
     information on hover alone puts it out of reach of keyboard and touch, so
     it stays legible and hover is left to the media. */

  .kw-project__meta {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: clamp(14px, 2vw, 40px);
    align-items: baseline;
    padding-top: 16px;
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-15);
  }

  .kw-project__client {
    font-size: var(--kw-size-project-title);
    font-weight: var(--kw-weight-medium);
    letter-spacing: var(--kw-tracking-title);
    line-height: 1.02;
    transition: color var(--kw-dur-state) ease;
  }

  .kw-project__link:hover .kw-project__client,
  .kw-project__link:focus-visible .kw-project__client {
    color: var(--kw-green);
  }

  .kw-project__statement {
    font-size: var(--kw-size-body-sm);
    line-height: 1.6;
    color: var(--kw-body-secondary);
    max-width: 34ch;
  }

  .kw-project__disciplines {
    display: grid;
    gap: 6px;
    align-content: start;
  }

  .kw-project__disciplines .kw-label {
    color: var(--kw-label-muted);
  }

  /* --- Mobile ---------------------------------------------------------------
     Asymmetry that reads as composition on a wide screen reads as inconsistent
     margins on a phone, so the measures reset to full width. The editorial
     feeling is carried by scale, spacing and the alternating alignment of the
     metadata instead of by desktop offsets.

     Reading order is already correct in the DOM: identity, media, statement,
     disciplines. */

  @media (max-width: 760px) {
    .kw-project,
    .kw-project--end {
      max-width: 100%;
      margin-left: 0;
    }

    .kw-work__list {
      gap: clamp(40px, 12vw, 64px);
    }

    /*
      Mobile reading order is identity → media → statement → disciplines, which
      is not the desktop stack. `display: contents` dissolves the metadata
      wrapper so its three children become siblings of the figure and can be
      ordered directly. The separating rule moves onto the client name, which
      now opens the block instead of closing it.

      The figure is aria-hidden, so this visual reorder cannot desynchronise
      from what a screen reader announces — it already hears identity first.
    */
    .kw-project__meta {
      display: contents;
    }

    .kw-project__client {
      order: 1;
      padding-top: 16px;
      border-top: var(--kw-hairline) solid var(--kw-rule-ink-15);
    }

    .kw-project__figure {
      order: 2;
    }

    .kw-project__statement {
      order: 3;
      max-width: 100%;
    }

    .kw-project__disciplines {
      order: 4;
    }

    .kw-project__disciplines {
      grid-auto-flow: column;
      justify-content: start;
      gap: 18px;
    }
  }

  /* --- Reduced motion -------------------------------------------------------- */

  @media (prefers-reduced-motion: reduce) {
    .kw-project__media {
      transition: none;
      will-change: auto;
    }

    .kw-project__link:hover .kw-project__media,
    .kw-project__link:focus-visible .kw-project__media {
      transform: none;
    }
  }

/* ============================================================================
   TechnicalDepth — locked Astro component source.
   ========================================================================= */
.kw-depth {
    padding-block: clamp(76px, 11vw, 170px);
    background: var(--kw-warm-band);
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-10);
  }

  .kw-depth__heading {
    font-size: var(--kw-size-headline);
    font-weight: var(--kw-weight-medium);
    line-height: var(--kw-leading-headline);
    letter-spacing: var(--kw-tracking-headline);
    max-width: 16ch;
  }

  .kw-depth__heading em {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-weight: var(--kw-weight-regular);
    color: var(--kw-marquee-quiet);
  }

  /* --- Intro pair ----------------------------------------------------------- */

  .kw-depth__intro {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: clamp(28px, 4vw, 72px);
    margin-top: clamp(30px, 4vw, 56px);
  }

  .kw-depth__para {
    font-size: var(--kw-size-body);
    line-height: 1.62;
    color: var(--kw-body-primary);
    text-wrap: pretty;
  }

  .kw-depth__para--secondary {
    color: var(--kw-body-secondary);
  }

  /* --- Layer groups --------------------------------------------------------- */

  .kw-depth__groups {
    margin-top: clamp(40px, 5vw, 80px);
  }

  .kw-depth__group {
    margin-bottom: clamp(26px, 3.4vw, 46px);
  }

  .kw-depth__group-head {
    display: flex;
    align-items: baseline;
    gap: 16px;
    padding-bottom: 10px;
    font-family: var(--kw-font-mono);
    font-size: var(--kw-size-label);
    font-weight: var(--kw-weight-regular);
    letter-spacing: var(--kw-tracking-label);
    text-transform: uppercase;
  }

  .kw-depth__group-key {
    color: var(--kw-green);
  }

  .kw-depth__group-title {
    color: var(--kw-ink);
  }

  .kw-depth__group-rule {
    flex: 1;
    height: var(--kw-hairline);
    background: var(--kw-rule-ink-15);
  }

  .kw-depth__group-note {
    color: var(--kw-meta-faint);
  }

  .kw-depth__rows {
    /* dl carries a 1em block margin by default and is not in the base reset. */
    margin: 0;
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-15);
  }

  /*
    Four tracks, matching the artboard: index, term, description, tag. The row
    is a grid container and its dt/dd are placed directly, so the definition
    list stays semantically intact while laying out as a table-like row.
  */
  .kw-depth__row {
    display: grid;
    grid-template-columns:
      minmax(36px, 0.24fr) minmax(150px, 1fr)
      minmax(220px, 2.1fr) minmax(120px, 0.8fr);
    gap: clamp(14px, 3vw, 44px);
    align-items: baseline;
    padding-block: clamp(15px, 1.9vw, 25px);
    border-bottom: var(--kw-hairline) solid var(--kw-rule-ink-15);
    transition: background var(--kw-dur-state-mid) ease;
  }

  /* Depth of stack expressed as depth of indent — a 1.6vw step per layer. */
  .kw-depth__row[data-depth='1'] {
    padding-left: calc(var(--kw-indent-step) * 1);
  }
  .kw-depth__row[data-depth='2'] {
    padding-left: calc(var(--kw-indent-step) * 2);
  }
  .kw-depth__row[data-depth='3'] {
    padding-left: calc(var(--kw-indent-step) * 3);
  }
  .kw-depth__row[data-depth='4'] {
    padding-left: calc(var(--kw-indent-step) * 4);
  }

  .kw-depth__row:hover {
    background: #e9e4d9;
  }

  /*
    A dl may only contain dt, dd, or a div grouping them — and that div may
    only contain dt and dd. So the index and tag sit inside the dt and dd
    rather than beside them, and both wrappers dissolve here so all four spans
    remain direct grid items of the row. Valid list semantics, four tracks
    rendered exactly as before.
  */
  .kw-depth__term,
  .kw-depth__desc {
    display: contents;
  }

  .kw-depth__row-index {
    font-family: var(--kw-font-mono);
    font-size: var(--kw-size-label-fine);
    letter-spacing: var(--kw-tracking-label);
    color: var(--kw-green);
  }

  .kw-depth__row-title {
    font-size: var(--kw-size-layer-title);
    font-weight: var(--kw-weight-medium);
    letter-spacing: -0.025em;
  }

  .kw-depth__row-body {
    margin: 0;
    font-size: var(--kw-size-detail);
    line-height: 1.6;
    color: var(--kw-body-secondary);
  }

  .kw-depth__row-tag {
    font-family: var(--kw-font-mono);
    font-size: var(--kw-size-label-fine);
    letter-spacing: var(--kw-tracking-label-fine);
    text-transform: uppercase;
    color: var(--kw-label-muted);
    text-align: right;
  }

  /* --- Closing statement ---------------------------------------------------- */

  .kw-depth__closing {
    margin-top: clamp(36px, 5vw, 72px);
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-size: var(--kw-size-statement-sm);
    line-height: 1.24;
    letter-spacing: -0.015em;
    max-width: 23ch;
  }

  /* --- Mobile ---------------------------------------------------------------
     The four-track row cannot survive at 390px, so each layer becomes a small
     stacked record: index and tag share a line, then the term, then the
     description. The indent ladder halves so the stack still reads as depth
     without pushing the description into a two-word column. */

  @media (max-width: 760px) {
    .kw-depth__row {
      grid-template-columns: auto 1fr;
      gap: 6px 14px;
      padding-block: clamp(14px, 4vw, 20px);
    }

    .kw-depth__row-index {
      grid-column: 1;
      grid-row: 1;
    }

    .kw-depth__row-tag {
      grid-column: 2;
      grid-row: 1;
      text-align: left;
    }

    .kw-depth__row-title {
      grid-column: 1 / -1;
      grid-row: 2;
    }

    .kw-depth__row-body {
      grid-column: 1 / -1;
      grid-row: 3;
    }

    .kw-depth__row[data-depth='1'] {
      padding-left: calc(var(--kw-indent-step) * 0.5);
    }
    .kw-depth__row[data-depth='2'] {
      padding-left: calc(var(--kw-indent-step) * 1);
    }
    .kw-depth__row[data-depth='3'] {
      padding-left: calc(var(--kw-indent-step) * 1.5);
    }
    .kw-depth__row[data-depth='4'] {
      padding-left: calc(var(--kw-indent-step) * 2);
    }

    .kw-depth__group-head {
      flex-wrap: wrap;
      gap: 8px 12px;
    }

    .kw-depth__group-rule {
      display: none;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .kw-depth__row {
      transition: none;
    }
  }

/* ============================================================================
   Founder — locked Astro component source.
   ========================================================================= */
.kw-founder {
    padding-block: clamp(76px, 11vw, 170px);
  }

  .kw-founder__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: clamp(28px, 4vw, 80px);
    /* The two columns meet at their feet, not their heads. */
    align-items: end;
  }

  /* --- Portrait -------------------------------------------------------------- */

  .kw-founder__figure {
    margin: 0;
  }

  .kw-founder__media {
    /* content-box matches the artboard, which has no box-sizing reset: the
       18px inset adds to the 4:5 box rather than eating into it. */
    box-sizing: content-box;
    aspect-ratio: 4 / 5;
    background: var(--kw-media-placeholder);
    border: var(--kw-hairline) solid var(--kw-rule-ink-08);
    display: flex;
    align-items: flex-end;
    padding: 18px;
    overflow: hidden;
  }

  .kw-founder__media-note {
    color: var(--kw-label-muted);
  }

  .kw-founder__caption {
    margin-top: 12px;
    font-size: var(--kw-size-caption-lg);
    color: var(--kw-label-muted);
  }

  /* --- Text column ----------------------------------------------------------- */

  .kw-founder__text {
    max-width: 720px;
    padding-bottom: clamp(0px, 3vw, 48px);
  }

  .kw-founder__eyebrow {
    color: var(--kw-label-muted);
  }

  .kw-founder__heading {
    margin-block: 18px clamp(26px, 4vw, 44px);
    font-size: var(--kw-size-headline-founder);
    font-weight: var(--kw-weight-medium);
    line-height: var(--kw-leading-headline-tight);
    letter-spacing: -0.04em;
  }

  .kw-founder__heading em {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-weight: var(--kw-weight-regular);
  }

  .kw-founder__para {
    margin-bottom: 20px;
    font-size: var(--kw-size-body-narrow);
    line-height: 1.62;
    color: var(--kw-body-primary);
    text-wrap: pretty;
  }

  .kw-founder__para--secondary {
    margin-bottom: clamp(26px, 4vw, 42px);
    color: var(--kw-body-secondary);
  }

  .kw-founder__closing {
    display: flex;
    flex-wrap: wrap;
    gap: 20px 40px;
    align-items: baseline;
    padding-top: 20px;
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-15);
  }

  .kw-founder__statement {
    font-size: var(--kw-size-statement-inline);
    font-weight: var(--kw-weight-medium);
    letter-spacing: -0.02em;
    color: var(--kw-green);
  }

  .kw-founder__closing-meta {
    color: var(--kw-label-muted);
  }

  /* --- Mobile ---------------------------------------------------------------
     Text leads on a phone: the eyebrow and heading introduce the person before
     the portrait appears, rather than opening on an image with no context.
     Bottom-alignment is meaningless in one column, so it is dropped. */

  @media (max-width: 760px) {
    .kw-founder__grid {
      grid-template-columns: 1fr;
      align-items: start;
      gap: clamp(28px, 8vw, 44px);
    }

    .kw-founder__portrait-col {
      order: 2;
    }

    .kw-founder__text {
      order: 1;
      max-width: 100%;
      padding-bottom: 0;
    }

    .kw-founder__closing {
      gap: 12px 28px;
    }
  }

/* ============================================================================
   Process — locked Astro component source.
   ========================================================================= */
.kw-process {
    padding-block: var(--kw-section-y-compact);
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-10);
  }

  .kw-process__eyebrow {
    color: var(--kw-label-muted);
  }

  .kw-process__heading {
    margin-block: clamp(22px, 3vw, 44px) clamp(36px, 5vw, 80px);
    font-size: var(--kw-size-headline-process);
    font-weight: var(--kw-weight-medium);
    line-height: var(--kw-leading-headline-tight);
    letter-spacing: -0.04em;
    max-width: 20ch;
  }

  .kw-process__list {
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-15);
  }

  .kw-process__step {
    /* Emphasis, 0 muted to 1 full. Defaults to 1 so every row is fully
       legible before — or without — the controller. */
    --kw-step-e: 1;
    display: grid;
    grid-template-columns: minmax(48px, 0.35fr) minmax(180px, 1.3fr) minmax(200px, 2fr);
    gap: clamp(14px, 3vw, 48px);
    align-items: baseline;
    padding-block: clamp(18px, 2.4vw, 32px);
    border-bottom: var(--kw-hairline) solid var(--kw-rule-ink-15);
  }

  /* Each step sits one rung deeper than the last — a 1.6vw ladder. */
  .kw-process__step[data-depth='1'] {
    padding-left: calc(var(--kw-indent-step) * 1);
  }
  .kw-process__step[data-depth='2'] {
    padding-left: calc(var(--kw-indent-step) * 2);
  }
  .kw-process__step[data-depth='3'] {
    padding-left: calc(var(--kw-indent-step) * 3);
  }
  .kw-process__step[data-depth='4'] {
    padding-left: calc(var(--kw-indent-step) * 4);
  }

  .kw-process__index {
    font-family: var(--kw-font-mono);
    /* 10px, matching the artboard. Permitted here because this is tertiary
       editorial numbering, not a control: the <ol> already carries the
       sequence, and the digits reinforce it. */
    font-size: var(--kw-size-label-fine);
    letter-spacing: var(--kw-tracking-label);
    /*
      Quiet metadata grey warming to green. The artboard runs this the other
      way — Ink when inactive, green when active — which means the number gets
      *lighter* as its row wakes up, working against the title beside it.
      Starting from Meta Faint makes the number recede with its row and arrive
      with it. The plain value is the fallback where color-mix is unavailable.
    */
    color: var(--kw-green);
    color: color-mix(in oklab, var(--kw-meta-faint), var(--kw-green) calc(var(--kw-step-e) * 100%));
  }

  .kw-process__title {
    font-size: var(--kw-size-title);
    font-weight: var(--kw-weight-medium);
    letter-spacing: var(--kw-tracking-title);
    line-height: 1.02;
    color: var(--kw-ink);
    color: color-mix(in oklab, var(--kw-meta-faint), var(--kw-ink) calc(var(--kw-step-e) * 100%));
  }

  .kw-process__summary {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-size: var(--kw-size-process-summary);
    /*
      Resolves to Body Primary, not Body Secondary. Against Meta Faint the
      secondary tone was only 4.80:1 -> 9.31:1, and the two greys read as
      nearly the same weight in a row of italic text. Body Primary widens that
      to 13.37:1 while staying a step softer than the title, so the serif line
      still sits below the name rather than competing with it.
    */
    color: var(--kw-body-primary);
    color: color-mix(
      in oklab,
      var(--kw-meta-faint),
      var(--kw-body-primary) calc(var(--kw-step-e) * 100%)
    );
  }

  /* --- Progression -----------------------------------------------------------
     Layered on top of already-legible rows. No JavaScript, and both gates must
     pass before any of it applies. */

  /* Nothing to declare here: emphasis arrives as --kw-step-e from the
     controller below, and the colour rules above translate it. Under reduced
     motion the controller never starts, so every row stays at 1. */

  /* --- Mobile ---------------------------------------------------------------
     Three tracks will not hold at 390px. The index and title share the first
     line, the summary takes the second, and the ladder halves so step 05 does
     not lose half its measure to indentation. */

  @media (max-width: 760px) {
    .kw-process__step {
      grid-template-columns: auto 1fr;
      gap: 4px 14px;
      padding-block: clamp(16px, 4vw, 22px);
    }

    .kw-process__index {
      grid-column: 1;
      grid-row: 1;
    }

    .kw-process__title {
      grid-column: 2;
      grid-row: 1;
    }

    .kw-process__summary {
      grid-column: 2;
      grid-row: 2;
    }

    .kw-process__step[data-depth='1'] {
      padding-left: calc(var(--kw-indent-step) * 0.5);
    }
    .kw-process__step[data-depth='2'] {
      padding-left: calc(var(--kw-indent-step) * 1);
    }
    .kw-process__step[data-depth='3'] {
      padding-left: calc(var(--kw-indent-step) * 1.5);
    }
    .kw-process__step[data-depth='4'] {
      padding-left: calc(var(--kw-indent-step) * 2);
    }
  }

/* ============================================================================
   Testimonials — locked Astro component source.
   ========================================================================= */
.kw-voices {
    padding-block: var(--kw-section-y-compact);
  }

  .kw-voices__eyebrow {
    color: var(--kw-label-muted);
  }

  .kw-voices__heading {
    margin-block: clamp(22px, 3vw, 44px) clamp(40px, 6vw, 88px);
    font-size: var(--kw-size-headline-process);
    font-weight: var(--kw-weight-medium);
    line-height: var(--kw-leading-headline-tight);
    letter-spacing: -0.04em;
    max-width: 18ch;
  }

  .kw-voices__heading em {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-weight: var(--kw-weight-regular);
  }

  .kw-voices__stack {
    display: grid;
    gap: clamp(40px, 5vw, 80px);
  }

  /* --- One voice -------------------------------------------------------------
     The uneven measures are the composition: each quote takes its own width
     and side, so the column edge never settles into a straight line. */

  .kw-voice {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: clamp(18px, 3vw, 64px);
    align-items: start;
    padding-top: clamp(20px, 2.6vw, 34px);
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-15);
    max-width: var(--kw-voice-width);
  }

  .kw-voice--end {
    margin-left: auto;
  }

  .kw-voice__attribution {
    display: grid;
    gap: 7px;
    align-content: start;
  }

  .kw-voice__person {
    font-size: var(--kw-size-detail);
    font-weight: var(--kw-weight-medium);
  }

  .kw-voice__org {
    font-size: var(--kw-size-caption-lg);
    color: var(--kw-label-muted);
  }

  .kw-voice__discipline {
    margin-top: 5px;
    color: var(--kw-green);
  }

  /* The quote takes the remaining two tracks, so the attribution sits in a
     narrow column beside a long measure rather than above it. */
  .kw-voice__quote {
    grid-column: span 2;
    font-size: var(--kw-size-quote);
    font-weight: var(--kw-weight-regular);
    line-height: 1.32;
    letter-spacing: -0.022em;
    color: var(--kw-ink);
    text-wrap: pretty;
  }

  /* --- Mobile ---------------------------------------------------------------
     Asymmetry that reads as composition on a wide screen reads as inconsistent
     margins on a phone, so the measures reset. The quote leads and the
     attribution follows it, which is the order the sentence is actually read
     in; the rule and the spacing carry the editorial feeling instead. */

  @media (max-width: 760px) {
    .kw-voice,
    .kw-voice--end {
      max-width: 100%;
      margin-left: 0;
      grid-template-columns: 1fr;
      gap: 16px;
    }

    .kw-voice__quote {
      grid-column: 1;
      order: 1;
    }

    .kw-voice__attribution {
      order: 2;
    }

    .kw-voices__stack {
      gap: clamp(36px, 11vw, 56px);
    }
  }

/* ============================================================================
   FinalCta — locked Astro component source.
   ========================================================================= */
.kw-cta {
    padding-block: clamp(84px, 12vw, 200px);
  }

  .kw-cta__heading {
    font-size: var(--kw-size-cta);
    font-weight: var(--kw-weight-medium);
    line-height: var(--kw-leading-display);
    letter-spacing: var(--kw-tracking-display);
    max-width: 14ch;
  }

  /*
    The mask clips the line as it rises. The descender padding and the matching
    negative margin keep the clip off the glyphs — without them the tail of a
    'g' is cut at rest, which was the defect corrected in the hero.
  */
  .kw-cta__mask {
    display: block;
    overflow: hidden;
    padding-bottom: 0.2em;
    margin-bottom: -0.18em;
  }

  .kw-cta__mask--inset {
    padding-left: clamp(0px, 9vw, 160px);
  }

  .kw-cta__line {
    display: block;
  }

  .kw-cta__heading em {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-weight: var(--kw-weight-regular);
    color: var(--kw-mint);
  }

  /* --- Closing row ----------------------------------------------------------- */

  .kw-cta__row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 32px;
    margin-top: clamp(36px, 5vw, 72px);
    padding-top: clamp(24px, 3vw, 40px);
    border-top: var(--kw-hairline) solid var(--kw-rule-cream-14);
  }

  .kw-cta__lead {
    font-size: var(--kw-size-cta-lead);
    color: var(--kw-dark-body);
  }

  .kw-cta__action {
    display: inline-flex;
    align-items: center;
    gap: 18px;
    background: var(--kw-green);
    color: var(--kw-paper-cream);
    padding: 22px 40px;
    font-size: var(--kw-size-body-sm);
    font-weight: var(--kw-weight-medium);
    min-height: var(--kw-target-min);
    box-sizing: border-box;
    transition:
      background var(--kw-dur-state) ease,
      color var(--kw-dur-state) ease;
  }

  .kw-cta__action:hover {
    background: var(--kw-mint);
    color: var(--kw-deep-ink);
  }

  /* --- The rise --------------------------------------------------------------
     Only ever applied by the observer, and only when motion is welcome. The
     lines are already painted; this animates them from below on first entry
     and never runs again. */

  @media (prefers-reduced-motion: no-preference) {
    .kw-cta[data-rise] .kw-cta__line {
      animation: kw-cta-rise 1.15s cubic-bezier(0.19, 0.72, 0.26, 1) both;
    }

    .kw-cta[data-rise] .kw-cta__mask:nth-child(2) .kw-cta__line {
      animation-delay: 95ms;
    }

    @keyframes kw-cta-rise {
      from {
        transform: translate3d(0, 104%, 0);
      }
      to {
        transform: none;
      }
    }
  }

  @media (max-width: 760px) {
    .kw-cta__row {
      gap: 24px;
    }

    .kw-cta__action {
      width: 100%;
      justify-content: center;
    }
  }

/* ============================================================================
   SiteFooter — locked Astro component source.
   ========================================================================= */
.kw-footer {
    padding-block: clamp(52px, 7vw, 104px) 40px;
    background: var(--kw-paper-cream);
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-15);
  }

  .kw-footer__statement {
    margin-bottom: clamp(44px, 6vw, 100px);
    font-size: var(--kw-size-footer-statement);
    font-weight: var(--kw-weight-medium);
    line-height: 0.94;
    letter-spacing: var(--kw-tracking-display);
  }

  .kw-footer__statement em {
    font-family: var(--kw-font-serif);
    font-style: italic;
    font-weight: var(--kw-weight-regular);
    color: var(--kw-marquee-quiet);
  }

  .kw-footer__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 32px;
    padding-top: 26px;
    border-top: var(--kw-hairline) solid var(--kw-rule-ink-15);
  }

  .kw-footer__identity {
    display: grid;
    gap: 8px;
    align-content: start;
  }

  .kw-footer__wordmark {
    font-size: var(--kw-size-caption-lg);
    font-weight: var(--kw-weight-wordmark);
    letter-spacing: -0.02em;
  }

  .kw-footer__identity .kw-label {
    color: var(--kw-label-muted);
  }

  .kw-footer__nav {
    display: grid;
    gap: 11px;
    align-content: start;
    font-size: var(--kw-size-detail);
    color: var(--kw-body-secondary);
  }

  /*
    The artboard sets these links 11px apart with no padding, leaving a 19px
    hit area — under the 24px minimum, and they are standalone navigation
    rather than links in a sentence, so the inline exception does not apply.

    Padding would fix it but would also grow the footer by 6px. Instead the
    pressable area is extended past the text box by an absolutely positioned
    pseudo-element: the link accepts pointer events across 25px while its own
    box, and therefore the whole footer, keeps the artboard's geometry. The
    3px reach either side leaves 5px of the 11px gap clear, so neighbouring
    targets never overlap.
  */
  .kw-footer__nav a {
    position: relative;
    width: fit-content;
  }

  .kw-footer__nav a::after {
    content: '';
    position: absolute;
    inset: -3px 0;
  }

  .kw-footer__copyright {
    color: var(--kw-label-muted);
    align-self: start;
  }

  /* --- Mobile ---------------------------------------------------------------
     Two columns rather than four narrow ones or a single long list: the
     navigations stay scannable side by side, and the statement keeps the
     footer feeling like space rather than a sitemap. */

  @media (max-width: 760px) {
    .kw-footer__grid {
      grid-template-columns: repeat(2, 1fr);
      gap: 28px 20px;
    }

    .kw-footer__identity,
    .kw-footer__copyright {
      grid-column: 1 / -1;
    }
  }

/* Native WordPress footer-logo accommodation. */
.kw-footer__identity .custom-logo-link {
  width: fit-content;
  min-height: 24px;
}

.kw-footer__identity .custom-logo {
  max-height: 24px;
}

/* CMS media occupies the already-reserved, design-locked placeholder boxes. */
.kw-hero__media,
.kw-northrose__media,
.kw-caps__media,
.kw-project__media,
.kw-founder__media {
  position: relative;
  overflow: hidden;
}

.kw-cms-media {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
}
