/* ── Archivo, self-hosted ───────────────────────────────────────────── */
/* Vendored from brand/fonts/ (see that directory's README and archivo.css).
 * One variable font, weight 400-700 and width 75-125%, in two subsets --
 * latin and latin-ext. Google's vietnamese subset is deliberately not
 * shipped: nothing on this site uses it.
 *
 * These replace a runtime <link> to fonts.googleapis.com. That link was a
 * third-party request on every public page load -- a preconnect handshake
 * and a blocking stylesheet the visitor paid for, and a Google request log
 * with a visitor's IP against a Nerdy Ventures page view. It is also the
 * rule the brand wrote for itself: no third-party runtime requests on
 * public pages (context/brand/brand-guidelines.md).
 *
 * font-display: swap -- text is readable immediately in the fallback stack
 * below and swaps when the face arrives.
 *
 * Archivo is SIL OFL 1.1; the licence ships at /static/fonts/OFL.txt and
 * must keep shipping with the files.
 */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 75% 125%;
  font-display: swap;
  src: url('/static/fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

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

/* ── tokens ─────────────────────────────────────────────────────────── */
:root {
  --paper:  #EEEDE8;
  --raised: #F6F5F2;
  --ink:    #1B2328;
  --steel:  #5F6B72;
  --rule:   #CFCCC4;
  --signal: #2D5F7C;
  --signal-ink: #24506B;
  --signal-wash: #DDE7EC;

  /* the inverted "terms" band */
  --band-bg:    #1B2328;
  --band-fg:    #EEEDE8;
  --band-muted: #A9B3B9;
  --band-rule:  #34404A;
  --band-accent:#8FBFDB;

  --on-signal: #F6F5F2;

  /* The logo's two gears (NV-118). The tile is the mark link's own colour,
     --ink; these are the colours that sit ON it, so they invert with it.
     Light: the on-light colourway. Values from brand/logos/README.md. */
  --logo-gear:    #2F3B43;
  --logo-venture: #8FBFDB;

  --measure: 62ch;
  --gutter: 16px;
  --step: clamp(3.5rem, 8vw, 6.5rem);
  --radius: 3px;

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:  #15191C;
    --raised: #1C2226;
    --ink:    #E8E6E1;
    --steel:  #98A2A8;
    --rule:   #2E363B;
    --signal: #7FB0CE;
    --signal-ink: #9CC4DC;
    --signal-wash: #1F2E38;

    --band-bg:    #0D1114;
    --band-fg:    #EEEDE8;
    --band-muted: #98A2A8;
    --band-rule:  #26303A;
    --band-accent:#8FBFDB;

    --on-signal: #0D1114;

    --logo-gear:    #CFCCC4;
    --logo-venture: #2D5F7C;
  }
}
:root[data-theme="dark"] {
  --paper:  #15191C;
  --raised: #1C2226;
  --ink:    #E8E6E1;
  --steel:  #98A2A8;
  --rule:   #2E363B;
  --signal: #7FB0CE;
  --signal-ink: #9CC4DC;
  --signal-wash: #1F2E38;

  --band-bg:    #0D1114;
  --band-fg:    #EEEDE8;
  --band-muted: #98A2A8;
  --band-rule:  #26303A;
  --band-accent:#8FBFDB;

  --on-signal: #0D1114;

  --logo-gear:    #CFCCC4;
  --logo-venture: #2D5F7C;
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: Archivo, ui-sans-serif, -apple-system, "Segoe UI", system-ui, sans-serif;
  font-size: 1.0625rem;
  line-height: 1.6;
  font-stretch: 100%;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-stretch: 112%;
  font-weight: 650;
  letter-spacing: -0.015em;
  line-height: 1.08;
  text-wrap: balance;
  margin: 0;
}

p { margin: 0 0 1.1em; max-width: var(--measure); }
p:last-child { margin-bottom: 0; }
strong { font-weight: 650; }

a { color: var(--signal-ink); text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }

:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; border-radius: 1px; }

