/*
 * Bittner AI — intake automation for solo and small law firms.
 *
 * One stylesheet, no external assets, no web fonts. The reader is a managing
 * partner between hearings, often on a phone, and the page has to look like a
 * document rather than a pitch deck.
 *
 * Palette and type carried over from the business plan: paper ground, one
 * muted green, a serif for display and a system sans for reading. Newsreader
 * and IBM Plex are the intended faces; the stacks below fall back to Georgia
 * and system-ui, which is what the plan's own CSS does. Loading them from a
 * font host would be the only external request on the site, so we don't.
 */

/* ---------- display face ----------
 * Newsreader, self-hosted so the site still makes zero external requests.
 * Variable, subset to latin + the punctuation this site actually sets, and
 * the axes clipped to the range in use (wght 500-650, opsz 18-56) — 58KB
 * rather than the 132KB Google serves.
 *
 * The second @font-face is not a font: it is Georgia re-declared with
 * Newsreader's metrics, so the fallback occupies the same space and swapping
 * costs no layout shift.
 */
@font-face {
  font-family: Newsreader;
  src: url("fonts/newsreader-var.9ec3e78c.woff2") format("woff2-variations");
  font-weight: 500 650;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Newsreader Fallback";
  src: local("Georgia"), local("Times New Roman"), local("Times");
  size-adjust: 88.48%;
  ascent-override: 83.07%;
  descent-override: 29.95%;
  line-gap-override: 0%;
}

:root {
  color-scheme: light dark;

  --paper:      #F6F8F7;
  --surface:    #FFFFFF;
  --surface-2:  #EDF1EF;
  --ink:        #121D1A;
  --ink-2:      #4E5B57;
  --ink-3:      #616C67;
  --rule:       #B9C4BF;
  --rule-soft:  #DCE3E0;
  --field:      #7A8984;
  --accent:     #0E5A4E;
  --accent-ink: #0B453C;
  --accent-soft:#E0EDE8;
  --on-accent:  #FFFFFF;
  --warn:       #8A5C13;
  --warn-soft:  #F5EBD9;

  --f-display: Newsreader, "Newsreader Fallback", Georgia, "Times New Roman", serif;
  --f-body:    system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --f-mono:    ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --wrap: 72rem;
  --measure: 68ch;
  --pad: 1.5rem;
  --radius: 4px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:      #0D1412;
    --surface:    #131C19;
    --surface-2:  #1A2521;
    --ink:        #E7EDEA;
    --ink-2:      #A0AEA9;
    --ink-3:      #8A9893;
    --rule:       #354742;
    --rule-soft:  #232F2B;
    --field:      #5E726B;
    --accent:     #52C0A8;
    --accent-ink: #7FD4C0;
    --accent-soft:#15302A;
    --on-accent:  #08211C;
    --warn:       #D9A64A;
    --warn-soft:  #2C2416;
  }
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (min-width: 48rem) { html { scroll-padding-top: 5rem; } }

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--f-body);
  font-size: 1.0625rem;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ---------- type ---------- */

h1, h2, h3 {
  font-family: var(--f-display);
  font-weight: 500;
  margin: 0 0 0.5em;
  text-wrap: balance;
}

/* Display type is the loudest element on a page with no photography, so it
   carries the weight instead: larger, tighter tracking, tighter leading. */
h1 {
  font-size: clamp(2.5rem, 7vw, 4.5rem);
  line-height: 0.99;
  letter-spacing: -0.032em;
}
h2 {
  font-size: clamp(1.85rem, 4.4vw, 2.9rem);
  line-height: 1.06;
  letter-spacing: -0.026em;
}
h3 {
  font-size: 1.22rem;
  font-weight: 600;
  line-height: 1.28;
  letter-spacing: -0.008em;
}

.side-head {
  font-family: var(--f-body);
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.08em;
  line-height: 1.35;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 0.7rem;
}

p, ul, ol { margin: 0 0 1.15rem; }

