/* ============================================================================
   TYPEFACES
   ----------------------------------------------------------------------------
   Self-hosted, so the site looks the same on Windows and Android as it does on
   a Mac. The three faces were picked against the macOS originals the design was
   built with, and each is the closest freely licensed match:

     Futura         -> Jost              a geometric revival of Futura
     DIN Condensed  -> Barlow Condensed  closest in width and weight; Oswald ran
                                         noticeably wider and more gothic
     Charter        -> Charis SIL        drawn from Bitstream Charter itself

   The macOS originals stay in each stack behind the web font, so a Mac with a
   slow connection falls back to something nearly identical rather than to a
   default. font-display: swap means text is readable before the fonts arrive.
   ========================================================================== */

@font-face {
  font-family: "Jost"; src: url("assets/fonts/jost-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Jost"; src: url("assets/fonts/jost-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Barlow Condensed"; src: url("assets/fonts/barlowcond-600.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Charis SIL"; src: url("assets/fonts/charis-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Charis SIL"; src: url("assets/fonts/charis-700.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}

/* ============================================================================
   CADA — visual system
   Palette is derived entirely from the logo. The ground #070A51 was sampled
   directly from the mark. There is no foreign accent colour: every value below
   is either that indigo, a tint or shade of it, or white. A two-colour system
   held strictly reads as more considered than a wider one held loosely.
   ========================================================================== */

:root {
  /* Colour */
  --ink:        #070A51;   /* sampled from the logo */
  --ink-deep:   #03051F;
  --ink-lift:   #0D1266;
  --ink-line:   rgba(255, 255, 255, 0.13);
  --ink-soft:   rgba(255, 255, 255, 0.58);
  --white:      #FFFFFF;
  --tint:       #9BA6E6;   /* pale indigo, eyebrows and data labels on navy */
  --paper:      #EDEFF6;   /* cool near-white, never cream */
  --paper-2:    #E1E5F1;
  --paper-line: rgba(7, 10, 81, 0.13);
  --on-paper:   #141943;
  --on-paper-2: #4C5379;

  /* Type */
  /* Three voices, each with one job.
     Display  Futura, the face on the Apollo 11 lunar plaque. Geometric, spare,
              unmistakably aerospace, and not a default anyone reaches for.
     Label    DIN Condensed. DIN is the German industrial standard face: machine
              dataplates, technical drawings, road signage. It replaces the
              tracked-out monospace that every generated site uses for labels.
     Body     Charter, Matthew Carter's screen serif. A serif body signals that
              this organisation writes analysis, and it stops the page reading
              as another sans-serif startup template.
     Web fallbacks for each are free faces (Jost, Oswald, Bitstream Charter) and
     should be self-hosted if the site is ever deployed off a Mac. */
  --display: "Jost", "Futura", "Avenir Next", system-ui, sans-serif;
  --label: "Barlow Condensed", "DIN Condensed", "Arial Narrow", system-ui, sans-serif;
  --body: "Charis SIL", "Charter", "Bitstream Charter", Georgia, serif;

  /* Rhythm */
  --pad: clamp(1.25rem, 3.4vw, 4.5rem);
  --max: 1680px;
  --nav-h: 68px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* The page background belongs on the root element, not only on body. On a short
   page such as Contact, body stops at the end of the content and the browser
   paints the rest of the viewport with the root background: that was the pale
   strip showing beneath the footer. Matching it to the footer removes it. */
html { background: var(--ink-deep); }

body {
  margin: 0;
  background: var(--paper);
  color: var(--on-paper);
  font-family: var(--body);
  font-size: 17.5px;
  line-height: 1.66;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; font-weight: 500; letter-spacing: -0.01em; }
p { margin: 0 0 1em; }
a { color: inherit; }

.wrap { max-width: var(--max); margin: 0 auto; padding-inline: var(--pad); }

/* Eyebrow: the utility voice. Mono, uppercase, widely tracked. Used for
   labels and data captions only, never for prose. */
.eyebrow {
  font-family: var(--label);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  color: var(--tint);
  margin: 0 0 1.4rem;
}
.eyebrow.on-paper { color: var(--on-paper-2); }

/* ---------------------------------------------------------------- NAV ----- */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  height: var(--nav-h);
  display: flex; align-items: center;
  background: rgba(7, 10, 81, 0.82);
  backdrop-filter: saturate(180%) blur(18px);
  -webkit-backdrop-filter: saturate(180%) blur(18px);
  border-bottom: 1px solid var(--ink-line);
}
.nav .wrap { display: flex; align-items: center; gap: 1.5rem; width: 100%; }

.brand { display: flex; align-items: center; gap: 0.7rem; text-decoration: none; margin-right: auto; }
.brand img { width: 38px; height: auto; display: block; }
.brand span {
  font-family: var(--display); color: var(--white);
  font-size: 17px; letter-spacing: 0.14em; text-transform: uppercase;
}

.nav-links { display: flex; gap: 0.35rem; }
.nav-links a {
  font-family: var(--label); font-weight: 600;
  font-size: 13.5px; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--ink-soft); text-decoration: none;
  padding: 0.55rem 0.85rem; border-radius: 4px;
  transition: color 0.18s ease, background 0.18s ease;
}
.nav-links a:hover { color: var(--white); background: rgba(255,255,255,0.07); }
.nav-links a[aria-current="page"] { color: var(--white); background: rgba(255,255,255,0.11); }

/* --------------------------------------------------------------- HERO ----- */
.hero {
  position: relative;
  min-height: 100svh;
  display: grid; place-items: center;
  background: var(--ink);
  overflow: hidden;
  text-align: center;
}
/* The signature element. A slow scan passes down a fine coordinate field,
   drawn from the LiDAR and ultrasonic survey work the team actually does. */
#field { position: absolute; inset: 0; width: 100%; height: 100%; }

.hero-inner { position: relative; z-index: 2; padding: calc(var(--nav-h) + 2rem) var(--pad) 4.5rem; }

/* The mark is a cut-out on transparency rather than the square tile it ships
   in, so it sits on the ground directly instead of inside a visible panel, and
   fills its footprint instead of spending most of it on the tile's padding. */
.hero-mark {
  width: clamp(128px, 15vw, 186px); height: auto;
  display: block; margin: 0 auto 2.4rem;
}

.hero h1 {
  font-family: var(--display);
  color: var(--white);
  text-transform: uppercase;
  font-size: clamp(1.9rem, 5.6vw, 5.3rem);
  line-height: 1.06;
  letter-spacing: 0.02em;
  margin: 0 0 1.8rem;
}
.hero h1 .amp { color: var(--tint); }

.hero-line {
  max-width: 50ch; margin: 0 auto 3.4rem;
  color: var(--ink-soft); font-size: clamp(1.05rem, 1.5vw, 1.32rem); line-height: 1.55;
}

/* The three questions, set as a rule-separated triptych. */
.triptych {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 1px; background: var(--ink-line);
  border-block: 1px solid var(--ink-line);
  max-width: 1040px; margin: 0 auto;
}
.triptych div { background: var(--ink); padding: 1.7rem 1.2rem; }
.triptych dt {
  font-family: var(--label); font-weight: 600; font-size: 13px; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--tint); margin-bottom: 0.7rem;
}
.triptych dd {
  margin: 0; font-family: var(--display); color: var(--white);
  font-size: clamp(0.98rem, 1.4vw, 1.22rem); line-height: 1.3;
}

.scroll-cue {
  position: absolute; bottom: 2rem; left: 50%; translate: -50% 0; z-index: 2;
  font-family: var(--label); font-weight: 600; font-size: 13px; letter-spacing: 0.05em;
  text-transform: uppercase; color: rgba(255,255,255,0.32);
}

/* ------------------------------------------------------------ SECTIONS ---- */
.band { padding: clamp(2.75rem, 5.2vw, 4.75rem) 0; }
.band-paper { background: var(--paper); color: var(--on-paper); }
.band-ink   { background: var(--ink);   color: var(--white); }
.band-deep  { background: var(--ink-deep); color: var(--white); }

.band h2, .shead h2 {
  font-family: var(--display); text-transform: uppercase;
  font-size: clamp(1.6rem, 3.4vw, 3.1rem); letter-spacing: 0.015em;
  line-height: 1.12; margin: 0 0 0.9rem; max-width: 20ch;
}
.lede { max-width: 64ch; font-size: 1.13rem; color: var(--on-paper-2); }
.band-ink .lede, .band-deep .lede { color: var(--ink-soft); }

/* Practice cards */
.practices { display: grid; gap: 1px; background: var(--paper-line); margin-top: 2.4rem; border-block: 1px solid var(--paper-line); }
@media (min-width: 860px) { .practices { grid-template-columns: repeat(3, 1fr); } }
.practice { background: var(--paper); padding: 1.9rem 1.7rem 2rem; }
.practice-q {
  font-family: var(--display); text-transform: uppercase;
  font-size: 1.18rem; letter-spacing: 0.035em; line-height: 1.25;
  margin: 0 0 1rem; color: var(--on-paper);
}
.practice-lead { color: var(--on-paper-2); font-size: 0.97rem; margin-bottom: 1.6rem; }
.practice ul { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--paper-line); }
.practice li {
  font-size: 0.9rem; padding: 0.7rem 0; border-bottom: 1px solid var(--paper-line);
  color: var(--on-paper-2);
}

/* Proof strip */
.proof { display: grid; gap: 1px; background: var(--ink-line); border-block: 1px solid var(--ink-line); margin-top: 1.8rem; }
@media (min-width: 700px) { .proof { grid-template-columns: repeat(4, 1fr); } }
.proof div { background: var(--ink-deep); padding: 1.5rem 1.3rem; }
.proof .v {
  font-family: var(--display); color: var(--white);
  font-size: clamp(1.8rem, 3.6vw, 3.2rem); letter-spacing: 0.01em; line-height: 1;
  margin-bottom: 0.7rem;
}
.proof .l { font-family: var(--label); font-weight: 600; font-size: 13px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--tint); line-height: 1.5; }

/* Engagement.
   One grid per entry: who the client is on the left, what the practices did on
   the right. Previously the summary wrapped at about 60 characters directly
   above rows running the full page at about 150, which is two different
   measures in one block and reads as untidy however the words are written. */
.engagement {
  border-top: 1px solid var(--paper-line);
  padding-top: 2rem; margin-top: 2.4rem;
  display: grid; gap: 1.5rem 4rem;
}
@media (min-width: 900px) {
  .engagement { grid-template-columns: minmax(250px, 0.85fr) minmax(0, 1.5fr); }
}
.eg-id h3 {
  font-family: var(--display); text-transform: uppercase;
  letter-spacing: 0.035em; font-size: 1.35rem; line-height: 1.15; margin: 0;
}
/* Every logo file is composited onto the same 200 by 58 canvas at 3x, sized by
   optical area, so one rule sizes all of them and their baselines line up down
   the page. Nothing here crops or recolours a client's mark. */
.eg-logo {
  display: block; width: 200px; max-width: 100%; height: auto;
  margin-bottom: 1rem;
}
.eg-meta { margin: 0.5rem 0 0; font-size: 0.93rem; color: var(--on-paper-2); }
.eg-meta:empty { display: none; }
.eg-tags { display: flex; flex-wrap: wrap; gap: 0.45rem; margin: 0.9rem 0 0; }
.eg-summary { margin: 1rem 0 0; font-size: 1rem; color: var(--on-paper-2); }

/* In a column this narrow a 150px label gutter wastes most of the width, so the
   practice name sits above its paragraph instead of beside it. */
.eg-work .workrow { grid-template-columns: 1fr; gap: 0.4rem; padding: 0 0 1.2rem; border-top: 0; }
.eg-work .workrow + .workrow { padding-top: 1.2rem; border-top: 1px solid var(--paper-line); }
.eg-work .workrow .k { padding-top: 0; }
.eg-work .workrow .d { max-width: 68ch; }
.chip {
  font-family: var(--label); font-weight: 600; font-size: 13px; letter-spacing: 0.05em; text-transform: uppercase;
  border: 1px solid var(--paper-line); border-radius: 999px; padding: 0.25rem 0.7rem; color: var(--on-paper-2);
}
.workrow { display: grid; gap: 0.5rem 2.5rem; padding: 1.1rem 0; border-top: 1px solid var(--paper-line); }
@media (min-width: 820px) { .workrow { grid-template-columns: 150px 1fr; } }
.workrow .k { font-family: var(--label); font-weight: 600; font-size: 13px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--on-paper-2); padding-top: 0.35rem; }
.workrow .d { margin: 0; font-size: 0.98rem; }

/* Team */
.team-group { margin-top: 2.6rem; }
.team-group > .eyebrow { padding-bottom: 1rem; border-bottom: 1px solid var(--paper-line); margin-bottom: 0; }
.member { display: grid; gap: 0.6rem 2.5rem; padding: 1.5rem 0; border-bottom: 1px solid var(--paper-line); }
@media (min-width: 820px) { .member { grid-template-columns: 260px 1fr; } }
.member h3 { font-family: var(--display); text-transform: uppercase; letter-spacing: 0.045em; font-size: 1.1rem; line-height: 1.3; }
.member .meta { font-family: var(--label); font-weight: 600; font-size: 13px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--on-paper-2); margin-top: 0.5rem; }
.member .bio { margin: 0; font-size: 0.98rem; color: var(--on-paper-2); }