/* ── the living backdrop (NV-61) ────────────────────────── */
/* A fixed, viewport-sized canvas. static/js/backdrop.js renders a
 * kaleidoscope into it as characters: a shaded 3D lattice of Nerdy
 * Ventures marks, folded into six mirrored segments about the centre of
 * the screen. It sits ON TOP of the body background and UNDERNEATH every
 * piece of content -- which is why `main` and the footer
 * below claim a stacking position of their own. The masthead already has
 * `z-index: 10`, and its translucent, blurred background means the field
 * reads through it rather than stopping at it.
 *
 * Sections that carry their own opaque background -- the inverted .terms
 * band, the .sheet -- cover the field completely. That is the intended
 * behaviour and not an oversight: they read as solid slabs laid over a
 * live surface, which is more interesting than a texture that runs
 * uninterrupted through everything.
 *
 * `pointer-events: none` is load-bearing. A full-viewport fixed element
 * that swallowed clicks would break every link on the site.
 *
 * The mask is what keeps this decoration rather than noise: strongest in
 * the upper middle of the viewport and gone at the edges, so the pattern
 * never crowds the masthead rule, the footer, or the gutters. It also
 * vignettes the kaleidoscope's outer rings, which is where its twelve
 * copies are spread thinnest and have least to say.
 *
 * It starts at `opacity: 0` and is revealed by the `is-live` class the
 * script adds once the first frame is in it. With JavaScript off the
 * class never arrives, the canvas stays invisible, and the page is
 * exactly what it was before this file existed.
 */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 900ms ease-out;
  -webkit-mask-image: radial-gradient(115% 85% at 50% 22%, #000 0%, #000 42%, transparent 88%);
  mask-image: radial-gradient(115% 85% at 50% 22%, #000 0%, #000 42%, transparent 88%);
}
.backdrop.is-live { opacity: 1; }

main, .foot { position: relative; z-index: 1; }

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

/* ── layout ─────────────────────────────────────────────────────────── */
.wrap { width: 100%; max-width: 72rem; margin-inline: auto; padding-inline: var(--gutter); }

.band { padding-block: var(--step); border-top: 1px solid var(--rule); }
.band:first-of-type { border-top: 0; }
.band-tight { padding-block: clamp(2.5rem, 5vw, 4rem); }

.band-head {
  font-size: clamp(1.6rem, 3.2vw, 2.25rem);
  margin-bottom: 1.75rem;
  max-width: 24ch;
}

/* A judgment line used as a section opener: the sentence is the heading. */
.statement {
  font-size: clamp(1.75rem, 4vw, 3rem);
  font-stretch: 114%;
  font-weight: 650;
  line-height: 1.1;
  letter-spacing: -0.02em;
  max-width: 22ch;
  margin-bottom: 2rem;
}
.statement .quiet { color: var(--steel); }
.statement .price { display: block; color: var(--steel); font-size: 0.7em; margin-top: 0.35em; font-variant-numeric: tabular-nums; }

/* ── buttons ────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.5rem;
  min-height: 3rem;
  padding: 0.7rem 1.4rem;
  border-radius: var(--radius);
  border: 1.5px solid var(--signal);
  background: var(--signal);
  color: var(--on-signal);
  font: inherit;
  font-weight: 650;
  font-stretch: 104%;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease, transform 120ms ease;
}
.btn:hover { background: var(--signal-ink); border-color: var(--signal-ink); }
.btn:active { transform: translateY(1px); }
.btn-ghost {
  background: transparent;
  color: var(--signal-ink);
  border-color: color-mix(in srgb, var(--signal) 55%, transparent);
}
.btn-ghost:hover { background: var(--signal-wash); border-color: var(--signal); color: var(--signal-ink); }
.btn-lg { min-height: 3.4rem; padding: 0.85rem 1.75rem; font-size: 1.0625rem; }
.btn-sm { min-height: 2.5rem; padding: 0.45rem 1rem; font-size: 0.9375rem; }

.actions { display: flex; flex-wrap: wrap; gap: 0.75rem 1rem; align-items: center; margin-top: 2rem; }
.actions-note { flex: 1 1 18rem; margin: 0.35rem 0 0; font-size: 0.9375rem; color: var(--steel); max-width: 40ch; }

/* ── masthead ───────────────────────────────────────────────────────── */
.masthead {
  border-bottom: 1px solid var(--rule);
  position: sticky; top: 0; z-index: 10;
  background: color-mix(in srgb, var(--paper) 90%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.masthead-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem 1.5rem; padding-block: 0.85rem; flex-wrap: wrap;
}
/* The wordmark is a two-line lockup (NV-58): the name, and a descriptor
   under it. `align-items: center` still applies -- the glyph centres
   against the pair, not against the first line. */
.mark {
  font-stretch: 118%;
  font-weight: 700; font-size: 1.125rem; letter-spacing: -0.01em;
  color: var(--ink); text-decoration: none;
  display: inline-flex; align-items: center; gap: 0.55rem;
}
.mark svg { width: 1.5rem; height: 1.5rem; flex: none; }
.mark-lockup { display: flex; flex-direction: column; }
/* Tight, because two lines of the same leading as one line of body copy
   read as two separate things rather than one mark. */
.mark-name { line-height: 1.1; }
/* Normal width and weight against the name's 118% stretch and 700: the
   contrast is what makes this read as a lockup instead of a wrapped
   sentence. `em`, so it tracks whichever size .mark is set to -- the
   footer's mark is smaller and its descriptor should shrink with it. */
.mark-desc {
  font-stretch: normal;
  font-weight: 500; font-size: 0.6em; letter-spacing: 0.005em;
  line-height: 1.25; color: var(--steel);
}
@media (max-width: 22rem) {
  /* Below this the descriptor wraps to three lines and pushes the
     masthead taller than the content it sits above. The name and the
     glyph carry the mark on their own at that width. */
  .mark-desc { display: none; }
}
.nav { display: flex; gap: 0.25rem 1.5rem; align-items: center; font-size: 0.9375rem; flex-wrap: wrap; }
.nav a { color: var(--steel); text-decoration: none; padding-block: 0.25rem; }
.nav a:hover, .nav a[aria-current="page"] { color: var(--ink); text-decoration: underline; text-underline-offset: 6px; }
.nav .btn { margin-left: 0.5rem; color: var(--on-signal); }
.nav .btn:hover, .nav .btn[aria-current="page"] { text-decoration: none; color: var(--on-signal); }
@media (max-width: 40rem) {
  .nav { width: 100%; justify-content: space-between; gap: 0.75rem; }
  .nav .btn { margin-left: auto; }
}

/* ── hero ───────────────────────────────────────────────────────────── */
.hero { padding-block: clamp(3.5rem, 9vw, 7.5rem) clamp(3rem, 6vw, 5rem); }
.hero h1 {
  font-size: clamp(2.4rem, 6.6vw, 4.75rem);
  font-stretch: 120%;
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.03em;
  max-width: 19ch;
}
.hero h1 .quiet { color: var(--steel); }
.hero-sub {
  margin-top: 1.75rem;
  font-size: clamp(1.125rem, 2vw, 1.375rem);
  line-height: 1.45;
  color: var(--ink);
  max-width: 44ch;
}
.hero-sub .quiet { color: var(--steel); }
.hero-inner { font-size: clamp(1.9rem, 4.6vw, 3.25rem); max-width: 20ch; }

/* ── symptom list ───────────────────────────────────────────────────── */
.symptoms {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  display: grid;
  grid-template-columns: minmax(0, 18rem) 1fr;
  gap: 1.5rem clamp(2rem, 5vw, 5rem);
  align-items: start;
  border-top: 1px solid var(--rule);
  padding-top: 2rem;
}
.symptoms h2 { font-size: clamp(1.375rem, 2.4vw, 1.75rem); max-width: 14ch; }
.symptoms ul { margin: 0; padding: 0; display: grid; gap: 0; }
.symptoms li {
  list-style: none;
  border-bottom: 1px solid var(--rule);
  padding: 1rem 0 1rem 1.25rem;
  position: relative;
  max-width: 60ch;
  font-size: clamp(1.0625rem, 1.5vw, 1.1875rem);
  line-height: 1.45;
}
.symptoms li::before {
  content: "";
  position: absolute; left: 0; top: 1.35rem;
  width: 0.5rem; height: 0.5rem;
  background: var(--signal);
}
.symptoms li:last-child { border-bottom: 0; }
.symptoms-close { grid-column: 2; margin-top: 0.5rem; font-size: 1.0625rem; color: var(--steel); max-width: 60ch; }
@media (max-width: 52rem) {
  .symptoms { grid-template-columns: 1fr; }
  .symptoms-close { grid-column: 1; }
}

/* ── quote sheet ────────────────────────────────────────────────────── */
.sheet {
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--raised);
  overflow: hidden;
  box-shadow: 0 1px 0 color-mix(in srgb, var(--ink) 6%, transparent);
}
.row {
  display: grid;
  grid-template-columns: minmax(12rem, 16rem) 1fr minmax(9rem, 12rem);
  gap: 1.5rem;
  padding: 1.75rem 1.6rem;
  border-top: 1px solid var(--rule);
  align-items: start;
}
.row:first-child { border-top: 0; }
.row h3 { font-size: 1.25rem; font-stretch: 110%; }
.row h3 small { display: block; font-size: 0.875rem; font-weight: 500; font-stretch: 100%; color: var(--steel); margin-top: 0.3rem; letter-spacing: 0; }
.row p { font-size: 0.9875rem; color: var(--steel); margin: 0; max-width: 56ch; }
.row .fig {
  font-stretch: 105%;
  font-weight: 650; font-size: 1.1875rem;
  font-variant-numeric: tabular-nums;
  text-align: right; white-space: nowrap;
  letter-spacing: -0.01em;
}
.row .fig small { display: block; font-weight: 400; font-size: 0.8125rem; color: var(--steel); margin-top: 0.3rem; white-space: normal; line-height: 1.4; }
.row-featured { background: color-mix(in srgb, var(--signal) 7%, var(--raised)); }
.row-open { border-top-style: dashed; }
.row-open .fig { white-space: normal; }
.row-open .fig .btn { white-space: nowrap; }
.row-featured .fig { color: var(--signal-ink); }
.sheet-foot {
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center;
  gap: 0.75rem 1.5rem;
  padding: 1.1rem 1.6rem;
  border-top: 1px solid var(--rule);
  background: var(--paper);
  font-size: 0.9375rem; color: var(--steel);
}
.sheet-foot p { margin: 0; max-width: none; }

@media (max-width: 48rem) {
  .row { grid-template-columns: 1fr; gap: 0.7rem; padding: 1.4rem 1.2rem; }
  .row .fig { text-align: left; }
  .sheet-foot { padding-inline: 1.2rem; }
}

.sheet-note { margin-top: 1rem; font-size: 0.9375rem; color: var(--steel); }

/* ── inverted terms band ────────────────────────────────────────────── */
.terms {
  background: var(--band-bg);
  color: var(--band-fg);
  border-top: 4px solid var(--signal);
}
.terms .statement { color: var(--band-fg); }
.terms .statement .quiet { color: var(--band-muted); }
.terms-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0 clamp(1.5rem, 4vw, 3.5rem);
  border-top: 1px solid var(--band-rule);
}
.terms-grid > div {
  padding-block: 1.75rem;
  border-bottom: 1px solid var(--band-rule);
}
.terms-grid h3 { font-size: 1.1875rem; font-stretch: 110%; margin-bottom: 0.6rem; color: var(--band-fg); }
.terms-grid p { font-size: 0.9875rem; color: var(--band-muted); line-height: 1.55; }
.terms-grid p strong { color: var(--band-fg); font-weight: 500; }
.terms .btn { background: var(--band-accent); border-color: var(--band-accent); color: var(--band-bg); }
.terms .btn:hover { background: #A7CFE6; border-color: #A7CFE6; }
.terms .btn-ghost { background: transparent; color: var(--band-fg); border-color: var(--band-rule); }
.terms .btn-ghost:hover { border-color: var(--band-accent); background: color-mix(in srgb, var(--band-accent) 12%, transparent); }
@media (max-width: 58rem) { .terms-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 38rem) { .terms-grid { grid-template-columns: 1fr; } }

/* ── prose sections ─────────────────────────────────────────────────── */
.prose p { font-size: 1.0625rem; }
.prose { max-width: var(--measure); }
.prose h3 { font-size: 1.1875rem; margin: 0 0 0.5rem; }
.prose h3 + p { margin-top: 0; }
.prose ul { padding-left: 1.2rem; margin: 0 0 1.1em; }
.prose li { margin-bottom: 0.4rem; }

.two-up { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
.two-up-wide { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
@media (max-width: 52rem) { .two-up, .two-up-wide { grid-template-columns: 1fr; } }

/* ── fit / not-a-fit ────────────────────────────────────────────────── */
.fit { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.5rem, 4vw, 3.5rem); }
.fit > div { border-top: 3px solid var(--rule); padding-top: 1.25rem; }
.fit > .fit-yes { border-top-color: var(--signal); }
.fit h3 { font-size: 1.25rem; margin-bottom: 1rem; }
.fit ul { margin: 0; padding: 0; }
.fit li { list-style: none; padding: 0.7rem 0; border-bottom: 1px solid var(--rule); font-size: 1.0625rem; line-height: 1.45; max-width: 44ch; }
.fit li:last-child { border-bottom: 0; }
.fit .fit-no li { color: var(--steel); }
@media (max-width: 48rem) { .fit { grid-template-columns: 1fr; } }

/* ── numbered sequence ──────────────────────────────────────────────── */
.steps { margin: 0; padding: 0; counter-reset: step; display: grid; gap: 0; border-top: 1px solid var(--rule); }
.steps li {
  list-style: none;
  counter-increment: step;
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 18rem) 1fr;
  gap: 0.5rem clamp(1rem, 3vw, 2.5rem);
  padding-block: 1.75rem;
  border-bottom: 1px solid var(--rule);
  align-items: start;
}
.steps li::before {
  content: counter(step);
  font-stretch: 120%;
  font-weight: 700;
  font-size: clamp(2rem, 4vw, 2.75rem);
  line-height: 1;
  color: var(--signal);
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.steps h3 { font-size: 1.25rem; padding-top: 0.25rem; }
.steps p { font-size: 1rem; color: var(--steel); max-width: 52ch; margin: 0; }
.steps p + p { margin-top: 0.6rem; }
@media (max-width: 48rem) {
  .steps li { grid-template-columns: 3rem 1fr; }
  .steps p { grid-column: 2; }
}

/* ── q & a ──────────────────────────────────────────────────────────── */
.qa { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem clamp(2rem, 5vw, 4rem); }
.qa > div { border-top: 1px solid var(--rule); padding-top: 1.1rem; }
.qa h3 { font-size: 1.125rem; margin-bottom: 0.5rem; }
.qa p { font-size: 1rem; color: var(--steel); }
@media (max-width: 48rem) { .qa { grid-template-columns: 1fr; gap: 1.5rem; } }

/* ── tier sheet on services ─────────────────────────────────────────── */
.tiers { margin-top: 2rem; }

/* ── contact form ───────────────────────────────────────────────────── */
.form { display: grid; gap: 1.25rem; max-width: 40rem; }
.form label { display: grid; gap: 0.4rem; font-size: 0.9375rem; font-weight: 600; }
.form label span.hint { font-weight: 400; color: var(--steel); }
.form input, .form select, .form textarea {
  font: inherit; font-size: 1rem;
  color: var(--ink);
  background: var(--raised);
  border: 1.5px solid var(--rule);
  border-radius: var(--radius);
  padding: 0.7rem 0.85rem;
  width: 100%;
}
.form textarea { min-height: 8.5rem; resize: vertical; }
.form input:focus, .form select:focus, .form textarea:focus { outline: 2px solid var(--signal); outline-offset: 1px; border-color: var(--signal); }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 40rem) { .form-row { grid-template-columns: 1fr; } }
.form-foot { display: flex; flex-wrap: wrap; gap: 0.75rem 1.25rem; align-items: center; margin-top: 0.25rem; }
.form-foot p { margin: 0; font-size: 0.9rem; color: var(--steel); max-width: none; }
.form-fallback { margin-top: 1.25rem; font-size: 0.9375rem; color: var(--steel); }

.contact-side { display: grid; gap: 2rem; align-content: start; }
.contact-side h2 { font-size: 1.25rem; margin-bottom: 0.6rem; }
.contact-side p { font-size: 1rem; color: var(--steel); }
.contact-side .big { font-size: 1.1875rem; color: var(--ink); font-weight: 600; }
.contact-side .big a { color: var(--signal-ink); }
.contact-side ul { margin: 0; padding-left: 1.1rem; color: var(--steel); font-size: 1rem; }
.contact-side li { margin-bottom: 0.4rem; }

/* ── footer ─────────────────────────────────────────────────────────── */
.foot { border-top: 1px solid var(--rule); padding-block: 3rem 3.5rem; font-size: 0.9375rem; color: var(--steel); }
.foot a { color: var(--steel); }
.foot a:hover { color: var(--ink); }
.foot-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 2rem; }
.foot-grid p { margin: 0 0 0.4rem; max-width: 34ch; }
.foot .mark { font-size: 1.0625rem; margin-bottom: 0.75rem; }
.foot ul { margin: 0; padding: 0; list-style: none; }
.foot li { margin-bottom: 0.4rem; }
.foot-legal { margin-top: 2.5rem; padding-top: 1.25rem; border-top: 1px solid var(--rule); font-size: 0.85rem; display: flex; flex-wrap: wrap; gap: 0.5rem 2rem; justify-content: space-between; }
.foot-legal p { margin: 0; max-width: none; }
@media (max-width: 48rem) { .foot-grid { grid-template-columns: 1fr 1fr; } .foot-grid > :first-child { grid-column: 1 / -1; } }