a { color: var(--accent); text-underline-offset: 2px; }
a:hover { color: var(--accent-ink); }

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

strong { font-weight: 650; }

code, .mono { font-family: var(--f-mono); font-size: 0.92em; }

.measure { max-width: var(--measure); }
.lede {
  font-size: clamp(1.14rem, 2.1vw, 1.4rem);
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 52ch;
  letter-spacing: -0.008em;
}
.lead-in { color: var(--ink-2); }
.fine  { font-size: 0.9rem; color: var(--ink-3); }
.mb0 { margin-bottom: 0; }

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

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
  padding: 0.7rem 1rem;
  z-index: 100;
}
.skip:focus { left: 0; }

/* ---------- masthead ---------- */

.site-head {
  border-bottom: 1px solid var(--rule);
  background: var(--surface);
  /* Positioned for the accent rule drawn by ::after; the media query below
     promotes this to sticky. Do not re-declare position later in the file —
     a later declaration silently wins and the header quietly stops sticking. */
  position: relative;
}

/* Sticky everywhere the bar is one row tall. On a phone that is only true once
   the links are behind the toggle — .has-toggle is set by the script, so a
   no-JS visitor keeps the taller, non-sticky header rather than losing a third
   of the screen to a pinned one. */
@media (min-width: 48rem) {
  .site-head { position: sticky; top: 0; z-index: 50; }
}
@media (max-width: 47.99rem) {
  .site-head.has-toggle { position: sticky; top: 0; z-index: 50; }
}
@supports (backdrop-filter: blur(1px)) {
  @media (min-width: 48rem) {
    .site-head {
      background: color-mix(in srgb, var(--surface) 88%, transparent);
      backdrop-filter: saturate(1.4) blur(12px);
    }
  }
  @media (max-width: 47.99rem) {
    .site-head.has-toggle {
      background: color-mix(in srgb, var(--surface) 92%, transparent);
      backdrop-filter: saturate(1.4) blur(12px);
    }
  }
}
.site-head .wrap {
  display: flex;
  align-items: center;
  gap: 0.6rem 2.25rem;
  flex-wrap: wrap;
  padding-block: 0.95rem;
}

.brand {
  font-family: var(--f-display);
  font-size: 1.3rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
  text-decoration: none;
  margin-right: auto;
}
.brand:hover { color: var(--ink); }
.brand em { font-style: normal; color: var(--accent); }

.nav {
  display: flex;
  align-items: center;
  gap: 0.3rem 1.75rem;
  flex-wrap: wrap;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.nav a {
  color: var(--ink-2);
  text-decoration: none;
  padding-block: 0.55rem;
  border-bottom: 1px solid transparent;
}
.nav a:hover { color: var(--ink); border-bottom-color: var(--rule); }
.nav a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--accent); }

/* ---------- buttons ---------- */

.btn {
  display: inline-block;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.3;
  padding: 0.95rem 1.85rem;
  border: 1px solid var(--accent);
  border-radius: 999px;
  text-decoration: none;
  min-height: 50px;
  letter-spacing: -0.005em;
}
.btn:hover, .btn:focus-visible {
  background: var(--accent-ink);
  border-color: var(--accent-ink);
  color: var(--on-accent);
}

.btn-quiet {
  background: transparent;
  color: var(--ink);
  border-color: var(--field);
}
.btn-quiet:hover, .btn-quiet:focus-visible {
  background: var(--surface-2);
  border-color: var(--ink-3);
  color: var(--ink);
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  align-items: center;
  margin: 2.5rem 0 0.6rem;
}
.cta-note { font-size: 0.9rem; color: var(--ink-3); margin: 0.35rem 0 0; }

/* ---------- sections ---------- */

section { padding-block: clamp(4rem, 9vw, 8rem); }
.hero {
  padding-block: clamp(4.5rem, 11vw, 9rem);
  background: var(--surface);
  border-bottom: 1px solid var(--rule);
}
.alt { background: var(--surface); border-block: 1px solid var(--rule); }