/* Steps */
.steps { margin-top: 2.2rem; border-top: 1px solid var(--ink-line); }
.step { display: grid; gap: 0.5rem 2.5rem; padding: 1.15rem 0; border-bottom: 1px solid var(--ink-line); }
@media (min-width: 820px) { .step { grid-template-columns: 200px 1fr; } }
.step .k { font-family: var(--display); text-transform: uppercase; letter-spacing: 0.09em; font-size: 1rem; color: var(--white); }
.step .d { margin: 0; color: var(--ink-soft); font-size: 0.98rem; }

/* Lists on ink */
.plainlist { list-style: none; margin: 2rem 0 0; padding: 0; border-top: 1px solid var(--paper-line); max-width: 60ch; }
.plainlist li { padding: 0.85rem 0; border-bottom: 1px solid var(--paper-line); color: var(--on-paper-2); font-size: 0.98rem; }

/* Placeholder marker: deliberately visible */
.todo {
  font-family: var(--label); font-weight: 600; font-size: 0.82em; letter-spacing: 0.06em;
  background: rgba(7,10,81,0.09); border: 1px dashed var(--paper-line);
  border-radius: 3px; padding: 0.1em 0.45em; color: var(--on-paper-2);
}
.band-ink .todo, .band-deep .todo, .hero .todo {
  background: rgba(255,255,255,0.08); border-color: var(--ink-line); color: var(--tint);
}

