/* nv-sync.css — desktop and mobile on one curve.
   Loaded last so it wins over page-level blocks. Every value here is fluid:
   there is no separate mobile design to drift out of step. */

/* ---- type scale ---------------------------------------------------------
   h1 measured 36px at both 1440 and 390. clamp ties them together: 27px on a
   small phone, 44px on a wide desktop, smooth between. */
.hero h1, .hero.sub h1 { font-size: clamp(1.7rem, 1.15rem + 2.3vw, 2.75rem);
  line-height: 1.15; }
.hero .lede, .hero.sub .lede { font-size: clamp(1rem, .95rem + .35vw, 1.19rem);
  line-height: 1.6; }
main h2 { font-size: clamp(1.35rem, 1.1rem + 1.05vw, 1.95rem); line-height: 1.25; }
main h3 { font-size: clamp(1.05rem, .98rem + .35vw, 1.24rem); }

/* ---- legibility floor ---------------------------------------------------
   Nothing readable drops below 12px on a phone. These are the classes built
   since the first legibility pass, which only covered book.css. */
@media (max-width: 767px) {
  .cat-pill, .cat-note, .cat-slot, .cat-open, .chip, .chip-n,
  .sv-pill, .sv-meta, .sv-slot, .sv-h, .sv-back, .sv-stepn, .sv-stept,
  .wk-tag, .wk-runs, .wk-job, .wk-tbl thead th,
  .cat-flabel, .cat-count, .cat-clear, .lv, .ev-tag, .pk-tag, .pf-tag,
  .v-eyebrow, .v-go, .eyebrow, figcaption {
    font-size: 12.5px;
    letter-spacing: .05em;
  }
  .cat-job, .sv-body li, .cat-body li, .intro, .wk-note { font-size: 15px; }
}

/* ---- tap targets --------------------------------------------------------
   44px is the accessibility floor for a touch target. Applied to the controls
   a finger actually hits, not to inline links inside prose. */