.eyebrow {
  font-family: var(--f-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 1.5rem;
}

/* Numbered section marker, like the plan's own contents. */
.marker {
  font-family: var(--f-mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
  display: block;
  margin-bottom: 1.35rem;
  padding-bottom: 1.15rem;
  border-bottom: 1px solid var(--rule);
}

/* ---------- grid + cards ---------- */

.grid {
  display: grid;
  gap: clamp(2rem, 4vw, 3.25rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); }

/* No panel, no fill, no shadow. A single rule across the top sets the column
   and whitespace does the rest — the page reads as one surface rather than a
   tray of boxes. */
.card {
  border-top: 2px solid var(--ink);
  padding: 1.15rem 0 0;
}
.card h3 { margin-bottom: 0.5rem; }
.card p { color: var(--ink-2); }
.card p:last-child { margin-bottom: 0; }

/* ---------- the chain diagram ---------- */

.chain {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: step;
  border-top: 1px solid var(--rule);
}
.chain > li {
  counter-increment: step;
  display: grid;
  grid-template-columns: 3.25rem 1fr;
  gap: 0 1.5rem;
  padding: 2rem 0;
  border-bottom: 1px solid var(--rule);
}
.chain > li::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--f-mono);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  color: var(--accent);
  padding-top: 0.4rem;
}
.chain h3 { margin-bottom: 0.3rem; }
.chain p { margin-bottom: 0; color: var(--ink-2); }
.chain .tool {
  font-family: var(--f-mono);
  font-size: 0.76rem;
  color: var(--ink-3);
  display: block;
  margin-top: 0.4rem;
}

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

.ticks, .nots { list-style: none; padding: 0; margin: 0 0 1.15rem; }
.ticks li, .nots li {
  position: relative;
  padding-left: 1.6rem;
  margin-bottom: 0.6rem;
  color: var(--ink-2);
}
.ticks li strong, .nots li strong { color: var(--ink); }
.ticks li::before {
  content: "";
  position: absolute;
  left: 0.15rem;
  top: 0.52em;
  width: 0.38rem;
  height: 0.72rem;
  border: solid var(--accent);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) translateY(-50%);
}
.nots li::before {
  content: "\00D7";
  position: absolute;
  left: 0.2rem;
  top: -0.05em;
  color: var(--ink-3);
  font-size: 1.05rem;
}

/* ---------- callouts ---------- */

.note {
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
  padding: 1.15rem 1.35rem;
  border-radius: 0 var(--radius) var(--radius) 0;
  margin: 1.75rem 0;
}
.note p:last-child { margin-bottom: 0; }
.note .side-head { color: var(--accent-ink); }

.note-warn { border-left-color: var(--warn); background: var(--warn-soft); }
.note-warn .side-head { color: var(--warn); }

/* ---------- tier panels ---------- */

.tier {
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--surface);
  padding: clamp(1.4rem, 3.5vw, 2rem);
  margin-bottom: 1.25rem;
}
.tier-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 1rem;
  border-bottom: 1px solid var(--rule-soft);
  padding-bottom: 0.9rem;
  margin-bottom: 1.15rem;
}
.tier-head h3 { margin: 0; font-size: 1.35rem; }
.status {
  font-family: var(--f-mono);
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  padding: 0.25rem 0.6rem;
  border-radius: 99px;
  border: 1px solid var(--accent);
  color: var(--accent-ink);
  background: var(--accent-soft);
  white-space: nowrap;
}
.status-soon {
  border-color: var(--warn);
  color: var(--warn);
  background: var(--warn-soft);
}

/* ---------- definition table ---------- */

.facts {
  display: grid;
  grid-template-columns: minmax(8rem, auto) 1fr;
  gap: 0.55rem 1.5rem;
  margin: 0 0 1.15rem;
  font-size: 0.97rem;
}
.facts dt { font-weight: 600; color: var(--ink-3); }
.facts dd {
  margin: 0;
  color: var(--ink-2);
  /* Grid items default to min-width:auto, so an unbreakable string such as an
     email address would push the track — and the page — past the viewport. */
  min-width: 0;
  overflow-wrap: break-word;
}