/* Footer */
.foot { background: var(--ink-deep); color: var(--ink-soft); padding: 2.2rem 0; border-top: 1px solid var(--ink-line); }
.foot .wrap { display: flex; flex-wrap: wrap; gap: 1.5rem; justify-content: space-between; align-items: center; }
.foot .eyebrow { margin: 0; }

/* Page routing: only the active page is shown */
.page { display: none; }
.page.is-active { display: block; }
.page:not(#page-home) { padding-top: var(--nav-h); }

@media (max-width: 720px) {
  .nav-links a { padding: 0.5rem 0.5rem; font-size: 10px; letter-spacing: 0.09em; }
  .brand span { display: none; }
  .triptych { grid-template-columns: 1fr; }
}

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

/* ============================================================================
   TEAM ROSTER AND MEMBER DIALOG
   The photographs arrive from ten different sources at ten different qualities.
   Rather than pretend otherwise, every portrait is held in a navy duotone so
   the grid reads as one set, and resolves to full colour on hover. That is the
   same idea as the cover: the structure is there, the instrument reveals it.
   ========================================================================== */

.team-head {
  display: flex; align-items: baseline; gap: 1.2rem;
  padding-bottom: 1rem; border-bottom: 1px solid var(--paper-line);
}
.team-head .eyebrow { margin: 0; }
.team-q { margin: 0; margin-right: auto; font-size: 0.95rem; color: var(--on-paper-2); }
.team-n { margin: 0; font-family: var(--label); font-weight: 600; font-size: 13px; color: var(--on-paper-2); }

/* Hairlines are drawn on the cards themselves rather than as a gap over a
   coloured background. With a grid background, a row that is not full renders
   its empty cells as visible grey panels. */
.roster {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 620px)  { .roster { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 900px)  { .roster { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 1360px) { .roster { grid-template-columns: repeat(5, 1fr); } }

.pcard {
  appearance: none; border: 0; cursor: pointer; text-align: left;
  background: var(--paper); padding: 1.15rem 1.15rem 1.4rem;
  font: inherit; color: inherit;
  /* A button centres its content block vertically by default, so a card whose
     name wraps to two lines pushes its photograph down out of line with the
     rest of the row. Flex-column pins everything to the top. */
  display: flex; flex-direction: column; align-items: stretch;
  border-right: 1px solid var(--paper-line);
  border-bottom: 1px solid var(--paper-line);
  transition: background 0.22s ease;
}
.pcard:hover { background: var(--paper-2); }

.pcard-frame {
  display: block; position: relative; aspect-ratio: 1; overflow: hidden;
  background: var(--ink); margin-bottom: 0.95rem;
  /* isolate: keeps the blend below contained to this frame. Without it the
     overlay composites against the page instead of the photograph. */
  isolation: isolate;
  /* The blend preserves luminance, so a headshot cut out on white stays white
     while the rest of the grid reads dark. This levels them. The filter sits on
     the frame, not the image, so it does not break the blend underneath it. */
  filter: contrast(1.07) brightness(0.86);
  transition: filter 0.55s ease;
}
.pcard:hover .pcard-frame,
.pcard:focus-visible .pcard-frame { filter: none; }
/* No filter on the image itself. A filter promotes it to its own stacking
   context, and the overlay then blends with the frame's flat background rather
   than with the photograph, which renders every portrait as a solid block. */
.pcard-frame img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transform: scale(1.01);
  transition: transform 0.55s ease;
}
/* The navy wash. mix-blend-mode: color keeps the luminance of the photograph
   and replaces its hue with the brand indigo. */
.pcard-frame::after {
  content: ""; position: absolute; inset: 0;
  background: var(--ink); mix-blend-mode: color; opacity: 1;
  transition: opacity 0.55s ease;
}
.pcard:hover .pcard-frame img,
.pcard:focus-visible .pcard-frame img { transform: scale(1.045); }
.pcard:hover .pcard-frame::after,
.pcard:focus-visible .pcard-frame::after { opacity: 0; }

.pcard-name {
  display: block; font-family: var(--display); text-transform: uppercase;
  letter-spacing: 0.05em; font-size: 0.93rem; line-height: 1.25; color: var(--on-paper);
}
.pcard-meta {
  display: block; margin-top: 0.4rem;
  font-family: var(--label); font-weight: 600; font-size: 12.5px; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--on-paper-2);
}

/* --- Dialog --------------------------------------------------------------- */

/* An author `display` rule beats the browser's own [hidden] rule, so the
   dialog must be hidden explicitly. Without this it sits invisible over the
   whole page and swallows every click. */
.modal { position: fixed; inset: 0; z-index: 100; display: none; place-items: center; padding: var(--pad); }
.modal:not([hidden]) { display: grid; }
.modal-scrim {
  position: absolute; inset: 0; background: rgba(3, 5, 31, 0.72);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  opacity: 0; transition: opacity 0.22s ease;
}
.modal.is-open .modal-scrim { opacity: 1; }

.modal-card {
  position: relative; z-index: 1;
  width: min(900px, 100%); max-height: 86vh; overflow-y: auto;
  background: var(--ink); color: var(--white);
  border: 1px solid var(--ink-line);
  box-shadow: 0 50px 120px -40px rgba(0, 0, 0, 0.9);
  opacity: 0; transform: translateY(14px) scale(0.985);
  transition: opacity 0.24s ease, transform 0.24s cubic-bezier(.2,.7,.3,1);
}
.modal.is-open .modal-card { opacity: 1; transform: none; }

.modal-close {
  position: absolute; top: 0.9rem; right: 0.9rem; z-index: 2;
  appearance: none; cursor: pointer;
  background: rgba(255,255,255,0.09); border: 1px solid var(--ink-line); color: var(--white);
  font-family: var(--label); font-weight: 600; font-size: 13px; letter-spacing: 0.05em; text-transform: uppercase;
  padding: 0.45rem 0.8rem; border-radius: 3px;
  transition: background 0.18s ease;
}
.modal-close:hover { background: rgba(255,255,255,0.18); }

.modal-body { display: grid; }
@media (min-width: 700px) { .modal-body { grid-template-columns: 246px 1fr; } }

.modal-portrait { background: var(--ink-deep); }
.modal-portrait img { width: 100%; height: 100%; max-height: 320px; object-fit: cover; display: block; }
@media (min-width: 700px) { .modal-portrait img { max-height: none; } }

.modal-text { padding: 2.2rem 2.3rem 2.4rem; }
.modal-text h3 {
  font-family: var(--display); text-transform: uppercase; letter-spacing: 0.045em;
  font-size: clamp(1.25rem, 2.6vw, 1.7rem); line-height: 1.16; color: var(--white);
}
.modal-meta {
  font-family: var(--label); font-weight: 600; font-size: 13px; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--tint); margin: 0.7rem 0 1.6rem;
}
.modal-why {
  margin: 0 0 1.6rem; padding-left: 1.1rem;
  border-left: 2px solid var(--tint);
  font-family: var(--display); font-size: 1.05rem; line-height: 1.45; color: var(--white);
}
.modal-bio { margin: 0; color: var(--ink-soft); font-size: 0.96rem; }