@media (pointer: coarse) {
  .chip, .ib, .pill, .tgl, .sv-step, .cat-clear, .nav-links a {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .chip, .ib, .pill, .sv-step { padding-top: 11px; padding-bottom: 11px; }
}

/* ---- hero imagery, both viewports ---------------------------------------
   Was display:none below 900px, which stripped the illustration from mobile
   on eight pages. It now sits above the copy at a size that earns its space.
   Desktop keeps the two-column arrangement. */
.hero.sub .hero-grid {
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  gap: clamp(24px, 3.5vw, 48px);
  align-items: center;
}
.hero-art { margin: 0; display: flex; justify-content: flex-end; }
.hero-art img { width: 100%; max-width: 420px; height: auto; display: block; }

@media (max-width: 900px) {
  .hero.sub .hero-grid { grid-template-columns: 1fr; }
  /* image first, then the words */
  .hero.sub .hero-grid > div { order: 2; }
  .hero-art { order: 1; display: flex; justify-content: flex-start;
    margin-bottom: 18px; }
  .hero-art img { max-width: min(260px, 62vw); }
}

/* ---- rhythm -------------------------------------------------------------
   Section padding on the same curve, so vertical spacing is proportional
   rather than a desktop value squeezed onto a phone. */
main > section { padding-top: clamp(30px, 1.4rem + 2.2vw, 60px);
  padding-bottom: clamp(34px, 1.6rem + 2.4vw, 68px); }
main > section:last-of-type { padding-bottom: clamp(48px, 2rem + 3vw, 96px); }
.hero.sub { padding-top: clamp(72px, 3.5rem + 3vw, 108px); }

/* ---- tables and wide content -------------------------------------------
   Wide content scrolls inside its own container. The page body must never
   scroll sideways. */
.wk-tbl { width: 100%; }
@media (max-width: 720px) {
  .wk-tbl, .wk-tbl tbody, .wk-tbl tr, .wk-tbl td { display: block; width: 100%; }
  .wk-tbl thead { display: none; }
}

/* ---- grids --------------------------------------------------------------
   One column on a phone. auto-fit with a 330px minimum would otherwise leave
   a card wider than the viewport at 390. */
@media (max-width: 620px) {
  .cat-grid, .v-grid, .sv-two, .sv-rel, .ct-what { grid-template-columns: 1fr; }
}


/* ---- nv-one-rhythm -------------------------------------------------------
   THE single source of vertical rhythm. Measured before this rule: nine
   different section padding pairs and five different hero heights across
   twenty pages, because each generation of page builder left its own values
   behind. Everything below is driven by two variables, so the whole site
   moves together.

   Loaded last on purpose. It is meant to win. */

:root {
  --nv-gap:      clamp(38px, 2.2rem + 2.4vw, 64px);   /* between sections */
  --nv-gap-last: clamp(56px, 3rem + 3vw, 96px);       /* before the footer */
  --nv-hero-top: clamp(76px, 4rem + 3vw, 112px);      /* nav clearance */
}

/* Hero: height follows content. No viewport-relative minimum, which was
   forcing 720px on pages holding 400px of content. */
.hero.sub,
main > header.hero {
  min-height: 0;
  padding-top: var(--nv-hero-top);
  padding-bottom: clamp(8px, 1vw, 18px);
}
.hero.sub .hero-grid { align-items: center; }

/* Sections: one pair of values everywhere, first and last cased separately so
   the page does not open or close on a dead band. */
main > section {
  padding-top: var(--nv-gap);
  padding-bottom: var(--nv-gap);
}
main > section:first-of-type { padding-top: clamp(20px, 1.2rem + 1vw, 30px); }
main > section:last-of-type  { padding-bottom: var(--nv-gap-last); }

/* The 39px band above the footer was a margin on the last child inside main.
   Content owns its spacing; the container does not add more. */
main > section:last-of-type > .wrap > *:last-child { margin-bottom: 0; }
main { padding-bottom: 0; }
footer.site { margin-top: 0; }

/* The home hero is the one page that earns a tall opening, but it should still
   fit the viewport rather than exceed it. */
body > main > header.hero:not(.sub) { min-height: min(88svh, 860px); }

@media (max-width: 760px) {
  :root {
    --nv-gap:      clamp(30px, 1.6rem + 2vw, 44px);
    --nv-gap-last: clamp(44px, 2.2rem + 2vw, 64px);
    --nv-hero-top: clamp(64px, 3.4rem + 2vw, 84px);
  }
  body > main > header.hero:not(.sub) { min-height: 0; }
}


/* ---- nv-final-trim ----------------------------------------------------------
   The 39px band above the footer was the bottom margin of the last paragraph
   inside the final section. Section padding sits outside it, so the margin
   showed through as an extra gap on every page. */
main > section:last-of-type > .wrap > *:last-child,
main > section:last-of-type > .wrap > *:last-child > *:last-child {
  margin-bottom: 0;
}

/* Atlas was the only page without the shared backdrop, so it did not read as
   the same site. Its own fixed layers stay beneath; this sits behind them. */
body > .sheet-ground { z-index: 0; }


/* ---- nv-llm-tag-fixed ---------------------------------------------------
   The tag sits between main and footer in the document. Where its
   position:fixed did not win, it stayed in normal flow and pushed the footer
   down by its own height: the 39px band measured on every page.
   Declared here, in the file that loads last, so it is fixed everywhere. */
.llm-tag {
  position: fixed;
  right: 22px;
  bottom: 82px;
  z-index: 79;
}
@media (max-width: 640px) {
  .llm-tag { right: 14px; left: 14px; bottom: 74px; }
}




/* ---- nv-floating-widgets -------------------------------------------------
   Both floating widgets sit between the footer and the scripts in the
   document. Without position:fixed they land in normal flow below the footer
   and add their own height to the page: measured 51px for the Atlas launcher
   on every page. Declared last so nothing can put them back in flow. */
#atlas-launcher {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 80;
}
.llm-tag {
  position: fixed;
  right: 22px;
  bottom: 84px;
  z-index: 79;
}
@media (max-width: 640px) {
  #atlas-launcher { right: 14px; bottom: calc(14px + env(safe-area-inset-bottom)); }
  .llm-tag { right: 14px; left: 14px; bottom: calc(76px + env(safe-area-inset-bottom)); }
}