/* A 128px label column is not worth having on a phone. */
@media (max-width: 30rem) {
  .facts { grid-template-columns: 1fr; gap: 0.15rem; }
  .facts dd { margin-bottom: 0.55rem; }
  .facts dd:last-child { margin-bottom: 0; }
}

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

details { border-bottom: 1px solid var(--rule); padding: 0.9rem 0; }
details summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 1.05rem;
  list-style: none;
  display: flex;
  gap: 0.75rem;
  align-items: baseline;
  min-height: 44px;
  padding-block: 0.3rem;
}
details summary::-webkit-details-marker { display: none; }
details summary::before {
  content: "+";
  font-family: var(--f-mono);
  color: var(--accent);
  flex: none;
  width: 0.8rem;
}
details[open] summary::before { content: "\2212"; }
details p { margin: 0.6rem 0 0 1.55rem; color: var(--ink-2); }

/* ---------- closing band ---------- */

.band { background: var(--surface); border-top: 1px solid var(--rule); }

/* ---------- contact form ---------- */

.contact-form { max-width: 34rem; margin-top: 1.75rem; }
.contact-form .field { margin-bottom: 1rem; }
.contact-form label {
  display: block;
  font-weight: 600;
  font-size: 0.95rem;
  margin-bottom: 0.35rem;
}
.contact-form input,
.contact-form textarea {
  width: 100%;
  font: inherit;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--field);
  border-radius: var(--radius);
  padding: 0.7rem 0.8rem;
  min-height: 46px;
}
.contact-form input::placeholder,
.contact-form textarea::placeholder { color: var(--ink-3); }
.contact-form textarea { resize: vertical; }
.contact-form input:focus-visible,
.contact-form textarea:focus-visible {
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.contact-form .field-row {
  display: grid;
  gap: 0 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
}
.contact-form button { margin-top: 0.35rem; cursor: pointer; }

/* Honeypot: off-screen rather than display:none, which bots detect. */
.contact-form .hp {
  position: absolute;
  left: -5000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---------- footer ---------- */

.site-foot {
  border-top: 1px solid var(--rule);
  background: var(--surface);
  padding-block: 2.5rem;
  font-size: 0.93rem;
  color: var(--ink-2);
}
.site-foot .cols {
  display: grid;
  gap: 1.75rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}
.site-foot ul { list-style: none; padding: 0; margin: 0; }
.site-foot li { margin-bottom: 0.4rem; }
.site-foot a { color: var(--ink-2); text-decoration: none; }
.site-foot a:hover { color: var(--accent); text-decoration: underline; }
.colophon {
  margin: 2rem 0 0;
  padding-top: 1.35rem;
  border-top: 1px solid var(--rule-soft);
  color: var(--ink-3);
  font-size: 0.85rem;
}

.spaced { margin-top: 2.75rem; }

/* ==========================================================================
   Motion and depth
   --------------------------------------------------------------------------
   Everything below is progressive enhancement. No JavaScript, no library.
   Two rules hold throughout:

   1. Nothing here may hide content. The scroll reveals live inside an
      @supports block, so a browser without view() timelines simply renders
      the page — it never gets an opacity:0 element it cannot animate back.
   2. Every transition and animation is off under prefers-reduced-motion.
   ========================================================================== */

/* ---------- ambient accent wash ---------- */

/* One soft field of the brand green behind the hero. No new colour is
   introduced — it is --accent at low alpha, so it follows the theme. */
.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
}
.hero::before {
  content: "";
  position: absolute;
  inset: -40% -15% auto -15%;
  height: 170%;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(58% 52% at 20% 8%,
      color-mix(in srgb, var(--accent) 13%, transparent), transparent 70%),
    radial-gradient(42% 44% at 92% 2%,
      color-mix(in srgb, var(--accent) 8%, transparent), transparent 72%);
}

/* A hairline of accent under the masthead, so the header reads as a rule
   rather than a border. */
.site-head::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: linear-gradient(90deg,
    var(--accent), color-mix(in srgb, var(--accent) 22%, transparent) 38%, transparent 72%);
}