@media (prefers-reduced-motion: reduce) {
  .pcard-frame img, .pcard-frame::after, .modal-card, .modal-scrim { transition: none; }
}

.chip-mark { border-color: var(--on-paper); color: var(--on-paper); }

/* ============================================================================
   CONTACT FORM
   Hairline underlines rather than boxed inputs, so the form belongs to the same
   rule system as the tables and grids elsewhere on the site.
   ========================================================================== */

.cform { margin-top: 2.2rem; max-width: 780px; }

.cgrid { display: grid; gap: 0 2.5rem; }
@media (min-width: 660px) { .cgrid { grid-template-columns: 1fr 1fr; } }

.cfield { display: block; margin-bottom: 1.5rem; }
.cfield > span {
  display: block; margin-bottom: 0.6rem;
  font-family: var(--label); font-weight: 600;
  font-size: 13px; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--tint);
}
.cfield input,
.cfield textarea {
  width: 100%; display: block;
  background: transparent; color: var(--white);
  border: 0; border-bottom: 1px solid var(--ink-line);
  padding: 0.55rem 0; font-family: var(--body); font-size: 1.02rem; line-height: 1.5;
  transition: border-color 0.2s ease, background 0.2s ease;
}
.cfield textarea { resize: vertical; min-height: 7.5rem; }
.cfield input:hover,
.cfield textarea:hover { border-bottom-color: rgba(255,255,255,0.3); }
.cfield input:focus,
.cfield textarea:focus {
  outline: none; border-bottom-color: var(--tint);
  background: rgba(255,255,255,0.04);
}

