/* ==========================================================================
   Blue Lotus Strategies — V5
   Implements "Blue Lotus - Website Mocks.dc.html" ("Still Water", 1280px).
   Direction and the reasoning behind each device: BRAND.md
   ========================================================================== */

/* --- 1. Tokens ----------------------------------------------------------- */

:root {
  --navy:        #0A4166;
  --navy-deep:   #062E4A;
  --navy-mid:    #12537E;
  --slate:       #7B99AD;
  --slate-ink:   #4E6474;   /* the mocks' label ink on the cream ground */
  --slate-light: #ABC1CF;
  --paper:       #F4F1E9;
  --warm:        #E7E4DC;   /* Warm Grey — the brand's second ground */
  --white:       #FFFFFF;
  --ink:         #14293A;
  --ink-soft:    #35495A;
  --ink-quiet:   #4F5F6A;

  /* A blue lotus has a yellow heart. One accent — numerals, figures, the rule
     under a link. Never a button fill. */
  --brass:       #9C7530;
  --brass-light: #D8BA7E;
  /* Brass with its lightness lowered, hue and saturation kept. Brass itself is
     3.72:1 on Paper Stone — fine at 24px and up, too faint for small figures.
     Brass Deep is 5.14:1 on Paper Stone and 4.57:1 on Warm Grey. See the
     accessibility addendum to the brand guidelines. */
  --brass-deep:  #806027;
  --still-blue:  #8FADC0;

  /* Mark fills. Four forms in three tones: on cream each tone darkens a step
     so the forms hold their weight; on navy the mark keeps logo.svg's own
     values, restored in the dark-ground rule below. */
  --mark-pale:   #9CB8C9;
  --mark-mid:    #6D92A9;
  --mark-deep:   #3C6880;

  --rule:        rgba(20, 41, 58, .15);
  --rule-mid:    rgba(20, 41, 58, .18);
  --rule-strong: rgba(20, 41, 58, .3);
  --rule-light:  rgba(255, 255, 255, .22);
  --rule-faint:  rgba(255, 255, 255, .16);

  --serif: "Newsreader", "Iowan Old Style", Georgia, serif;
  --sans:  "Archivo", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono:  "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --gutter:  clamp(1.5rem, 5vw, 5rem);
  --measure: 66ch;
  --ease:    cubic-bezier(.22, .61, .36, 1);
}

/* Wherever the mark sits on a dark ground it keeps its own colours. */
.field, .cta, .footer, [data-hero="dark"] .masthead:not(.is-stuck) {
  --mark-pale: #EEF4F7; --mark-mid: #8FADC0; --mark-deep: #4A7A94;
}

/* --- 2. Reset ------------------------------------------------------------ */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: clamp(1.0625rem, 1rem + .25vw, 1.0625rem);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { display: block; max-width: 100%; }
/* The browser's own [hidden] rule loses to any class that sets display — and
   .form sets display:grid — so a hidden form stayed on screen. Make the
   attribute win everywhere. */
[hidden] { display: none !important; }
a { color: inherit; }
button { font: inherit; }

h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 350;
  line-height: 1.1;
  letter-spacing: -.014em;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0; }
p + p { margin-top: 1.15em; }
ul { margin: 0; padding: 0; list-style: none; }

/* Focus rings need 3:1 against the ground they sit on (WCAG 1.4.11 / 2.4.7).
   Lotus Navy on the light grounds is 9.49:1; Still Blue on navy is 4.54:1.
   The navy masthead over the home hero is a dark ground too — it used to fall
   through to the light-ground ring and show navy on navy. */
:focus-visible { outline: 2px solid var(--navy); outline-offset: 3px; border-radius: 2px; }
.field :focus-visible, .cta :focus-visible, .footer :focus-visible,
[data-hero="dark"] .masthead:not(.is-stuck) :focus-visible {
  outline-color: var(--still-blue);
}

/* Said to a screen reader, never shown — "(opens in a new tab)" on the
   LinkedIn links, so the jump to another tab is not a surprise. */