/* ---------- micro-interactions ---------- */

.card, .tier {
  transition: border-color 180ms ease, box-shadow 180ms ease;
}

@media (hover: hover) {
  .card:hover { border-top-color: var(--accent); }
  .tier:hover {
    border-color: color-mix(in srgb, var(--accent) 42%, var(--rule));
    box-shadow: 0 14px 30px -18px color-mix(in srgb, var(--accent) 45%, transparent);
  }
}

.btn {
  transition:
    background-color 160ms ease,
    border-color     160ms ease,
    box-shadow       160ms ease,
    transform        110ms ease;
}
.btn:hover { box-shadow: 0 8px 20px -12px color-mix(in srgb, var(--accent) 70%, transparent); }
.btn:active { transform: translateY(1px); }

/* Chain rows: the step number picks up weight as you read down it. */
.chain > li { transition: background-color 160ms ease; }
.chain > li::before { transition: color 160ms ease, transform 160ms ease; }
@media (hover: hover) {
  .chain > li:hover { background: color-mix(in srgb, var(--accent) 4%, transparent); }
  .chain > li:hover::before { color: var(--accent-ink); transform: translateX(2px); }
}

/* Nav: the underline grows from the left rather than blinking on. */
.nav a { position: relative; }
.nav a,
.nav a:hover,
.nav a[aria-current="page"] { border-bottom-color: transparent; }
.nav a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  height: 1px;
  width: 100%;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 180ms ease;
}
.nav a:hover::after,
.nav a[aria-current="page"]::after { transform: scaleX(1); }

.status { transition: border-color 160ms ease, background-color 160ms ease; }

.contact-form input,
.contact-form textarea { transition: border-color 140ms ease, box-shadow 140ms ease; }
.contact-form input:hover,
.contact-form textarea:hover { border-color: color-mix(in srgb, var(--accent) 50%, var(--field)); }

/* ---------- scroll reveals ---------- */

/* Scroll-driven animations, CSS only. Wrapped in @supports so that a browser
   without view() timelines never sees the opacity:0 start state. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .reveal,
    .card,
    .tier,
    .spec,
    .chain > li {
      animation: reveal-in linear both;
      animation-timeline: view();
      /* The range must END somewhere every element can actually reach. A range
         ending in the `cover` phase is not reachable for anything near the foot
         of the page — there is no scroll left to complete it — and the element
         stays stranded at opacity 0. `entry` completes as soon as the element
         is fully in the viewport, which is reachable for all of them. */
      animation-range: entry 0% entry 55%;
    }
    @keyframes reveal-in {
      from { opacity: 0; transform: translateY(16px); }
      to   { opacity: 1; transform: none; }
    }
  }
}

/* Printing has no scroll timeline to drive, so opt out of the reveal entirely
   rather than print a page of invisible boxes. */