.cerror {
  margin: 0 0 1.5rem; padding: 0.7rem 0.9rem;
  border: 1px solid var(--tint); border-left-width: 3px;
  color: var(--white); font-size: 0.95rem;
  background: rgba(255,255,255,0.05);
}

.crow { display: flex; flex-wrap: wrap; gap: 1.2rem 1.8rem; align-items: center; }

.cbtn {
  appearance: none; cursor: pointer;
  background: var(--white); color: var(--ink); border: 1px solid var(--white);
  font-family: var(--label); font-weight: 600;
  font-size: 15px; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 0.75rem 1.7rem;
  transition: background 0.18s ease, color 0.18s ease;
}
.cbtn:hover { background: transparent; color: var(--white); }

.cnote { margin: 0; font-size: 0.92rem; color: var(--ink-soft); max-width: 42ch; }
.cnote a, .foot a { color: var(--tint); }

/* Autofill on WebKit repaints the field white. Force it back to the ground. */
.cfield input:-webkit-autofill,
.cfield textarea:-webkit-autofill {
  -webkit-text-fill-color: var(--white);
  -webkit-box-shadow: 0 0 0 1000px var(--ink) inset;
}

/* Honeypot. Off-screen rather than display:none, and out of the tab order via
   tabindex, so a person can neither see it nor reach it while a crawler that
   fills every field still trips it. */