/* ── utility ────────────────────────────────────────────────────────── */
.lede { font-size: clamp(1.125rem, 2.2vw, 1.375rem); color: var(--steel); max-width: 48ch; line-height: 1.45; }
.cta-link {
  display: inline-block;
  margin-top: 1.5rem;
  font-weight: 600;
  font-size: 1.0625rem;
  color: var(--signal-ink);
  border-bottom: 2px solid var(--signal);
  text-decoration: none;
  padding-bottom: 2px;
}
.cta-link:hover { background: color-mix(in srgb, var(--signal) 12%, transparent); }
.skip {
  position: absolute; left: -9999px;
  background: var(--ink); color: var(--paper); padding: 0.6rem 1rem;
}
.skip:focus { left: var(--gutter); top: 0.5rem; z-index: 100; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* Was a `style="color:inherit;text-decoration:none"` attribute on the
   /services/ pricing sheet's per-offering anchor (templates/pages/services.html)
   -- moved here so the Content-Security-Policy's style-src does not need
   'unsafe-inline'; see platform/app/README.md "Security headers". */
.plain-link { color: inherit; text-decoration: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ── Honeypot (NV-54) ────────────────────────────────────────────────── */
/* The one field on /contact/ that a human must never fill in. Positioned
 * off-screen rather than `display:none`: some form-filling bots skip
 * anything explicitly hidden, and the point is that they DO fill it. A
 * person never sees it, never tabs to it (tabindex="-1" on the input) and
 * never hears it (aria-hidden on the wrapper).
 *
 * Without this rule the field is simply visible, and a visitor who
 * helpfully types their website address is silently marked as spam. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ── light/dark toggle in the masthead (NV-76) ───────────────────────── */
/* The palette and the `data-theme` override hooks have been in this file
 * since the site was built; this is the control that finally reaches them.
 * Hidden until static/js/theme.js reveals it -- see the comment on the
 * button in templates/layout/base.html for why a dead control is worse
 * than none. */
.theme-toggle {
  /* A button element, so it needs the button reset: this is a masthead
   * icon, not a form control. */
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  padding: 0.3rem;
  margin: 0;
  color: var(--steel);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius);
  /* `hidden` is only `display: block` in the UA sheet, and the rule above
   * would otherwise beat it and show a button the script never wired. */
  line-height: 0;
}
.theme-toggle[hidden] { display: none; }
.theme-toggle:hover { color: var(--ink); }
.theme-toggle:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

.theme-icon { width: 20px; height: 20px; display: block; }

/* Which icon shows is the DESTINATION, not the current state: in light
 * you see a moon, because pressing it gives you dark -- which is what the
 * accessible name the script sets says too ("Switch to dark theme").
 *
 * Both icons are in the markup and CSS picks one, so the right icon is
 * painted in the same frame as the theme it belongs to. Three rules,
 * matching how every other themed value in this file is written: the
 * light default, the OS-dark case that an explicit `light` must beat, and
 * the explicit `dark` case. */
.theme-icon-sun { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-icon-sun { display: block; }
  :root:not([data-theme="light"]) .theme-icon-moon { display: none; }
}
:root[data-theme="dark"] .theme-icon-sun { display: block; }
:root[data-theme="dark"] .theme-icon-moon { display: none; }

/* ── account control in the masthead (NV-56) ─────────────────────────── */
/* A <details>/<summary> disclosure, because the CSP forbids inline script
 * and nothing is vendored -- see the comment in templates/layout/base.html.
 * Everything below is presentation; the open/closed state is the browser's.
 */
.acct-signin { color: var(--steel); text-decoration: none; padding-block: 0.25rem; }
.acct-signin:hover, .acct-signin[aria-current="page"] { color: var(--ink); text-decoration: underline; text-underline-offset: 6px; }

.acct { position: relative; }

/* The default disclosure triangle is removed in both dialects: WebKit
 * needs the pseudo-element, everyone else honours `list-style`. Without
 * both, Safari draws a marker next to the avatar. */
.acct > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 0.3rem; }
.acct > summary::-webkit-details-marker { display: none; }
.acct > summary::marker { content: ""; }
.acct > summary:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; border-radius: 999px; }