/* ---- nv-no-stray-linebox -----------------------------------------------------
   Blank lines between body-level elements become a text node, and body has a
   line-height, so they render as an empty line box. That was the 39px band
   measured above the footer on every page. Zero line-height on body, restored
   on the elements that hold text, so stray whitespace cannot make space. */
body { line-height: 0; }
body > nav.site,
body > main,
body > footer.site,
body > .llm-tag,
body > aside,
body > dialog { line-height: 1.5; }


/* ---- nv-copyout-widget ------------------------------------------------
   The Copy Out pill. Matches the Atlas launcher in height, radius and weight
   so the two read as a pair, and sits directly above it.

   These live here rather than in a page-level block because the generator
   that rebuilds the widget also strips inline styles, which left the button
   completely unstyled: 94x112 and wrapping, with a 1052px menu. */
.llm-tag {
  position: fixed;
  right: 22px;
  bottom: 84px;
  z-index: 79;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
  width: auto;
}
.llm-btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  white-space: nowrap;
  cursor: pointer;
  padding: 13px 20px;
  border-radius: 999px;
  border: 1px solid var(--rule);
  background: var(--bg-elev, rgba(10, 14, 22, .94));
  color: var(--body);
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: .07em;
  text-transform: uppercase;
  line-height: 1;
  backdrop-filter: blur(8px);
  transition: border-color .18s, color .18s, transform .18s;
}
.llm-btn:hover {
  border-color: var(--accent-2);
  color: var(--white);
  transform: translateY(-2px);
}
.llm-btn svg {
  width: 15px; height: 15px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}

.llm-menu {
  width: 330px;
  max-width: calc(100vw - 44px);
  padding: 16px;
  border-radius: 16px;
  border: 1px solid var(--rule);
  background: var(--bg-elev, rgba(10, 14, 22, .98));
  backdrop-filter: blur(14px);
  box-shadow: 0 24px 60px -18px rgba(0, 0, 0, .8);
  text-align: left;
}
.llm-menu[hidden] { display: none; }
.llm-head {
  margin: 0 0 8px; font-family: var(--mono); font-size: 10.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--dim);
}
.llm-blurb { margin: 0 0 13px; font-size: 13px; line-height: 1.6; color: var(--body); }
.llm-item {
  display: block; width: 100%; text-align: left; cursor: pointer;
  padding: 12px 13px; margin: 0 0 7px; border-radius: 11px;
  border: 1px solid var(--rule); background: transparent; font: inherit;
  transition: border-color .16s, background .16s;
}
.llm-item:hover { border-color: var(--accent-2); background: rgba(127,127,127,.08); }
.llm-item.copied { border-color: var(--accent-2); background: rgba(45,111,217,.14); }
.llm-t { display: block; font-size: 14.5px; color: var(--white); margin-bottom: 3px; }
.llm-d { display: block; font-size: 12.5px; line-height: 1.5; color: var(--dim); }
.llm-item.copied .llm-t::after { content: " — copied"; color: var(--accent-2); }
.llm-foot { margin: 9px 0 0; font-size: 12px; line-height: 1.5; color: var(--dim); }
.llm-count { margin: 7px 0 0; font-family: var(--mono); font-size: 11.5px; color: var(--accent-2); }
.llm-count[hidden] { display: none; }

@media (max-width: 640px) {
  .llm-tag { right: 14px; bottom: 76px; }
  .llm-menu { width: min(330px, calc(100vw - 28px)); }
}


/* ---- nv-floor-final -----------------------------------------------------
   Classes added after the first legibility pass and so never covered:
   .ppl-meta, .llm-head, and the numeric label in the service pager. The last
   selector is a sweep so a component added later inherits the floor instead of
   needing another pass. */
@media (max-width: 767px) {
  .ppl-meta, .llm-head, .llm-foot, .llm-count, .llm-blurb,
  .sv-stepn, .layer-n, .q-n, .q-tag, .wk-n {
    font-size: 12.5px !important;
  }
  .ppl span, .llm-menu span, .llm-menu p,
  .sv-pager span, .layers span, .cat-bar span {
    font-size: max(12px, 1em) !important;
  }
}