.hp {
  position: absolute !important;
  left: -9999px; top: auto;
  width: 1px; height: 1px; overflow: hidden;
  opacity: 0; pointer-events: none;
}

/* Field-level validation. The palette has no red in it, so an invalid field is
   marked the way the rest of the site marks emphasis: the underline thickens to
   the pale indigo and a message appears beneath it. The text does the work. */
/* display must be declared only on the :not([hidden]) selector. An author
   display rule outranks the browser's own [hidden] rule, which would leave
   every field's error marker on screen with no error to report. */
.cfield-error { display: none; }
.cfield-error:not([hidden]) {
  display: block; margin-top: 0.55rem;
  font-style: normal; font-size: 0.9rem; line-height: 1.45;
  color: var(--tint);
}
.cfield-error::before { content: "\2192\00a0"; }

.cfield input.is-invalid,
.cfield textarea.is-invalid {
  border-bottom-color: var(--tint);
  border-bottom-width: 2px;
}

.cerror-detail { display: block; margin-top: 0.5rem; color: var(--ink-soft); font-size: 0.88rem; }

/* Success. Replaces the form outright. */
.csuccess {
  margin-top: 3.2rem; max-width: 780px;
  padding: 1.8rem 1.9rem;
  border: 1px solid var(--ink-line); border-left: 3px solid var(--tint);
  background: rgba(255, 255, 255, 0.045);
}
.csuccess-head {
  margin: 0 0 0.6rem; color: var(--white);
  font-family: var(--label); font-weight: 600;
  font-size: 17px; letter-spacing: 0.05em; text-transform: uppercase;
}
.csuccess-body { margin: 0; color: var(--ink-soft); font-size: 1rem; }