.acct-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem;
  border-radius: 999px;
  background: var(--signal);
  color: var(--on-signal);
  font-size: 0.75rem;
  font-weight: 700;
  font-stretch: 104%;
  letter-spacing: 0.02em;
  /* The letters are centred by flex; this stops a descender nudging them. */
  line-height: 1;
  user-select: none;
}
.acct > summary:hover .acct-avatar { background: var(--signal-ink); }

.acct-caret { width: 0; height: 0; border: 4px solid transparent; border-top-color: var(--steel); margin-top: 3px; }
.acct[open] .acct-caret { border-top-color: transparent; border-bottom-color: var(--ink); margin-top: -3px; }

.acct-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 0.6rem);
  z-index: 20;
  min-width: 14rem;
  display: flex;
  flex-direction: column;
  background: var(--raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px color-mix(in srgb, var(--ink) 18%, transparent);
  padding: 0.35rem 0;
  font-size: 0.9375rem;
}
.acct-who { padding: 0.5rem 0.9rem 0.6rem; border-bottom: 1px solid var(--rule); margin-bottom: 0.3rem; }
.acct-who strong { display: block; font-weight: 650; color: var(--ink); }
.acct-who span { display: block; font-size: 0.8125rem; color: var(--steel); overflow-wrap: anywhere; }