.vh { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
      overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

.skip { position: absolute; left: -9999px; top: 0; z-index: 100;
        background: var(--navy); color: #fff; padding: .75rem 1.25rem; }
.skip:focus { left: .5rem; top: .5rem; }

/* --- 3. Layout ----------------------------------------------------------- */

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

/* Section heights vary deliberately — the page should not tick like a metronome. */
.section     { padding-block: clamp(4rem, 7vw, 6.5rem); }
.section--xl { padding-block: clamp(5rem, 9vw, 8rem); }
.section--sm { padding-block: clamp(2.25rem, 4vw, 3.25rem); }
.section--flush-b { padding-bottom: 0; }
.section--flush-t { padding-top: 0; }

.field { background: var(--navy); color: var(--white); position: relative; overflow: clip; }
.field p { color: rgba(255, 255, 255, .86); }
.field h1, .field h2, .field h3 { color: var(--white); }

/* --- 4. Type ------------------------------------------------------------- */

/* Size floors. Archivo and IBM Plex Mono never below 13px (.8125rem), and
   14px (.875rem) for anything you click — the nav, the buttons, the menu
   toggle, the form's field labels. Newsreader reading text never below 16px
   (1rem). The one exception is the "Strategies" line of the logo lockup, at
   12px, which is a logo.

   WCAG sets no minimum size, so these are the brand's own floors rather than
   a conformance line. The earlier ones — 11px small caps, 15px Newsreader —
   met the letter of 1.4.4, since everything still scales to 200%, while being
   smaller than anyone should have to read. 11px uppercase was the worst of
   it: the .16em tracking that makes a small label legible also makes it look
   larger than it measures. */

.label, .nav a, .btn, .tlink, .chip, .form label, .detail dt, .person__role,
.creds h4, .case__step h4, .result h4, .footer h4, .nav-toggle,
.sectionhead__intro ~ .tlink {
  font-family: var(--sans);
  font-size: .8125rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
}
/* A step up again for the things a person actually clicks. The tracking comes
   in as the size goes up: .16em was set for 11px, where letters need air to be
   told apart; at 14px it only makes the nav wide. */
.nav a, .btn, .nav-toggle, .form label {
  font-size: .875rem; letter-spacing: .13em;
}
.label { color: var(--slate-ink); line-height: 1.5; margin: 0; }
.field .label, .cta .label { color: #C3D3DE; }

/* The display face, at the two sizes the mocks use: the home headline, and
   every interior page head. */
.display {
  font-size: clamp(2.6rem, 1.4rem + 4.2vw, 2.875rem);
  font-weight: 300; line-height: 1.09; letter-spacing: -.03em;
  hanging-punctuation: first last;
}
.h2 { font-size: clamp(1.5rem, 1.15rem + 1.4vw, 1.875rem); font-weight: 350;
      letter-spacing: -.02em; line-height: 1.14; }
.h3 { font-size: clamp(1.15rem, 1.05rem + .5vw, 1.25rem); line-height: 1.2; }

/* A single sentence given a whole column. The mocks use it at two sizes:
   large for a section's thesis, small beside a form or a portrait. */
.statement {
  font-family: var(--serif); font-weight: 350;
  font-size: clamp(1.5rem, 1.05rem + 1.9vw, 2.5rem);
  line-height: 1.14; letter-spacing: -.024em; max-width: 30ch;
  text-wrap: balance;
}
/* A statement may run to two paragraphs; at display size the body rule's
   1.15em gap is far too big. */
.statement p + p { margin-top: .5em; }
.statement em { font-style: italic; color: var(--brass); }
.statement--sm em { color: var(--brass-deep); }   /* under 24px: Brass Deep */
.field .statement em, .cta .statement em { color: var(--brass-light); }
.statement--sm {
  font-size: clamp(1.15rem, 1.02rem + .6vw, 1.25rem);
  line-height: 1.45; letter-spacing: -.014em; max-width: 34ch;
}

/* A link inside a sentence. The standalone link is tracked caps with a brass
   rule under it (.tlink); inside running text that is impossible, so it keeps
   the rule and drops the caps — the treatment the form's error message already
   uses for its address. content.md can put [a link](x) in any block, so this
   covers the containers that render prose. The rule, not the colour, is what
   marks it (WCAG 1.4.1). */
.lede a, .prose a, .pair__body a, .person__bio a, .index__body a,
.case__step p a, .result p a {
  text-decoration: none; border-bottom: 1px solid var(--brass-deep);
}
.lede a:hover, .prose a:hover, .pair__body a:hover,
.person__bio a:hover, .index__body a:hover,
.case__step p a:hover, .result p a:hover { border-bottom-color: var(--ink); }
.field .lede a, .field .pair__body a, .field .person__bio a, .field .index__body a,
.field .case__step p a, .field .result p a {
  border-bottom-color: var(--brass-light);
}

.lede {
  font-family: var(--serif);
  font-size: clamp(1.05rem, 1rem + .3vw, 1.125rem);
  line-height: 1.6; color: var(--ink-soft); max-width: 54ch;
  margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
}
.field .lede { color: rgba(255, 255, 255, .86); }

.prose { max-width: var(--measure); color: var(--ink-soft); font-size: 1rem;
         line-height: 1.62; }
.field .prose { color: rgba(255, 255, 255, .78); }

.rule { border: 0; border-top: 1px solid var(--rule); margin: 0; }
.field .rule { border-top-color: var(--rule-light); }
.seam { margin-block: clamp(3rem, 6vw, 5rem) 0; }

/* --- 5. Buttons and links ------------------------------------------------ */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  white-space: nowrap; padding: 1.0625rem 1.75rem; text-decoration: none;
  border: 1px solid transparent; border-radius: 2px; cursor: pointer;
  transition: background-color .35s var(--ease), color .35s var(--ease),
              border-color .35s var(--ease);
}
.btn--primary { background: var(--navy); color: var(--white); }
.btn--primary:hover { background: var(--navy-deep); }
.btn--ghost { border-color: var(--rule-strong); color: var(--navy); background: transparent; }
.btn--ghost:hover { border-color: var(--navy); background: rgba(10, 65, 102, .05); }

.field .btn--primary, .cta .btn--primary { background: var(--white); color: var(--navy); }
.field .btn--primary:hover, .cta .btn--primary:hover { background: var(--slate-light); }

.btn-row { display: flex; flex-wrap: wrap; gap: 1.25rem 1.75rem; align-items: center; }

/* Every link that is not a button is a tracked cap with a brass rule under
   it — one link style on the whole site, so nothing else has to announce
   itself as clickable. */
.tlink {
  display: inline-block; text-decoration: none; color: var(--navy);
  padding-bottom: .4rem; border-bottom: 1px solid var(--brass);
  transition: color .35s var(--ease), border-color .35s var(--ease);
}
.tlink:hover { border-bottom-color: var(--ink); }
.field .tlink, .cta .tlink { color: var(--white); border-bottom-color: var(--brass-light); }
.field .tlink:hover, .cta .tlink:hover { border-bottom-color: var(--white); }

/* --- 6. Masthead --------------------------------------------------------- */

.masthead {
  position: sticky; top: 0; z-index: 50;
  background: rgba(244, 241, 233, .92);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  border-bottom: 1px solid var(--rule);
  transition: border-color .4s var(--ease), background-color .4s var(--ease);
}
/* In the mocks the masthead sits *inside* the navy hero, divided from it by a
   hairline. The bar here is a sticky element above the hero, so it takes the
   hero's ground itself and keeps that hairline — transparent would show the
   cream page behind white type. */
[data-hero="dark"] .masthead:not(.is-stuck) {
  background: var(--navy); border-bottom-color: var(--rule-faint);
}
[data-hero="dark"] .masthead:not(.is-stuck) .brand { color: var(--white); }
[data-hero="dark"] .masthead:not(.is-stuck) .brand__name small { color: var(--slate-light); }
[data-hero="dark"] .masthead:not(.is-stuck) .nav a { color: rgba(255, 255, 255, .82); }
[data-hero="dark"] .masthead:not(.is-stuck) .nav a:hover,
[data-hero="dark"] .masthead:not(.is-stuck) .nav a[aria-current="page"] { color: var(--white); }
[data-hero="dark"] .masthead:not(.is-stuck) .nav a::after { background: var(--white); }
[data-hero="dark"] .masthead:not(.is-stuck) .btn--primary {
  background: var(--white); color: var(--navy);
}
[data-hero="dark"] .masthead:not(.is-stuck) .nav a.btn--primary { color: var(--navy); }
[data-hero="dark"] .masthead:not(.is-stuck) .nav-toggle {
  color: var(--white); border-color: rgba(255, 255, 255, .4);
}
.masthead__inner { display: flex; align-items: center; justify-content: space-between;
                   gap: 1.5rem; min-height: 4.75rem; }

.brand { display: inline-flex; align-items: center; gap: .75rem;
         text-decoration: none; color: var(--navy); }
.brand__mark { width: 2rem; height: auto; flex: none; }
/* The stacked wordmark the mocks use: the name, then the discipline under it. */
.brand__name { font-family: var(--sans); font-weight: 700; font-size: .9375rem;
               letter-spacing: .005em; line-height: 1.15; }
/* Slate Ink, not Slate. WCAG exempts a logotype from 1.4.3 whatever its
   contrast, but this line is half the company's name and Slate left it at
   2.66:1 on the bone ground — exempt and unreadable is still unreadable.
   Slate Ink is 5.47:1. The dark grounds keep Slate Light, set above and in
   the footer. */
.brand__name small { display: block; font-weight: 700; font-size: .75rem;
                     letter-spacing: .14em; text-transform: uppercase;
                     color: var(--slate-ink); margin-top: .1rem; }

.nav { display: flex; align-items: center; gap: clamp(1.25rem, 2.4vw, 2rem); }
.nav a { text-decoration: none; color: var(--ink-soft);
         padding-block: .35rem; position: relative; transition: color .3s var(--ease); }
.nav a::after { content: ""; position: absolute; left: 0; right: 0; bottom: -.1rem;
                height: 1px; background: var(--navy);
                transform: scaleX(0); transform-origin: left;
                transition: transform .45s var(--ease); }
.nav a:hover { color: var(--navy); }
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }
.nav a[aria-current="page"] { color: var(--navy); }
.nav .btn { padding: .8125rem 1.375rem; }
.nav a.btn--primary, .nav a.btn--primary:hover { color: var(--white); }
.nav a.btn--primary::after { display: none; }

.nav-toggle { display: none; background: none; border: 1px solid var(--rule-strong);
              border-radius: 2px; color: var(--navy); padding: .65rem 1rem; cursor: pointer; }

@media (max-width: 61.99rem) {
  .nav-toggle { display: inline-block; }
  .nav { position: absolute; inset: 100% 0 auto; flex-direction: column;
         align-items: stretch; gap: 0; background: var(--paper);
         border-bottom: 1px solid var(--rule);
         padding: .5rem var(--gutter) 1.75rem; display: none; }
  .nav.is-open { display: flex; }
  .nav a { padding: .95rem 0; border-bottom: 1px solid var(--rule); color: var(--ink-soft); }
  .nav a::after { display: none; }
  .nav .btn { margin-top: 1.25rem; border-bottom: 0; }

  /* The panel drops below the bar onto the page's own cream, so its contents
     are always styled for a light ground — inheriting the dark hero's white
     nav type would put white on bone. The toggle itself stays in the navy
     bar, so it keeps the dark-ground treatment. */
  [data-hero="dark"] .masthead:not(.is-stuck) .nav a { color: var(--ink-soft); }
  [data-hero="dark"] .masthead:not(.is-stuck) .nav a:hover,
  [data-hero="dark"] .masthead:not(.is-stuck) .nav a[aria-current="page"] { color: var(--navy); }
  [data-hero="dark"] .masthead:not(.is-stuck) .nav a.btn--primary,
  [data-hero="dark"] .masthead:not(.is-stuck) .nav :focus-visible { outline-color: var(--navy); }
  [data-hero="dark"] .masthead:not(.is-stuck) .nav a.btn--primary:hover {
    background: var(--navy); color: var(--white);
  }
}

/* --- 7. Hero ------------------------------------------------------------- */

/* One screen and no more: the masthead is sticky rather than fixed, so the
   hero starts under it and 100svh minus the bar fills the rest. The headline
   is capped in vh as well as vw, which is what keeps the headline, the
   sentence and both calls to action above the fold on a short window. */
.hero {
  position: relative;
  display: flex; align-items: center;
  min-height: calc(100vh - 4.75rem);
  min-height: calc(100svh - 4.75rem);
  padding-block: clamp(2.5rem, 6vh, 4.5rem);
}
.hero__inner { position: relative; z-index: 1; width: 100%; }
.hero .display {
  /* The vh cap keeps the calls to action above the fold, but vh shrinks as a
     visitor zooms, so on its own it stopped the headline growing (WCAG 1.4.4,
     failure F94). The 2.75rem floor is half the 5.5rem ceiling, so browser
     zoom can always take the headline to at least twice its size. */
  font-size: max(2.75rem, min(clamp(2.6rem, 1rem + 5.6vw, 5.5rem), 11vh));
  max-width: 14ch; line-height: 1.08; letter-spacing: -.035em; margin-top: 0;
}
.hero__lede { margin-top: clamp(1.25rem, 3vh, 2rem); max-width: 52ch;
              font-size: clamp(1.05rem, 1rem + .45vw, 1.3125rem); line-height: 1.5;
              color: rgba(255, 255, 255, .86); }
.hero .btn-row { margin-top: clamp(1.5rem, 3.5vh, 2.5rem); }

/* The water photograph, with a navy scrim over it for text legibility. */
.hero__photo {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: url(../img/hero-water.jpg) center / cover no-repeat;
}
.hero__photo::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(105deg, var(--navy) 12%, rgba(10, 65, 102, .76) 46%,
                              rgba(6, 46, 74, .46) 100%);
}
@media (max-width: 47.99rem) {
  .hero__photo::after {
    background: linear-gradient(180deg, var(--navy) 22%, rgba(10, 65, 102, .8) 70%,
                                rgba(6, 46, 74, .58) 100%);
  }
}