.cbtn[disabled] { opacity: 0.55; cursor: default; }
.cbtn[disabled]:hover { background: var(--white); color: var(--ink); }

/* ============================================================================
   SECTION HEADERS, CLIENT ROW, CALL TO ACTION, MOBILE MENU, REVEAL
   ========================================================================== */

/* Heading left, lede right. A short paragraph under a heading leaves a column
   of dead page beside it and makes every section taller than it needs to be. */
.shead { display: grid; gap: 0.9rem 3.5rem; align-items: start; margin-bottom: 0.5rem; }
@media (min-width: 900px) {
  .shead { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: 0 4.5rem; }
  .shead-r { padding-top: 0.45rem; }
}
.shead-solo { grid-template-columns: 1fr; }
.shead .eyebrow { margin-bottom: 0.85rem; }
.shead h2 { margin-bottom: 0; }
.shead .lede { margin: 0; }

/* The clients, on the same dark band as the numbers, so the band carries two
   kinds of proof instead of ending in empty ground. */
.clientrow {
  margin-top: 2.2rem; padding-top: 1.6rem;
  border-top: 1px solid var(--ink-line);
  display: grid; gap: 0.9rem 2.5rem; align-items: baseline;
}
@media (min-width: 860px) { .clientrow { grid-template-columns: auto 1fr auto; } }
.clientrow .eyebrow { margin: 0; white-space: nowrap; }
.clientrow ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 0.6rem 2.2rem;
}
.clientrow li {
  font-family: var(--display); text-transform: uppercase;
  letter-spacing: 0.04em; font-size: clamp(1rem, 1.7vw, 1.3rem); color: var(--white);
}
.clientrow-note { margin: 0; font-size: 0.85rem; color: var(--ink-soft); }