.acct-menu a, .acct-menu button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.45rem 0.9rem;
  color: var(--ink);
  text-decoration: none;
  font: inherit;
  font-size: 0.9375rem;
  background: none;
  border: 0;
  cursor: pointer;
}
.acct-menu a:hover, .acct-menu button:hover { background: var(--signal-wash); color: var(--signal-ink); }
.acct-menu form { margin: 0.3rem 0 0; border-top: 1px solid var(--rule); padding-top: 0.3rem; }

/* On a narrow masthead the nav already wraps to its own full-width row;
 * anchoring the menu to the right edge of a wrapped row can push it off
 * screen, so it anchors left there instead. */
@media (max-width: 40rem) {
  .acct-menu { right: auto; left: 0; }
}

/* ── portal (NV-57) ─────────────────────────────────────────────────
 * The client-facing portal extends layout/base.html, not layout/admin.html
 * -- a client is a visitor to this site who happens to be signed in, so
 * they get this stylesheet and the brand rather than the internal tool's.
 * That is why these classes live here and not in admin.css, and why they
 * are built from the same tokens, .sheet border and .wrap measure the
 * marketing pages use instead of importing the admin grid.
 */
.pt { padding-block: clamp(2.5rem, 5vw, 4rem) clamp(3rem, 6vw, 5rem); }
.pt-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.5rem 1.5rem; margin-bottom: 0.35rem; }
.pt-head h1 { font-size: clamp(1.6rem, 3.2vw, 2.25rem); margin: 0; }
.pt-sub { color: var(--steel); margin: 0 0 2rem; font-size: 0.9375rem; }
.pt-back { font-size: 0.9375rem; }