/* --- 8. The mark in motion ----------------------------------------------
   Three treatments, all built on one fact about the artwork: its four petals
   radiate from a single point at the foot of the mark. Animate about *that*
   point (113, 373.5 in the artwork's own units) and a petal extends along its
   own axis; animate about the centre and it only gets bigger. BRAND.md §7.

   The services diagram has its own transforms on `.dgm .lotus > *`, so these
   are scoped to the brand mark and the footer mark and never meet it. */

.brand__mark .lotus > *, .footer__mark .lotus > * { transform-origin: 113px 373.5px; }
/* A bloom overshoots to 1.04, which reaches past the artwork's own bounds —
   and an SVG root clips by default. */
.brand__mark { overflow: visible; }

/* Bloom — armed from site.js on a visitor's first page only. */
@keyframes lotus-bloom {
  0%   { opacity: 0; transform: scale(.04) rotate(-9deg); }
  55%  { opacity: 1; }
  72%  { transform: scale(1.04) rotate(.6deg); }
  100% { opacity: 1; transform: scale(1) rotate(0deg); }
}
.brand__mark.is-bloom .lotus > * { animation: lotus-bloom 1s var(--ease) both; }
.brand__mark.is-bloom .lotus > *:nth-child(2) { animation-delay: 95ms; }
.brand__mark.is-bloom .lotus > *:nth-child(3) { animation-delay: 190ms; }
.brand__mark.is-bloom .lotus > *:nth-child(4) { animation-delay: 285ms; }

/* Ripple — whenever the logo is reached for, by pointer or by keyboard.
   Suppressed mid-bloom so the two cannot fight over the same property. */
@keyframes lotus-ripple {
  0%, 100% { transform: scale(1); }
  45%      { transform: scale(1.07); }
}
.brand:hover .brand__mark:not(.is-bloom) .lotus > *,
.brand:focus-visible .brand__mark:not(.is-bloom) .lotus > * {
  animation: lotus-ripple .62s ease-in-out both;
}
.brand:hover .brand__mark:not(.is-bloom) .lotus > *:nth-child(2),
.brand:focus-visible .brand__mark:not(.is-bloom) .lotus > *:nth-child(2) {
  animation-delay: 90ms;
}
.brand:hover .brand__mark:not(.is-bloom) .lotus > *:nth-child(3),
.brand:focus-visible .brand__mark:not(.is-bloom) .lotus > *:nth-child(3) {
  animation-delay: 180ms;
}
.brand:hover .brand__mark:not(.is-bloom) .lotus > *:nth-child(4),
.brand:focus-visible .brand__mark:not(.is-bloom) .lotus > *:nth-child(4) {
  animation-delay: 270ms;
}

/* Drift — a nine-second breath that never resolves, in the footer only. Over
   the navy-deep ground and under the type, held to the right so the columns
   always have clean ground. */
@keyframes lotus-drift {
  0%, 100% { transform: scale(1) translateY(0); }
  50%      { transform: scale(1.025) translateY(-5px); }
}
.footer__mark {
  position: absolute; z-index: 0; pointer-events: none;
  top: 50%; right: -4%; transform: translateY(-50%);
  width: auto; height: 190%; max-width: none;
  opacity: .07;
}
@media (max-width: 47.99rem) {
  .footer__mark { height: auto; width: 96%; right: -22%; top: 62%; opacity: .05; }
}
.footer__mark .lotus > * { animation: lotus-drift 9s ease-in-out infinite both; }
.footer__mark .lotus > *:nth-child(2) { animation-delay: 1.1s; }
.footer__mark .lotus > *:nth-child(3) { animation-delay: 2.2s; }
.footer__mark .lotus > *:nth-child(4) { animation-delay: 3.3s; }

/* The site-wide reduced-motion rule clamps every duration to .001ms, which
   would leave an infinite loop cycling. Stop these outright instead. */
@media (prefers-reduced-motion: reduce) {
  .brand__mark .lotus > *, .footer__mark .lotus > * { animation: none !important; }
}

/* --- 9. Page head -------------------------------------------------------- */

.pagehead { padding-block: clamp(3rem, 7vw, 6.875rem); }
.pagehead .display { max-width: 24ch; }
.pagehead .label { margin-bottom: clamp(1rem, 2vw, 1.5rem); }
/* Over the page-head photograph Slate measured 4.1:1 at worst; Deep Ink keeps
   the small eyebrow clear of it. */
.pagehead--art .label { color: var(--ink); }

/* Each interior head carries a photograph, faded back into the page colour on
   the left — where the headline lands — and at the foot, so it has no
   rectangle edge and the type always sits on clean paper. The stops are the
   published design output's own. Gradient overlays rather than a CSS mask:
   masks fail to composite in some renderers. */
.pagehead--art { position: relative; overflow: clip; }
.pagehead--art .wrap { position: relative; z-index: 1; }
.art {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-size: cover; background-position: center; background-repeat: no-repeat;
  opacity: .85;
}
.art::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(90deg, var(--paper) 6%, rgba(244, 241, 233, 0) 66%),
    linear-gradient(180deg, rgba(244, 241, 233, 0) 40%, var(--paper) 96%);
}
@media (max-width: 47.99rem) {
  /* On a phone the headline fills the measure, so a left-to-right fade cannot
     clear it. Fade top to bottom instead. */
  .art::after {
    background: linear-gradient(180deg, rgba(244, 241, 233, .4) 0%, var(--paper) 86%);
  }
}

/* --- 10. The pair -------------------------------------------------------
   A tracked label on the left, content on the right, a hairline between: the
   back of the business card at page scale, and the mocks' main structural
   device. */

.pair { display: grid; gap: clamp(1.25rem, 3vw, 2rem); }
.pair__main { min-width: 0; }
@media (min-width: 60rem) {
  .pair { grid-template-columns: 9.5rem minmax(0, 1fr); gap: clamp(2rem, 4vw, 3rem); }
  .pair__label { align-self: start; position: sticky; top: 7.5rem; }
  .pair__main { border-left: 1px solid var(--rule-mid); padding-left: clamp(2rem, 4vw, 3rem); }
  .field .pair__main, .cta .pair__main { border-left-color: var(--rule-light); }
  /* The services figure sits in the label column, so that column is wider.
     It sticks like a label does: the mark holds still while its five rows
     travel past it, which is the whole point of lighting them. */
  .pair--figure { grid-template-columns: minmax(0, 14rem) minmax(0, 1fr); }
  .pair--figure .pair__label { position: sticky; top: 7.5rem; }
}
.pair__body { margin-top: clamp(1.5rem, 3vw, 2.25rem); color: var(--ink-soft);
              font-size: 1rem; line-height: 1.62; max-width: 62ch; }