@media print {
  .reveal, .card, .tier, .spec, .chain > li {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ---------- the reduced-motion contract ---------- */

@media (prefers-reduced-motion: reduce) {
  .card, .tier, .btn, .chain > li, .chain > li::before, .nav a::after,
  .status, details summary::before, .contact-form input, .contact-form textarea {
    transition: none;
  }
  .btn:active { transform: none; }
  .nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }
  .reveal, .card, .tier, .spec, .chain > li {
    animation: none; opacity: 1; transform: none;
  }
}

/* ==========================================================================
   Hero diagram
   --------------------------------------------------------------------------
   Inline SVG rather than an image: it is text at any zoom, it themes with the
   palette, it costs one request fewer than a PNG, and its aspect ratio is
   fixed by the viewBox so it cannot shift layout.
   ========================================================================== */

.hero-grid {
  display: grid;
  gap: clamp(2rem, 5vw, 3.5rem);
  grid-template-columns: 1fr;
  align-items: start;
}
.hero-copy > h1 { max-width: 18ch; }

.hero-fig { margin: 0; justify-self: start; }
.chain-dia {
  width: 100%;
  max-width: 252px;
  height: auto;
  display: block;
}

@media (min-width: 62rem) {
  .hero-grid { grid-template-columns: minmax(0, 1.25fr) auto; }
  .hero-fig { justify-self: end; }
  .chain-dia { max-width: 252px; }
}

.dia-spine path,
.dia-fan path {
  fill: none;
  stroke: var(--rule);
  stroke-width: 1.5;
  stroke-linecap: round;
}
.dia-fan path { stroke: color-mix(in srgb, var(--accent) 50%, transparent); }
.dia-dot circle { fill: var(--paper); stroke: var(--accent); stroke-width: 2; }
.dia-dot .dia-dot-end { fill: var(--accent); }
.hero .dia-dot circle { fill: var(--surface); }
.hero .dia-dot .dia-dot-end { fill: var(--accent); }

.dia-label text {
  font-family: var(--f-body);
  font-size: 12px;
  font-weight: 650;
  fill: var(--ink);
}
.dia-sub text {
  font-family: var(--f-mono);
  font-size: 8px;
  fill: var(--ink-3);
}

/* A single accent stroke travelling the spine. Decorative only — the diagram
   reads identically without it. */
.dia-pulse {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linecap: round;
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .dia-pulse {
    stroke-dasharray: 46 700;
    animation: dia-travel 4.6s ease-in-out infinite;
  }
  @keyframes dia-travel {
    0%        { stroke-dashoffset: 60;   opacity: 0; }
    12%       { opacity: 0.9; }
    78%       { opacity: 0.9; }
    88%, 100% { stroke-dashoffset: -420; opacity: 0; }
  }
}

/* ==========================================================================
   Specification tiles
   --------------------------------------------------------------------------
   The figures here are structural facts about how the system is built — route
   count, field count, the number of ways it can report a cleared conflict
   (zero). They are not performance metrics, because nothing is measured yet.
   Never put a result in this grid.
   ========================================================================== */

.spec-head { margin-top: 2.5rem; }

.specs {
  display: grid;
  gap: clamp(2rem, 4vw, 3.25rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  list-style: none;
  margin: 2.5rem 0 3rem;
  padding: 0;
}

.spec {
  border-top: 1px solid var(--rule);
  padding: 1.15rem 0 0;
  transition: border-color 180ms ease;
}

/* The numeral carries the panel. Nothing boxes it in. */
.spec-fig {
  font-family: var(--f-display);
  font-size: clamp(3.6rem, 7vw, 5rem);
  font-weight: 500;
  line-height: 0.9;
  letter-spacing: -0.04em;
  color: var(--accent);
  margin: 0 0 0.45rem;
  font-variant-numeric: lining-nums tabular-nums;
}

.spec-label {
  font-family: var(--f-body);
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.07em;
  line-height: 1.35;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 0.7rem;
}

.spec p:last-child { margin-bottom: 0; color: var(--ink-2); font-size: 0.97rem; }

@media (hover: hover) {
  .spec:hover { border-top-color: var(--accent); }
}

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

/* ==========================================================================
   Interactive sections
   --------------------------------------------------------------------------
   Every panel below is authored into the HTML and visible by default. The
   script hides all but one and reveals the picker. If it never runs, the
   section is a plain readable stack — which is also why it is crawlable.
   ========================================================================== */

/* ---------- picker ---------- */

.picker {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 2.5rem;
  padding: 0;
  list-style: none;
}
.picker button {
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--ink-2);
  background: transparent;
  border: 1px solid var(--field);
  border-radius: 999px;
  padding: 0.6rem 1.1rem;
  min-height: 44px;
  cursor: pointer;
  transition: background-color 140ms ease, color 140ms ease, border-color 140ms ease;
}
@media (hover: hover) {
  .picker button:hover { color: var(--ink); border-color: var(--ink); }
}
.picker button.is-on {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

/* Panels stack until the script switches the group to one-at-a-time. */
.panels > [data-panel] + [data-panel] { margin-top: 3.5rem; }
.panels.is-switched > [data-panel] + [data-panel] { margin-top: 0; }
.panels > [data-panel]:focus { outline: none; }

/* ---------- the workflow diptych ---------- */

.wf { display: grid; gap: clamp(2rem, 4vw, 3.5rem); }
@media (min-width: 54rem) { .wf { grid-template-columns: 1fr 1fr; } }

.wf-head {
  font-family: var(--f-mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin: 0 0 1.25rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--rule);
}
.wf-today .wf-head { color: var(--ink-3); }
.wf-with  .wf-head { color: var(--accent); border-bottom-color: var(--accent); }

.wf-steps { list-style: none; margin: 0; padding: 0; counter-reset: wfstep; }
.wf-steps li {
  counter-increment: wfstep;
  position: relative;
  padding: 0 0 1.15rem 2.15rem;
  font-size: 0.98rem;
  line-height: 1.45;
  color: var(--ink-2);
}
.wf-steps li::before {
  content: counter(wfstep);
  position: absolute;
  left: 0;
  top: 0.1em;
  font-family: var(--f-mono);
  font-size: 0.7rem;
  color: var(--ink-3);
}
/* The connector between steps, so the column reads as a sequence. */
.wf-steps li::after {
  content: "";
  position: absolute;
  left: 0.42rem;
  top: 1.5em;
  bottom: 0.35rem;
  width: 1px;
  background: var(--rule);
}
.wf-steps li:last-child { padding-bottom: 0; }
.wf-steps li:last-child::after { display: none; }

.wf-with .wf-steps li { color: var(--ink); }
.wf-with .wf-steps li::before { color: var(--accent); }
.wf-with .wf-steps li::after { background: color-mix(in srgb, var(--accent) 45%, transparent); }

/* The cost of a manual step, stated where it happens. */
.wf-steps .who {
  display: block;
  font-family: var(--f-mono);
  font-size: 0.72rem;
  color: var(--ink-3);
  margin-top: 0.2rem;
}
.wf-with .wf-steps .who { color: var(--accent); }

.wf-note {
  grid-column: 1 / -1;
  margin: 0.5rem 0 0;
  color: var(--ink-3);
  font-size: 0.9rem;
}

/* Stagger on selection. Delays are per-position because an inline style
   attribute would be refused by the CSP, and rightly so. */
@media (prefers-reduced-motion: no-preference) {
  .is-entering .wf-steps li { animation: step-in 320ms ease both; }
  .is-entering .wf-steps li:nth-child(1) { animation-delay: 0ms; }
  .is-entering .wf-steps li:nth-child(2) { animation-delay: 55ms; }
  .is-entering .wf-steps li:nth-child(3) { animation-delay: 110ms; }
  .is-entering .wf-steps li:nth-child(4) { animation-delay: 165ms; }
  .is-entering .wf-steps li:nth-child(5) { animation-delay: 220ms; }
  .is-entering .wf-steps li:nth-child(6) { animation-delay: 275ms; }
  .is-entering .wf-steps li:nth-child(7) { animation-delay: 330ms; }
  .is-entering .wf-steps li:nth-child(8) { animation-delay: 385ms; }
  .is-entering .wf-steps li:nth-child(9) { animation-delay: 440ms; }
  .is-entering .wf-steps li:nth-child(n+10) { animation-delay: 495ms; }
  @keyframes step-in {
    from { opacity: 0; transform: translateY(7px); }
    to   { opacity: 1; transform: none; }
  }
}

/* ---------- calculator ---------- */

.calc { margin: 2.5rem 0 0; }
.calc-grid {
  display: grid;
  gap: 1.25rem 1.75rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  margin-bottom: 2.5rem;
}
.calc-field label {
  display: block;
  font-size: 0.88rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
}
.calc-field input {
  width: 100%;
  font: inherit;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--field);
  border-radius: var(--radius);
  padding: 0.65rem 0.75rem;
  min-height: 46px;
}
.calc-field input:focus-visible {
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.calc-out {
  border-top: 2px solid var(--ink);
  padding-top: 1.35rem;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.75rem;
}
.calc-fig {
  font-family: var(--f-display);
  font-size: clamp(3.4rem, 8vw, 5.5rem);
  font-weight: 500;
  line-height: 0.9;
  letter-spacing: -0.04em;
  color: var(--accent);
  margin: 0;
  font-variant-numeric: lining-nums tabular-nums;
}
.calc-unit {
  font-family: var(--f-body);
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0;
}
.calc-note { margin: 1.15rem 0 0; color: var(--ink-2); max-width: 46ch; }

/* ---------- the five-stage centrepiece ---------- */

.stage-grid {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4.5rem);
  align-items: start;
}
@media (min-width: 54rem) {
  .stage-grid { grid-template-columns: auto minmax(0, 1fr); }
}
.stage-fig { margin: 0; justify-self: start; }
.stage-copy h3 { margin-top: 0; }
.stage-copy h3 + p { color: var(--ink-2); }
.stage-copy > h3 ~ h3 { margin-top: 2.25rem; }
.stage-copy p:last-child { margin-bottom: 0; }

/* The status pill sits inline with a panel heading. */
h3 .status { margin-left: 0.6rem; vertical-align: 0.18em; }


/* ---------- mobile navigation ---------- */

.navtoggle {
  display: none;
  align-items: center;
  gap: 0.55rem;
  font: inherit;
  font-size: 0.74rem;
  font-weight: 650;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--field);
  border-radius: 999px;
  padding: 0.5rem 0.95rem;
  min-height: 44px;
  cursor: pointer;
  margin-left: auto;
}
.navtoggle-bars {
  position: relative;
  width: 15px;
  height: 9px;
  flex: none;
}
.navtoggle-bars::before,
.navtoggle-bars::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1.5px;
  background: var(--ink);
  transition: transform 180ms ease, opacity 140ms ease;
}
.navtoggle-bars::before { top: 0; }
.navtoggle-bars::after  { bottom: 0; }
.nav-open .navtoggle-bars::before { transform: translateY(3.75px) rotate(45deg); }
.nav-open .navtoggle-bars::after  { transform: translateY(-3.75px) rotate(-45deg); }