.pt-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: 1rem; margin-bottom: 2.5rem; }
.pt-card {
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--raised); padding: 1.25rem 1.4rem;
}
.pt-card h2 { font-size: 0.8125rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--steel); margin: 0 0 0.5rem; font-weight: 600; }
.pt-figure { font-size: 1.75rem; font-stretch: 112%; font-weight: 700; line-height: 1.1; margin: 0; }
.pt-card p.pt-note { margin: 0.4rem 0 0; font-size: 0.9375rem; color: var(--steel); max-width: none; }

.pt-section { margin-bottom: 2.5rem; }
.pt-section > h2 { font-size: 1.25rem; margin: 0 0 1rem; }

/* One engagement or one invoice, as a row you can click into. A block
 * link rather than a card with a link inside it: the whole row is the
 * target, which is what a thumb on a phone expects. */
.pt-row {
  display: block; text-decoration: none; color: inherit;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--raised); padding: 1.1rem 1.3rem; margin-bottom: 0.75rem;
}
a.pt-row:hover { border-color: var(--signal); background: var(--signal-wash); }
a.pt-row:hover .pt-row-title { color: var(--signal-ink); }
.pt-row-top { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.35rem 1rem; }
.pt-row-title { font-weight: 700; font-stretch: 108%; }
.pt-row-meta { color: var(--steel); font-size: 0.9375rem; margin: 0.3rem 0 0; max-width: none; }
.pt-amount { font-variant-numeric: tabular-nums; font-weight: 700; }

/* Status. Four buckets, the same four the admin surface uses, named for
 * what they mean rather than for a colour. */