.field .pair__body, .cta .pair__body { color: rgba(255, 255, 255, .78); }

/* A section head: the title, and one thing beside it — a link, or an intro. */
.sectionhead { display: flex; flex-wrap: wrap; align-items: baseline;
               justify-content: space-between; gap: 1rem 2rem;
               margin-bottom: clamp(1.75rem, 3.5vw, 2.5rem); }

/* --- 11. The ruled index ------------------------------------------------
   Three columns: a mono numeral in a narrow rail, the title, the description.
   Hairlines, no fills — the list is the composition. */

.index { border-top: 1px solid var(--rule-mid); }
.field .index { border-top-color: var(--rule-light); }
.index__row {
  display: grid; gap: .5rem 1.75rem;
  padding-block: clamp(1.25rem, 2.4vw, 1.625rem);
  border-bottom: 1px solid var(--rule);
  position: relative; transition: background-color .5s var(--ease);
}
.field .index__row { border-bottom-color: var(--rule-light); }
.index__row::before {
  /* A rule in the margin marks the current row — the hairline system already
     in use, rather than a filled slab that breaks it. */
  content: ""; position: absolute; inset: 0 auto 0 -1.15rem; width: 2px;
  background: var(--brass); opacity: 0;
  transition: opacity .45s var(--ease); pointer-events: none;
}
.index__row:hover::before, .index__row.is-current::before { opacity: 1; }
.field .index__row::before { background: var(--brass-light); }

.index__num {
  font-family: var(--mono); font-size: .8125rem; font-weight: 400;
  letter-spacing: .18em; color: var(--brass-deep); font-variant-numeric: tabular-nums;
  padding-top: .45em;
}
.field .index__num { color: var(--brass-light); }
.index__title { font-family: var(--serif); font-weight: 350;
                font-size: clamp(1.15rem, 1.05rem + .5vw, 1.25rem); line-height: 1.24;
                letter-spacing: -.016em; text-wrap: balance; }
.index__body { color: var(--ink-soft); font-size: 1rem; line-height: 1.6; }
.field .index__body { color: rgba(255, 255, 255, .8); }

@media (max-width: 47.99rem) {
  .index__row { grid-template-columns: 2rem minmax(0, 1fr); align-items: baseline; }
  .index__body { grid-column: 2; }
}
@media (min-width: 48rem) {
  .index__row { grid-template-columns: 2.25rem minmax(0, 15rem) minmax(0, 1fr);
                align-items: baseline; }
}
/* Beside the figure the rows lose their third column, so the measure holds. */
@media (min-width: 48rem) {
  .pair--figure .index__row { grid-template-columns: 2.25rem minmax(0, 1fr); }
  .pair--figure .index__body { grid-column: 2; margin-top: .4rem; }
}

/* --- 12. The mark as a diagram -----------------------------------------
   Four petals, four areas of service — one each. Scrolling the list lights
   the matching petal, so the mark explains the offer rather than decorating
   it. */

.lotusgrid__fig { margin: 0; }
.dgm { width: 100%; height: auto; max-width: 13rem; }
/* Every petal grows from the point all four share at the foot of the mark. */
.dgm .lotus > * {
  transform-origin: 113px 373.5px;
  transition: opacity .55s var(--ease), transform .65s var(--ease);
}
[data-lotus].is-focused .lotus > *:not(.is-active) { opacity: .26; }
[data-lotus] .lotus > *.is-active { transform: scale(1.055); }
/* Returning to rest, the four petals open in the order they are drawn rather
   than snapping together. Picking one out of them is immediate. */
[data-lotus].is-rest .lotus > *:nth-child(2) { transition-delay: 60ms; }
[data-lotus].is-rest .lotus > *:nth-child(3) { transition-delay: 120ms; }
[data-lotus].is-rest .lotus > *:nth-child(4) { transition-delay: 180ms; }


/* --- 13. Chips ----------------------------------------------------------
   The mocks set the issue areas, and the case-study filter, as outlined
   chips: the tracked-caps voice in a box, so a set of tags reads as one
   object rather than as a paragraph of links. */

.chip {
  display: inline-flex; align-items: center;
  padding: .5625rem .875rem; border-radius: 2px;
  border: 1px solid var(--rule-strong); color: var(--ink);
  background: transparent;
  /* An issue area can be as long as "Anti-Corruption & Government
     Accountability", which is wider than a phone. A chip that cannot wrap
     simply loses its end: the row sits inside a clipped page head, so there is
     not even a sideways scroll to find it. Short names still take one line —
     they fit — so wrapping costs nothing and keeps every label readable. */
  max-width: 100%; white-space: normal; text-align: left;
}
.field .chip, .cta .chip { border-color: rgba(255, 255, 255, .3); color: var(--white); }

.filter { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1.25rem;
          margin-top: clamp(2rem, 4vw, 3rem); }
.filter__label { flex: none; }
.filter__set { display: flex; flex-wrap: wrap; gap: .625rem; }
.chip--btn { cursor: pointer; transition: background-color .3s var(--ease),
             color .3s var(--ease), border-color .3s var(--ease); }
.chip--btn:hover { border-color: var(--navy); }
.chip--btn[aria-pressed="true"] { background: var(--navy); color: var(--white);
                                  border-color: var(--navy); }
.cases__empty { color: var(--ink-soft); font-size: 1rem;
                padding: clamp(3rem, 6vw, 5rem) var(--gutter);
                max-width: 70rem; margin-inline: auto; }

/* --- 14. The issue-area ribbon ------------------------------------------
   On the home page the same list is set large and travels past on a loop,
   separated by a brass lozenge. It pauses on hover; under
   prefers-reduced-motion the track stops and wraps to a static list. */

.ribbon {
  --fade: clamp(2rem, 7vw, 7rem);
  --ribbon-bg: var(--paper);
  --ribbon-fade: rgba(244, 241, 233, 0);
  position: relative; overflow: hidden;
  border-block: 1px solid var(--rule-mid);
  padding-block: clamp(1.15rem, 2.2vw, 1.625rem);
}
.ribbon::before, .ribbon::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: var(--fade);
  z-index: 2; pointer-events: none;
}
.ribbon::before { left: 0;
  background: linear-gradient(90deg, var(--ribbon-bg) 22%, var(--ribbon-fade) 100%); }
.ribbon::after { right: 0;
  background: linear-gradient(270deg, var(--ribbon-bg) 22%, var(--ribbon-fade) 100%); }
.field .ribbon { --ribbon-bg: var(--navy); --ribbon-fade: rgba(10, 65, 102, 0);
                 border-block-color: var(--rule-light); }
/* Inline: the ribbon lives inside the column it is placed in rather than
   running the width of the window, so on the services page it travels within
   the pair's measure. Same marquee, clipped by its own box. */
.ribbon--inline {
  --fade: clamp(1.5rem, 4vw, 3rem);
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
}
.ribbon--inline .ribbon__item {
  font-size: clamp(1rem, .95rem + .35vw, 1.1875rem);
  gap: clamp(1rem, 2vw, 1.5rem);
  padding-inline: clamp(.5rem, 1vw, .75rem);
}
.ribbon--inline .ribbon__track { animation-duration: 38s; }

.ribbon__track { display: flex; width: max-content; animation: ribbon-drift 56s linear infinite; }
.ribbon:hover .ribbon__track { animation-play-state: paused; }

/* One switch for all ambient motion (WCAG 2.2.2). The preference lives on
   <html>, so a visitor who pauses on one page finds it paused on the next. */
.motion-paused .ribbon__track,
.motion-paused .footer__mark .lotus > * { animation-play-state: paused !important; }