@media (prefers-reduced-motion: reduce) {
  .navtoggle-bars::before, .navtoggle-bars::after { transition: none; }
}

/* Below the breakpoint, and only once the script has revealed the toggle, the
   links collapse behind it. Without .has-toggle nothing here applies and the
   nav renders as the plain wrapping list it has always been. */
@media (max-width: 47.99rem) {
  .site-head.has-toggle .navtoggle { display: inline-flex; }
  .site-head.has-toggle .brand { margin-right: 0; }
  .site-head.has-toggle .wrap { gap: 0; }
  .site-head.has-toggle .nav {
    display: none;
    width: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin-top: 0.85rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--rule);
  }
  .site-head.has-toggle.nav-open .nav { display: flex; }
  .site-head.has-toggle .nav a {
    padding-block: 0.95rem;
    font-size: 0.82rem;
  }
  .site-head.has-toggle .nav a::after { display: none; }
  .site-head.has-toggle .nav a[aria-current="page"] { color: var(--accent); }
}

/* ---------- footer legal links ---------- */

.legal-links {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0 1.15rem;
  margin-left: 0.35rem;
}
.legal-links a {
  color: var(--ink-3);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-color: var(--rule);
  /* The colophon runs at 0.85rem; these need a 44px target of their own
     without pushing the line apart on a phone. */
  padding-block: 0.72rem;
}
.legal-links a:hover { color: var(--accent); text-decoration-color: var(--accent); }