/* Closing call to action */
.cta-band { padding-block: clamp(2.5rem, 4.5vw, 4rem); }
.cta { display: grid; gap: 1.6rem 3.5rem; align-items: center; }
@media (min-width: 860px) { .cta { grid-template-columns: 1fr auto; } }
.cta h2 { margin-bottom: 0.7rem; max-width: 18ch; }
.cta .lede { margin: 0; max-width: 52ch; }
.cta-btn { text-decoration: none; display: inline-block; white-space: nowrap; }

/* Join page: the list and the way in, side by side */
.joingrid { display: grid; gap: 2rem 3.5rem; margin-top: 2.2rem; }
@media (min-width: 860px) { .joingrid { grid-template-columns: 1fr 1fr; } }
.joingrid .plainlist { margin-top: 0; }
.joincta {
  border: 1px solid var(--paper-line); border-left: 3px solid var(--on-paper);
  padding: 1.6rem 1.7rem; align-self: start;
}
.joincta p { color: var(--on-paper-2); font-size: 0.98rem; }
.cbtn-dark {
  background: var(--ink); color: var(--white); border-color: var(--ink);
  text-decoration: none; display: inline-block; margin-top: 0.4rem;
}
.cbtn-dark:hover { background: transparent; color: var(--ink); }

.modal-link { margin: -1rem 0 1.4rem; }
.modal-link a { color: var(--tint); font-size: 0.9rem; }

/* --- Mobile menu ---------------------------------------------------------
   Six items will not fit across a phone: they overflowed the bar and the last
   one could not be reached. Below the breakpoint they collapse behind a button
   and open as a panel under the bar. */

.navtoggle { display: none; }

@media (max-width: 860px) {
  .js .navtoggle {
    display: flex; flex-direction: column; justify-content: center; gap: 4px;
    width: 42px; height: 38px; padding: 0 9px; cursor: pointer;
    background: transparent; border: 1px solid var(--ink-line); border-radius: 4px;
    margin-left: auto;
  }
  .navtoggle span { display: block; height: 1.5px; background: var(--white); transition: transform 0.22s ease, opacity 0.22s ease; }
  .nav.is-open .navtoggle span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
  .nav.is-open .navtoggle span:nth-child(2) { opacity: 0; }
  .nav.is-open .navtoggle span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }

  .nav .wrap { gap: 0.75rem; }
  .brand { margin-right: 0; }

  .js .nav-links {
    position: fixed; top: var(--nav-h); left: 0; right: 0;
    display: block; background: var(--ink);
    border-bottom: 1px solid var(--ink-line);
    max-height: calc(100svh - var(--nav-h)); overflow-y: auto;
    transform: translateY(-8px); opacity: 0; pointer-events: none;
    transition: opacity 0.2s ease, transform 0.2s ease;
  }
  .nav.is-open .nav-links { transform: none; opacity: 1; pointer-events: auto; }

  .nav-links a {
    display: block; padding: 1rem var(--pad); border-radius: 0;
    border-top: 1px solid var(--ink-line);
    font-size: 15px; letter-spacing: 0.05em; color: var(--white);
  }
  .nav-links a[aria-current="page"] { background: rgba(255,255,255,0.09); }
}

/* Below the menu breakpoint the brand wordmark is worth keeping: it is the
   only thing naming the site once the links are hidden. */
@media (max-width: 720px) {
  .brand span { display: inline; font-size: 15px; letter-spacing: 0.1em; }
  .brand img { width: 30px; }
}
@media (max-width: 420px) { .brand span { display: none; } }

/* --- Reveal --------------------------------------------------------------- */
/* Fails open by design. Nothing here is hidden by the stylesheet: the hiding
   class is added by script and removed again when the section comes into view.
   If the script never runs, never loads, or errors, no element ever gets the
   class and the whole page is simply visible. The earlier version hid sections
   in CSS and revealed them with script, which meant any failure in that script
   left a blank site with no way for a visitor to tell there was content. */
.reveal { transition: opacity 0.5s ease, transform 0.5s cubic-bezier(.2, .7, .3, 1); }
.reveal.is-pre { opacity: 0; transform: translateY(14px); }
@media (prefers-reduced-motion: reduce) {
  .reveal { transition: none; }
  .reveal.is-pre { opacity: 1; transform: none; }
}