.ribbon__ctl { display: flex; justify-content: flex-end; padding-top: .625rem; }
.motion-toggle {
  display: inline-flex; align-items: center; gap: .5rem;
  min-height: 1.75rem; padding: .25rem 0;
  background: none; border: 0; cursor: pointer;
  font-family: var(--sans); font-size: .8125rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--slate-ink);
}
.motion-toggle:hover .motion-toggle__label { text-decoration: underline; text-underline-offset: .2em; }
.field .motion-toggle { color: #C3D3DE; }
.footer .motion-toggle { color: rgba(255, 255, 255, .66); font-family: var(--mono);
                         font-weight: 400; letter-spacing: .12em; }
/* Two bars for pause, a triangle for play — drawn, so no icon font. */
.motion-toggle__icon { position: relative; width: .5rem; height: .5625rem; flex: none; }
.motion-toggle__icon::before, .motion-toggle__icon::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 2px; background: currentColor;
}
.motion-toggle__icon::before { left: 0; }
.motion-toggle__icon::after  { right: 0; }
.motion-toggle[aria-pressed="true"] .motion-toggle__icon::before {
  width: 0; height: 0; background: none; left: 0;
  border-left: .5rem solid currentColor;
  border-top: .28rem solid transparent; border-bottom: .28rem solid transparent;
}
.motion-toggle[aria-pressed="true"] .motion-toggle__icon::after { display: none; }
.ribbon__group { display: flex; align-items: center; flex: none; }
.ribbon__item {
  display: inline-flex; align-items: center; gap: clamp(1.25rem, 2.6vw, 2rem);
  padding-inline: clamp(.75rem, 1.4vw, 1.125rem);
  font-family: var(--serif); font-weight: 350;
  font-size: clamp(1.15rem, .98rem + .8vw, 1.5rem);
  letter-spacing: -.016em; line-height: 1.1;
  color: var(--ink); white-space: nowrap;
}
.field .ribbon__item { color: #fff; }
/* A brass lozenge rather than a petal: at this size a four-petal mark reads
   as a smudge, and the list needs a tick, not a second logo. */
.ribbon__dot { width: .3125rem; height: .3125rem; flex: none;
               background: var(--brass); transform: rotate(45deg); opacity: .85; }
.field .ribbon__dot { background: var(--brass-light); }
@keyframes ribbon-drift { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .ribbon::before, .ribbon::after { display: none; }
  .ribbon__track { animation: none; flex-wrap: wrap; width: 100%; }
  .ribbon__group:last-child { display: none; }
}

/* --- 15. Case studies ---------------------------------------------------- */

.case__eyebrow { display: flex; align-items: baseline; gap: 1rem; }
.case__num { font-family: var(--serif); font-size: 1.625rem; font-weight: 300;
             color: var(--brass); letter-spacing: -.01em; line-height: 1;
             font-variant-numeric: lining-nums; }
.field .case__num { color: var(--brass-light); }
.case__title { margin-top: clamp(.75rem, 1.5vw, 1.125rem); max-width: 26ch; }

.case__cols { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem);
              margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }
@media (min-width: 52rem) {
  .case__cols--2 { grid-template-columns: repeat(2, minmax(0, 1fr));
                   gap: clamp(2rem, 4vw, 3.5rem); }
}
.case__step h4 { color: var(--slate-ink); margin-bottom: .7rem; }
.field .case__step h4 { color: var(--slate-light); }
.case__step p { color: var(--ink-soft); font-size: 1rem; line-height: 1.6; max-width: 44ch; }
.field .case__step p { color: rgba(255, 255, 255, .8); }

/* Outcome as prose under a hairline — a result, not a fake statistic. The one
   real number on the site is set in brass inside the sentence. */
.result { border-top: 1px solid var(--rule-mid); padding-top: 1.25rem;
          margin-top: clamp(2rem, 4vw, 2.75rem); max-width: 44ch; }
.field .result { border-top-color: rgba(255, 255, 255, .3); }
.result h4 { color: var(--slate-ink); margin-bottom: .85rem; }
.field .result h4 { color: var(--slate-light); }
.result p { font-family: var(--serif); font-weight: 350;
            font-size: clamp(1.15rem, 1.05rem + .5vw, 1.25rem);
            line-height: 1.42; color: var(--ink); letter-spacing: -.014em; }
.field .result p { color: rgba(255, 255, 255, .94); }
.result p b { font-weight: 350; color: var(--brass-deep); }
.field .result p b { color: var(--brass-light); }
/* A paragraph-length outcome reads as prose: the full measure and body size,
   keeping the ink weight so it still lands harder than the situation beside
   it. Short outcomes keep the statement treatment above. */
.result--long { max-width: var(--measure); }
.result--long p { font-size: 1rem; line-height: 1.6; letter-spacing: 0; }

.result__more { margin-top: 1.75rem; }

/* --- 15b. Who we've worked with -----------------------------------------
   A row of logos on Navy Deep. Dark is not a style choice here: every logo is
   the white version its owner publishes for dark grounds, used exactly as
   supplied, because the US-Japan Foundation's guidelines say not to recolour
   theirs and the same courtesy is owed to the rest. Navy Deep rather than
   Lotus Navy because the featured case sits directly above it on Navy, and the
   second dark is what gives two dark sections an edge.

   Sized by eye, not by number: four logos of different proportions look even
   when their optical weight matches, which is not the same as matching their
   heights. The stacked one is allowed to be taller than the horizontal three.
   Nothing links anywhere — the row is to be recognised, not read. */

.clients { background: var(--navy-deep); color: var(--white); }
/* The heading is read, not seen (.vh), so the row sits at the top of the band
   with nothing above it and needs no margin of its own. */
.clients__row {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: clamp(1.5rem, 3.6vw, 3.25rem);
}
.clients__row img {
  display: block; width: auto; height: auto;
  /* --h is set per logo in the markup, worked out from that file's own
     proportions so all five carry about the same optical weight. */
  max-height: var(--h, 2.25rem); max-width: 14rem;
  /* The logos arrive at different densities; nothing is upscaled past its own
     pixels, so a small source simply sits a little smaller. No opacity, no
     filter, nothing: the US-Japan Foundation's guidelines say not to apply
     filters that obscure the design, and knocking 8% off every logo for the
     sake of a slightly softer row is not worth being the exception. */
}
@media (max-width: 47.99rem) {
  .clients__row { gap: clamp(1.75rem, 7vw, 2.5rem); }
  /* Everything down a notch together, so the row keeps its proportions. */
  .clients__row img { max-height: calc(var(--h, 2.25rem) * .82); max-width: 11rem; }
}

/* --- 16. Tenets ---------------------------------------------------------- */

.tenets { border-top: 1px solid var(--rule-mid); }
.tenet { border-bottom: 1px solid var(--rule);
         padding-block: clamp(1.75rem, 3.5vw, 2.5rem); display: grid; gap: .85rem; }
@media (min-width: 56rem) {
  .tenet { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
           gap: clamp(2.5rem, 5vw, 4rem); align-items: start; }
}
.tenet__title { font-family: var(--serif); font-weight: 350;
                font-size: clamp(1.15rem, 1.05rem + .55vw, 1.3125rem); line-height: 1.26;
                letter-spacing: -.016em; color: var(--ink); max-width: 22ch;
                text-wrap: balance; }
.tenet__body { color: var(--ink-soft); font-size: 1rem; line-height: 1.6;
               max-width: 52ch; margin: 0; }

/* --- 17. Bio and people -------------------------------------------------- */

.split { display: grid; gap: clamp(2rem, 4vw, 3.5rem); }
@media (min-width: 60rem) {
  .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
           gap: clamp(2.5rem, 5vw, 4rem); align-items: start; }
  .split--weighted { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
}

/* The portrait column is wide — 18rem — because the photograph is the only
   one on the site and has to carry that weight. The aside does not stick:
   it is a plate at the head of the column, not a rail that follows you. */
.bio { display: grid; gap: clamp(2rem, 4vw, 3rem);
       margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }
@media (min-width: 58rem) {
  .bio { grid-template-columns: minmax(0, 18rem) minmax(0, 1fr); gap: clamp(2.5rem, 5vw, 4rem); }
  .bio__aside { position: static; align-self: start; }
}
/* A hairline under the portrait, then the role, then the name. */
.bio__aside > .label { display: block; border-top: 1px solid var(--rule-strong);
                       padding-top: clamp(.9rem, 1.8vw, 1.2rem); }