.pt-state {
  display: inline-block; font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase;
  padding: 0.15rem 0.5rem; border-radius: 999px;
  border: 1px solid var(--rule); color: var(--steel); background: transparent;
}
.pt-state-ok   { color: var(--signal-ink); border-color: var(--signal); background: var(--signal-wash); }
.pt-state-warn { color: #7A4A12; border-color: #C79A57; background: #F6EBD9; }
.pt-state-idle { color: var(--steel); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .pt-state-warn { color: #E7C58A; border-color: #7A5E2E; background: #2A2318; }
}
:root[data-theme="dark"] .pt-state-warn { color: #E7C58A; border-color: #7A5E2E; background: #2A2318; }

/* The milestone list. A list, not a table: each entry is a name, a date
 * and a state, and a table of three columns two of which are often empty
 * reads worse than lines do. */
.pt-miles { list-style: none; margin: 0; padding: 0; }
.pt-miles li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 1rem;
  justify-content: space-between;
  padding: 0.7rem 0; border-top: 1px solid var(--rule);
}
.pt-miles li:first-child { border-top: 0; }
.pt-mile-name { font-weight: 600; }
.pt-mile-done .pt-mile-name { color: var(--steel); text-decoration: line-through; text-decoration-thickness: 1px; }
.pt-mile-meta { color: var(--steel); font-size: 0.9375rem; }

.pt-table { width: 100%; border-collapse: collapse; font-size: 0.9375rem; }
.pt-table th, .pt-table td { text-align: left; padding: 0.7rem 0.9rem; border-bottom: 1px solid var(--rule); vertical-align: top; }
.pt-table th { font-size: 0.8125rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--steel); }
.pt-table .num, .pt-table .money { text-align: right; font-variant-numeric: tabular-nums; }
.pt-table tfoot td { border-bottom: 0; border-top: 2px solid var(--rule); font-weight: 700; }
.pt-scroll { overflow-x: auto; }

.pt-defs { display: grid; grid-template-columns: auto 1fr; gap: 0.5rem 1.25rem; margin: 0; font-size: 0.9375rem; }
.pt-defs dt { color: var(--steel); }
.pt-defs dd { margin: 0; }

.pt-empty { border: 1px dashed var(--rule); border-radius: var(--radius); padding: 2rem 1.5rem; text-align: center; color: var(--steel); }
.pt-empty p { margin: 0 auto; max-width: 44ch; }
.pt-quiet { color: var(--steel); }

/* An invoice is the one page here somebody prints. Everything that is
 * navigation rather than the document itself comes off the paper -- and
 * so does the backdrop, which a portal page never has anyway (it sets no
 * `json_ld`, so layout/base.html renders no canvas) but a printed public
 * page would, as several thousand characters of toner. */
/* ---------------------------------------------------------------- contracts
 *
 * A rendered contract, and the control that signs it (NV-34).
 *
 * `.doc-body` wraps the frozen HTML a contract stores. It is styled here in
 * site.css rather than admin.css because both surfaces show the same
 * document: the owner at /admin/contracts/{id} and the client at
 * /portal/contracts/{id}. One definition, so the thing the client signs and
 * the thing the owner reads cannot drift apart visually.
 *
 * These four classes were referenced by the templates before they existed,
 * which a browser walkthrough on 2026-09-21 caught: the signing control --
 * the single most consequential interaction in the product -- rendered as an
 * unstyled run of label, input, checkbox and button on one line.
 */
.doc-body {
  max-width: var(--measure);
}
/* A contract is dense, numbered and read closely. Tighter rhythm than
 * marketing prose, and clause headings that are findable when someone is
 * looking for section 10. */
.doc-body h1 { font-size: 1.5rem; margin: 0 0 1.5rem; }
.doc-body h2 { font-size: 1.125rem; margin: 2rem 0 0.75rem; }
.doc-body h3 { font-size: 1rem; margin: 1.5rem 0 0.5rem; }
.doc-body p { margin: 0 0 0.85rem; line-height: 1.65; }
.doc-body ul, .doc-body ol { margin: 0 0 0.85rem 1.25rem; line-height: 1.65; }
.doc-body li { margin-bottom: 0.35rem; }
.doc-body table { width: 100%; border-collapse: collapse; margin: 0 0 1.25rem; }
.doc-body th, .doc-body td {
  padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--rule); text-align: left;
}
.doc-body strong { font-weight: 600; }
/* The block renderer wraps each block in .wrap, which is a page-width
 * container. Inside a document that is already constrained, it would add a
 * second gutter and a second max-width. */
.doc-body .wrap { padding: 0; max-width: none; }

.pt-form { display: grid; gap: 1rem; max-width: var(--measure); margin-top: 1rem; }
.pt-form label { display: grid; gap: 0.35rem; font-size: 0.9375rem; }
.pt-form input[type="text"] {
  padding: 0.6rem 0.75rem; border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--paper); color: var(--ink); font: inherit; max-width: 24rem;
}
.pt-form input[type="text"]:focus-visible { outline: 2px solid var(--signal); outline-offset: 1px; }
.pt-form button { justify-self: start; }

/* The consent control. `align-items: start` so a two-line consent sentence
 * keeps its box beside the first line rather than centred against the
 * paragraph, and the whole sentence is the label, so the whole sentence is
 * the click target. */
.pt-check {
  display: grid; grid-template-columns: auto 1fr; gap: 0.6rem;
  align-items: start; line-height: 1.55; font-size: 0.9375rem; cursor: pointer;
}
.pt-check input[type="checkbox"] { margin-top: 0.2rem; width: 1rem; height: 1rem; }

.pt-hint { color: var(--steel); font-size: 0.875rem; margin: 0; line-height: 1.55; }

@media print {
  .masthead, .foot, .skip, .pt-back, .pt-print-hide, .backdrop { display: none !important; }
  /* A signed contract is a document somebody files. The control that
   * signed it is not part of it. */
  .pt-form, .pt-check, .pt-hint { display: none !important; }
  .doc-body { max-width: none; }
  .pt { padding-block: 0; }
  .pt-card, .pt-row, .pt-table td, .pt-table th { background: transparent; }
}

/* ==========================================================================
   Content blocks and tree-driven chrome (NV-71)

   Everything below is used only by pages drawn from the content tree, or by
   the masthead and footer once `nav.source` is switched to `tree`. Nothing
   here restyles an existing page: the cutover is meant to be invisible, and
   a stylesheet that quietly redefined `.nav` would undo that.

   The block presets (`.callout-signal`, `.figure-center`) are why an author
   gets a `<select>` of tones and widths rather than a colour picker: the
   choices live here, in the theme, so a page cannot drift away from the
   brand by being edited.
   ========================================================================== */

/* The announcement banner, above the masthead. */
.banner {
  background: var(--signal-wash);
  border-bottom: 1px solid var(--rule);
  font-size: 0.9rem;
}
.banner p { margin: 0; padding: 0.6rem 0; color: var(--ink); }
.banner a { margin-left: 0.5rem; }

/* A nav entry with children. A <details> disclosure, not a hover menu --
   see templates/layout/base.html for why. Closed by default, so the
   masthead looks identical to the flat version until someone opens one. */
.nav-group { position: relative; display: inline-block; }
.nav-group > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}
.nav-group > summary::-webkit-details-marker { display: none; }
.nav-group > summary::after {
  content: "";
  width: 0.35rem;
  height: 0.35rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-1px) rotate(45deg);
}
.nav-group[open] > summary::after { transform: translateY(1px) rotate(-135deg); }
.nav-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 20;
  min-width: 14rem;
  display: grid;
  gap: 0.15rem;
  padding: 0.5rem;
  background: var(--raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgb(0 0 0 / 12%);
}
.nav-menu a { display: block; padding: 0.35rem 0.5rem; border-radius: var(--radius); }
.nav-menu a:hover { background: var(--signal-wash); }

/* Breadcrumbs. Only below the top level; the trail and the JSON-LD
   BreadcrumbList are built from one walk of the tree. */
.crumbs { padding-top: 1.5rem; font-size: 0.85rem; color: var(--steel); }
.crumbs ol { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0; padding: 0; list-style: none; }
.crumbs li + li::before { content: "/"; margin-right: 0.4rem; color: var(--rule); }

/* Blocks share one vertical rhythm, so a page reads evenly however its
   blocks were ordered. */
.block { margin-block: var(--step); }
.content-page > .block:first-of-type { margin-top: calc(var(--step) * 0.6); }
.block-prose { max-width: var(--measure); }
.block-prose h2 { margin-top: 2rem; }
.block-prose h3 { margin-top: 1.5rem; }
.block-prose table { width: 100%; border-collapse: collapse; }
.block-prose th, .block-prose td { padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--rule); text-align: left; }
.block-prose pre { padding: 1rem; overflow-x: auto; background: var(--raised); border-radius: var(--radius); }

.callout {
  max-width: var(--measure);
  padding: 1.25rem 1.5rem;
  border-left: 3px solid var(--signal);
  background: var(--raised);
  border-radius: var(--radius);
}
.callout > :last-child { margin-bottom: 0; }
.callout-title { margin: 0 0 0.5rem; font-weight: 600; }
.callout-signal { border-left-color: var(--signal); }
.callout-quiet  { border-left-color: var(--rule); }
.callout-warning { border-left-color: #B4761F; }

.faq { max-width: var(--measure); margin: 0; }
.faq-item { border-bottom: 1px solid var(--rule); }
.faq-item > summary {
  cursor: pointer;
  padding: 0.85rem 0;
  list-style: none;
  font-weight: 600;
}
.faq-item > summary::-webkit-details-marker { display: none; }
/* <dt> inside <summary> keeps the definition-list semantics the JSON-LD
   mirrors; it must not also be a block box, or every question wraps. */
.faq-item > summary dt { display: inline; }
.faq-item dd { margin: 0 0 1rem; color: var(--steel); }

.cta {
  padding: 2rem;
  background: var(--band-bg);
  color: var(--band-fg);
  border-radius: var(--radius);
}
.cta h2 { margin-top: 0; color: var(--band-fg); }
.cta p { max-width: var(--measure); color: var(--band-muted); }

.stats { display: flex; flex-wrap: wrap; gap: 2.5rem; margin: 0; padding: 0; list-style: none; }
.stat { display: grid; gap: 0.25rem; }
.stat-value {
  font-size: clamp(2rem, 5vw, 3rem);
  font-weight: 700;
  line-height: 1;
  /* The digits stop jittering while the counter runs. */
  font-variant-numeric: tabular-nums;
}
.stat-label { color: var(--steel); font-size: 0.9rem; }

.pullquote { max-width: var(--measure); margin: 0; padding-left: 1.5rem; border-left: 3px solid var(--signal); }
.pullquote blockquote { margin: 0; font-size: 1.25rem; }
.pullquote figcaption { margin-top: 0.75rem; color: var(--steel); font-size: 0.9rem; }

.figure { margin: 0; }
.figure img { width: 100%; height: auto; border-radius: var(--radius); }
.figure figcaption { margin-top: 0.6rem; color: var(--steel); font-size: 0.9rem; }
.figure-left { max-width: var(--measure); }
.figure-center { margin-inline: auto; }

/* 16:9 without a wrapper hack -- aspect-ratio is supported everywhere this
   site targets. */
.embed iframe { width: 100%; aspect-ratio: 16 / 9; border: 0; border-radius: var(--radius); }

@media (max-width: 40rem) {
  /* The dropdown becomes an inline list: a floating panel on a narrow
     screen either overflows or covers the page. */
  .nav-menu { position: static; box-shadow: none; min-width: 0; }
  .stats { gap: 1.5rem; }
}