/* The one photograph on the site. It is shot on a light grey backdrop, so the
   white point is raised until that backdrop clips out and multiply drops it
   into the ground behind — no box, no cool rectangle fighting the page. The
   grade also makes one portrait sit with a site that has no other. */
.bio__portrait { margin: 0 0 clamp(1.125rem, 2.2vw, 1.5rem); }
.bio__portrait img {
  width: 100%; height: auto; display: block;
  filter: grayscale(1) brightness(1.14) contrast(1.22);
  mix-blend-mode: multiply;
}
/* The grade assumes a light ground: the team block sits on the bone page, not
   on navy, which is what lets multiply drop the backdrop into the paper and
   give the grey a warm tint rather than a cold one. */
.bio__name { font-family: var(--serif); font-weight: 300;
             font-size: clamp(1.6rem, 1.25rem + 1.4vw, 2.1rem); line-height: 1.1;
             letter-spacing: -.02em; margin-top: .85rem; }
.bio__body .prose { margin-top: clamp(1.25rem, 2.5vw, 1.75rem); }
/* The opening line is the one sentence that introduces him, so it runs the
   full measure of the column rather than stopping at a statement's 34ch. */
.bio__body .statement--sm { max-width: none; }

/* The founder, on the home page. The portrait is 18rem against the partners'
   14.6rem plates below it — deliberately the larger of the two, so the page
   reads founder first, then the people he brings in. */
.founder { display: grid; gap: clamp(1.75rem, 3.5vw, 3rem); align-items: start; }
@media (min-width: 52rem) {
  .founder { grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);
             gap: clamp(2.5rem, 5vw, 4rem); }
}
.founder__fig { margin: 0; max-width: 18rem; }
.founder__body .bio__name { margin-top: .85rem; }
.founder__blurb { margin-top: clamp(1.25rem, 2.5vw, 1.75rem); color: var(--ink-soft);
                  font-size: 1rem; line-height: 1.6; max-width: 52ch; }
.founder__more { margin-top: clamp(1.5rem, 3vw, 2rem); }

.people { display: grid; gap: clamp(2.25rem, 4.5vw, 3.5rem); }
@media (min-width: 52rem) {
  .people--2 { grid-template-columns: repeat(2, minmax(0, 1fr));
               gap: clamp(2.5rem, 5vw, 4rem); }
  /* The divider hangs in the middle of the gutter rather than padding the
     second column, so the two columns stay identical — which matters now
     that each one opens on a fixed-ratio plate. */
  .people--ruled { position: relative; }
  .people--ruled::after {
    content: ""; position: absolute; top: 0; bottom: 0; left: 50%;
    width: 1px; background: var(--rule); pointer-events: none;
  }
  .field .people--ruled::after { background: var(--rule-light); }
}
/* Where a portrait goes. The partners' photographs have not been supplied, so
   the slot is marked with the same diagonal hatch the design output used —
   visibly a placeholder, not a missing image. Swap for an <img> on arrival. */
.plate {
  position: relative; display: block; width: 100%;
  aspect-ratio: 3 / 2; margin-bottom: clamp(1.125rem, 2.2vw, 1.5rem);
  border: 1px solid var(--rule);
  background: repeating-linear-gradient(135deg,
              #E3E0D6 0 8px, #EDEAE1 8px 16px);
}
/* The placeholder standing in for a portrait that has not arrived takes the
   portrait's shape, so a row with one missing photograph still lines up. */
.plate--portrait { aspect-ratio: 1 / 1; max-width: 16rem; }

.field .plate, .cta .plate {
  border-color: rgba(255, 255, 255, .18);
  background: repeating-linear-gradient(135deg,
              rgba(255, 255, 255, .07) 0 8px, rgba(255, 255, 255, .03) 8px 16px);
}
.plate__cap {
  position: absolute; left: .75rem; bottom: .625rem;
  font-family: var(--sans); font-size: .8125rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--slate-ink);
}
.field .plate__cap, .cta .plate__cap { color: rgba(255, 255, 255, .5); }

/* The interns sit under the founder in the same block, so they take his
   portrait's grade — but at a size that says they are the second thing you
   read there, not the first. */
.interns__label { display: block; margin-top: clamp(3rem, 6vw, 4.5rem);
                  border-top: 1px solid var(--rule-strong);
                  padding-top: clamp(.9rem, 1.8vw, 1.2rem);
                  margin-bottom: clamp(1.75rem, 3.5vw, 2.5rem); }
/* Framed, not floated. The founder's portrait melts into the page because it
   was shot on a backdrop light enough to clip out; nobody else's was — a
   rooftop, a studio grey, foliage, a sage wall — and pushed far enough to
   clip, the faces go with them. So every other portrait takes the same
   grayscale grade at a gentler setting and keeps its own edge, with the
   hairline the plates carry. They read as portraits in the slot the plates
   held, rather than as a failed version of the founder's.

   One square, two widths: partners a step larger than interns, which is the
   only thing separating them once the plates are gone. */
.portrait { margin: 0 0 clamp(1.125rem, 2.2vw, 1.5rem); max-width: 14rem;
            border: 1px solid var(--rule); }
.portrait--lg { max-width: 16rem; }
.portrait img { width: 100%; height: auto; display: block;
                filter: grayscale(1) brightness(1.04) contrast(1.08); }

/* The partner's own firm. Set like the standalone link it is, not like the
   prose above it. */
.person__site { margin-top: 1.125rem; }
.person__site a {
  font-family: var(--sans); font-size: .8125rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--navy);
  text-decoration: none; display: inline-block;
  padding-bottom: .4rem; border-bottom: 1px solid var(--brass);
}
.person__site a:hover { border-bottom-color: var(--ink); }
.field .person__site a, .cta .person__site a {
  color: var(--white); border-bottom-color: var(--brass-light);
}
.person__link { margin-top: 1.125rem; }

.person__name { font-family: var(--serif); font-size: clamp(1.2rem, 1.1rem + .5vw, 1.375rem);
                font-weight: 350; line-height: 1.15; letter-spacing: -.018em; }
.person__role { color: var(--slate-ink); margin-top: .5rem; }
.field .person__role, .cta .person__role { color: var(--slate-light); }
.person__bio { margin-top: 1.125rem; color: var(--ink-soft); max-width: 46ch;
               font-size: 1rem; line-height: 1.6; }
.field .person__bio { color: rgba(255, 255, 255, .8); }

.creds { display: grid; gap: 2rem; margin-top: clamp(2.25rem, 4.5vw, 3rem);
         border-top: 1px solid var(--rule-mid); padding-top: clamp(1.5rem, 3vw, 2rem); }
@media (min-width: 44rem) { .creds { grid-template-columns: repeat(2, minmax(0, 1fr));
                                     gap: 2.5rem; } }
.creds h4 { color: var(--slate-ink); margin-bottom: 1rem; }
.creds ul { display: grid; gap: .6rem; }
.creds li { font-size: 1rem; line-height: 1.5; color: var(--ink-soft); }
.field .creds { border-top-color: var(--rule-light); }
.field .creds h4 { color: var(--slate-light); }
.field .creds li { color: rgba(255, 255, 255, .8); }

/* --- 17b. Photographs of the work ---------------------------------------
   The site's photographs were, until now, water and studio portraits: texture
   and faces, nothing of the firm actually at work. These two are documentary,
   and they are graded like the portraits rather than left in colour. That is
   not only for consistency. Both frames were lit magenta and red for the
   stage, against green dresses — on Paper Stone and Lotus Navy that reads as a
   different website, and the colour pulls the eye to the backdrop instead of
   to the gesture, which is the whole reason the pictures are here. */

/* Two grades, because the two frames were exposed differently: the wide one
   was shot into a dark hall and needs the white point lifted a long way before
   it stops reading as a dark slab against Paper Stone. */
.band__img { filter: grayscale(1) brightness(1.18) contrast(.95); }
/* The second frame was shot closer and brighter, so it needs far less lifting
   than the one taken into the dark of the hall. */
.band--bright .band__img { filter: grayscale(1) brightness(1.04) contrast(1.02); }

/* The band runs the full width of the window, the only photograph besides the
   hero to do so, and unlike the hero it carries no scrim. It is the loudest
   instrument on the page and it is used once. */
.band { margin-block: clamp(3.5rem, 7vw, 6rem); }
/* Butted straight against the section below it. On Services the next section
   is navy, and the site's own rule is that where a cream ground meets a dark
   one there is no rule between them — the change of ground is the seam. A
   strip of bone between the photograph and the navy is that seam drawn twice. */
.band--flush-b { margin-bottom: 0; }
.band__fig { margin: 0; }
.band__img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 16 / 10; object-fit: cover; object-position: 50% 32%;
}
@media (min-width: 48rem) {
  /* A letterbox above phone width: at 2.4:1 it reads as a band across the
     page rather than as a billboard you have to scroll past. */
  .band__img { aspect-ratio: 2.4 / 1; max-height: 34rem; }
}
/* --- 17c. The full media list --------------------------------------------
   The archive at news.html. Cards carry the featured six; a dozen of them
   would be a wall of tinted plates, and a list like this is read by scanning
   down outlets and dates rather than by looking at pictures. So: hairlines, a
   year in the mono rail the ruled index uses, the whole row a link. */

.medialist { border-top: 1px solid var(--rule-mid); }
.medialist__row { border-bottom: 1px solid var(--rule); position: relative; }
.medialist__link {
  display: block; text-decoration: none; color: inherit;
  padding-block: clamp(1.1rem, 2.2vw, 1.5rem);
}
.medialist__link::before {
  /* The rule in the margin the ruled index uses to mark a row. */
  content: ""; position: absolute; inset: 0 auto 0 -1.15rem; width: 2px;
  background: var(--brass); opacity: 0;
  transition: opacity .45s var(--ease); pointer-events: none;
}
.medialist__link:hover::before, .medialist__link:focus-visible::before { opacity: 1; }

.medialist__year {
  font-family: var(--mono); font-size: .8125rem; letter-spacing: .14em;
  color: var(--brass-deep); font-variant-numeric: tabular-nums;
}
.medialist__outlet {
  display: block; font-family: var(--sans); font-size: .8125rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--slate-ink);
  line-height: 1.5;
}
.medialist__title {
  display: block; margin-top: .35rem;
  font-family: var(--serif); font-weight: 350;
  font-size: clamp(1.15rem, 1.05rem + .5vw, 1.3125rem);
  line-height: 1.24; letter-spacing: -.018em; text-wrap: balance;
}
.medialist__link:hover .medialist__title,
.medialist__link:focus-visible .medialist__title {
  text-decoration: underline; text-decoration-thickness: 1px;
  text-underline-offset: .18em; text-decoration-color: var(--brass);
}
.medialist__date {
  font-family: var(--mono); font-size: .8125rem; letter-spacing: .1em;
  color: var(--ink-quiet); font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* Phone: the year sits above the piece, the date under it. */
@media (max-width: 51.99rem) {
  .medialist__row { padding-block: clamp(1.1rem, 2.2vw, 1.5rem); }
  .medialist__link { padding-block: 0; }
  .medialist__year:not(:empty) { display: block; margin-bottom: .6rem; }
  .medialist__date { display: block; margin-top: .6rem; }
}
/* Wider: a year rail on the left, the date in a column on the right, so the
   run of time is readable down both edges. */
@media (min-width: 52rem) {
  .medialist__row {
    display: grid; grid-template-columns: 4.5rem minmax(0, 1fr) 10rem;
    gap: 0 1.75rem; align-items: baseline;
    padding-block: clamp(1.1rem, 2.2vw, 1.5rem);
  }
  .medialist__link { padding-block: 0; }
  .medialist__year { padding-top: .2em; }
  .medialist__date { text-align: right; }
}

.medialist__ask {
  margin-top: clamp(2.25rem, 4.5vw, 3rem);
  font-family: var(--serif); font-size: 1.0625rem; line-height: 1.6;
  color: var(--ink-soft); max-width: 48ch;
}

/* --- 18. In the news ----------------------------------------------------
   The curated press list, from media.json. Cards rather than a ruled list, so
   the section carries some weight next to the partners' portraits above it.

   Every card has a picture. When media.json names one it is used; otherwise
   the card gets a tinted plate with the outlet set across it and the mark
   behind, which means a piece can go up the minute it runs, without anyone
   hunting for a photograph that we would not have the rights to anyway. */

.news {
  display: grid; gap: clamp(1.75rem, 3.2vw, 2.5rem);
  margin-top: clamp(2rem, 4vw, 3rem);
}
@media (min-width: 40rem) { .news { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 62rem) { .news { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.news__link {
  display: flex; flex-direction: column; height: 100%;
  text-decoration: none; color: inherit;
}

/* --- the cover --- */
.news__cover {
  position: relative; display: block; overflow: hidden;
  aspect-ratio: 3 / 2;
  border: 1px solid var(--rule);
  margin-bottom: clamp(1rem, 2vw, 1.375rem);
}
.field .news__cover { border-color: rgba(255, 255, 255, .18); }
.news__shot {
  /* height:auto, or the width/height attributes on the <img> — there so the
     card does not reflow while the picture loads — win over aspect-ratio and
     the cover comes out 400px tall. */
  width: 100%; height: 100%; object-fit: cover; display: block;
}

.news__cover--plate { color: #fff; }

/* The outlet's own picture as the plate's ground. It goes under a navy wash
   rather than being shown plain: a row of six press images is six different
   colour schemes, and the wash puts them all on the house ground so the mark
   and the outlet's name stay legible over any of them. Grayscale first, for
   the same reason every other photograph here is. */
.news__cover--photo { color: #fff; background: var(--navy); }
.news__cover--photo .news__shot {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; filter: grayscale(1) brightness(.92) contrast(1.05);
}
.news__cover--photo::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(10, 65, 102, .52) 0%, rgba(10, 65, 102, .88) 78%),
    rgba(10, 65, 102, .34);
}
/* Above the wash. */
.news__cover--photo .news__watermark,
.news__cover--photo .news__stamp { z-index: 1; }
.news__cover--plate[data-tint="1"] { background: var(--navy); }
.news__cover--plate[data-tint="2"] { background: var(--ink); }
.news__cover--plate[data-tint="3"] { background: var(--slate-ink); }
/* One light plate in the set, so a row of cards is not a row of dark slabs.
   Lotus Navy on Warm Grey is 8.4:1. */
.news__cover--plate[data-tint="4"] { background: var(--warm); color: var(--navy); }

.news__watermark {
  position: absolute; right: -14%; bottom: -22%; width: 72%; height: auto;
  color: currentColor; opacity: .17; pointer-events: none;
}
.news__cover--plate[data-tint="4"] .news__watermark { opacity: .2; }
.news__stamp {
  position: absolute; z-index: 1; inset: auto 1.1rem 1rem 1.1rem;
  font-family: var(--serif); font-weight: 350;
  font-size: clamp(1.25rem, 1.05rem + .85vw, 1.625rem);
  line-height: 1.12; letter-spacing: -.02em; text-wrap: balance;
  max-width: 12ch;
  /* A plate is a fixed 3:2, and some outlets are called things like "U.S.
     House Committee on Oversight & Government Reform". Three lines, then it
     stops — the card names the outlet in full underneath either way. */
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  overflow: hidden;
}
.news__stamp--long { font-size: clamp(1.0625rem, .95rem + .5vw, 1.25rem); max-width: 15ch; }

/* --- the card --- */
.news__meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem .75rem; }
.news__date {
  font-family: var(--mono); font-size: .8125rem; font-weight: 400;
  letter-spacing: .14em; text-transform: uppercase; color: var(--brass-deep);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.field .news__date { color: var(--brass-light); }
.news__meta::before {
  /* The brass lozenge the ribbon uses, as the join between date and outlet. */
  content: ""; width: .3125rem; height: .3125rem; flex: none; order: 1;
  background: var(--brass); transform: rotate(45deg); opacity: .85;
  align-self: center;
}
.field .news__meta::before { background: var(--brass-light); }
.news__outlet {
  order: 2; font-family: var(--sans); font-size: .8125rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--slate-ink);
  line-height: 1.5;
}
.field .news__outlet { color: var(--slate-light); }

.news__title {
  display: block; margin-top: .7rem;
  font-family: var(--serif); font-weight: 350;
  font-size: clamp(1.15rem, 1.05rem + .5vw, 1.3125rem);
  line-height: 1.22; letter-spacing: -.018em; text-wrap: balance;
}
.news__go {
  display: inline-flex; align-items: center; gap: .5rem;
  margin-top: auto; padding-top: clamp(1rem, 2vw, 1.375rem);
  font-family: var(--sans); font-size: .8125rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--slate-ink);
}
.field .news__go { color: #C3D3DE; }
.news__arrow { width: .8125rem; height: .8125rem; flex: none;
               transition: transform .3s var(--ease); }

/* Hover and keyboard focus say the same thing: the rule under the headline,
   the arrow moving on, the cover coming up a little. */
.news__link:hover .news__title,
.news__link:focus-visible .news__title {
  text-decoration: underline; text-decoration-thickness: 1px;
  text-underline-offset: .18em; text-decoration-color: var(--brass);
}
.news__link:hover .news__go, .news__link:focus-visible .news__go { color: var(--brass-deep); }
.news__link:hover .news__arrow, .news__link:focus-visible .news__arrow {
  transform: translateX(.25rem);
}
.news__link:hover .news__cover, .news__link:focus-visible .news__cover {
  border-color: var(--rule-strong);
}
.news__shot, .news__watermark, .news__stamp { transition: transform .6s var(--ease); }
.news__link:hover .news__shot, .news__link:hover .news__watermark { transform: scale(1.03); }
@media (prefers-reduced-motion: reduce) {
  .news__arrow, .news__shot, .news__watermark, .news__stamp { transition: none; }
  .news__link:hover .news__arrow, .news__link:focus-visible .news__arrow,
  .news__link:hover .news__shot, .news__link:hover .news__watermark { transform: none; }
}

/* --- 19. Contact -------------------------------------------------------- */

.contact-grid { display: grid; gap: clamp(2.5rem, 5vw, 5rem); }
@media (min-width: 56rem) {
  .contact-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 15rem); }
}

/* Inputs are hairlines on the ground, like every other rule on the site —
   not browser boxes. */
.form { display: grid; gap: clamp(1.1rem, 1.8vw, 1.375rem);
        margin-top: clamp(2rem, 4vw, 2.75rem); }
.form__row { display: grid; gap: .3rem; }
.form label { color: var(--slate-ink); }
.form input, .form textarea {
  font-family: var(--serif); font-size: 1.0625rem; color: var(--ink);
  background: transparent; border: 0; border-bottom: 1px solid var(--slate-ink);
  border-radius: 0; padding: .5rem 0; width: 100%;
  transition: border-color .3s var(--ease);
}
.form textarea { min-height: 4.5rem; resize: vertical; line-height: 1.55; }
.form input:focus, .form textarea:focus {
  outline: none; border-bottom-color: var(--navy);
  box-shadow: 0 1px 0 0 var(--navy);
}
.form .btn { justify-self: start; margin-top: .5rem; }
/* Required fields carry an asterisk. It is hidden from screen readers, which
   already announce "required" from the input's own attribute — otherwise they
   would read it out as "star". Brass Deep keeps it 5.14:1 on Paper Stone. */
.form__req { color: var(--brass-deep); margin-left: .2em; font-weight: 700; }
/* The key to the asterisk, set like the field labels beneath it. */
.form__legend { font-family: var(--sans); font-size: .8125rem; font-weight: 700;
                letter-spacing: .16em; text-transform: uppercase; color: var(--slate-ink); }
.form__legend .form__req { margin-left: 0; margin-right: .15em; }
/* A note under a field, tied to it by aria-describedby so a screen reader
   reads it as part of the field rather than as stray text after it. Set in
   Newsreader, not the label's caps: it is a sentence, not a name. */
.form__hint { margin-top: .35rem; font-size: 1rem; line-height: 1.5;
              color: var(--ink-soft); }
/* The bait field. Off-screen rather than display:none, because some scripted
   submitters skip anything a browser would not render at all. */
.form__bait { position: absolute; left: -9999px; width: 1px; height: 1px;
              opacity: 0; pointer-events: none; }

/* What replaces the form once a note has been sent, and the error that keeps
   the form in place when it has not. */
.form__done { margin-top: clamp(2rem, 4vw, 2.75rem); max-width: 34ch; }
.form__done-body { margin-top: 1rem; font-size: 1rem; line-height: 1.6;
                   color: var(--ink-soft); }
.form__error { font-size: 1rem; line-height: 1.6; color: var(--ink);
               border-left: 2px solid var(--brass-deep); padding-left: .875rem; }
.form__error a { border-bottom: 1px solid var(--brass-deep); text-decoration: none; }
.form__error a:hover { border-bottom-color: var(--ink); }
.form button[aria-busy="true"] { opacity: .7; }

.details { margin: 0; }
.detail { border-top: 1px solid var(--rule-mid); padding-top: 1rem; margin-top: 1.5rem; }
.detail:first-child { margin-top: 0; }
.detail dt { color: var(--slate-ink); margin-bottom: .5rem; }
.detail dd { margin: 0; font-size: 1rem; line-height: 1.6; }
.detail dd a { text-decoration: none; border-bottom: 1px solid var(--rule-strong); }
.detail dd a:hover { border-bottom-color: var(--navy); }

/* --- 20. Closing band ---------------------------------------------------- */

.cta { background: var(--navy); color: var(--white); position: relative; overflow: clip;
       padding-block: clamp(4rem, 7.5vw, 6.5rem); }
.cta h2 { color: var(--white); }
.cta p { color: rgba(255, 255, 255, .86); }
.cta__grid { display: grid; gap: clamp(2rem, 4vw, 3rem); }
.cta__head { margin-top: 1.125rem; max-width: 18ch;
             font-size: clamp(1.75rem, 1.2rem + 2.2vw, 2.875rem); }
.cta__act { display: grid; gap: 1.75rem; align-content: start; }
.cta__act p { max-width: 38ch; font-size: 1rem; line-height: 1.6; }
@media (min-width: 60rem) {
  .cta__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
               gap: clamp(2.5rem, 5vw, 4rem); align-items: start; }
}

/* --- 21. Footer ---------------------------------------------------------- */

.footer { background: var(--navy-deep); color: rgba(255, 255, 255, .72);
          position: relative; overflow: clip; }
.footer a { color: rgba(255, 255, 255, .72); text-decoration: none;
            transition: color .3s var(--ease); }
.footer a:hover { color: var(--white); }
.footer__inner { display: grid; gap: clamp(2.25rem, 4.5vw, 4rem);
                 padding-block: clamp(3rem, 6vw, 4.5rem); position: relative; z-index: 1; }
@media (min-width: 52rem) {
  .footer__inner { grid-template-columns: minmax(0, 1.5fr) repeat(2, minmax(0, 1fr)); }
}
.footer .brand { color: var(--white); }
.footer .brand__name small { color: var(--slate-light); }
.footer__tag { margin-top: 1.25rem; max-width: 28ch; font-size: 1rem;
               line-height: 1.6; color: rgba(255, 255, 255, .6); }
/* Deliberately quieter than a section eyebrow — this is furniture. */
.footer h4 { color: rgba(255, 255, 255, .66); margin-bottom: 1rem; }
.footer ul { display: grid; gap: .625rem; font-size: 1rem; }
.footer__base { font-family: var(--mono); font-size: .8125rem; letter-spacing: .12em;
                text-transform: uppercase;
                border-top: 1px solid rgba(255, 255, 255, .18); padding-block: 1.5rem;
                display: flex; flex-wrap: wrap; gap: .5rem 1.5rem;
                align-items: center; justify-content: space-between;
                color: rgba(255, 255, 255, .66); position: relative; z-index: 1; }

/* --- 22. Reveal ---------------------------------------------------------- */

/* Only hide content when JS is running — a failed script must never leave the
   page blank. The .js class is set inline in <head>. */
.js [data-reveal] { opacity: 0; transform: translateY(14px);
                    transition: opacity .75s var(--ease), transform .75s var(--ease);
                    transition-delay: var(--delay, 0ms); }
.js [data-reveal].is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { opacity: 1; transform: none; transition: none; }
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}
