/* SIGNAL — shared foundation for every surface (app.html, index.html,
   about.html, 404.html, costs/*, guides/*). Holds the tokens, reset, type
   scale, masthead/brand, and control (.act/.btn/.micro/.g/.a/.r) rules that
   used to be copied — and drifting — across signal-app.css, signal-
   landing.css and costs.css.

   Load this FIRST, before the page's own stylesheet. Page sheets must NOT
   redeclare :root tokens or the rules below — extend them (a page-specific
   addendum to .micro, a mobile override of .brand) but don't restate them.

   Winners, where the three files disagreed (Task 4, design-audit-2026-09):
   - tokens/controls: the APP's values, since parents spend their time
     there. --ink-raise is #242B32 (was #111713 in signal-landing.css, an
     unused/dead token there, and missing from costs.css entirely) —
     docs/design-system.md updated to match.
   - masthead (.mast/.brand): the content-page (costs.css) metrics, since
     that surface carries 430 of the site's pages. signal-landing.css's
     .mast/.brand rules were unused dead code (index.html's real header is
     .site-nav/.site-brand, styled separately, further down that file) so
     this only visibly changes app.html's header — see docs/design-system.md
     and the Task 4 report for the before/after measurements.
   Full diff table and rationale: see the Task 4 report. */

:root {
  --ink: #0B0F12;
  --ink-raise: #242B32; /* one clear lightness step above --field (#12161B) and --field-line (#212730) — was #14171A, only 1.01:1 against --field, so the open panel didn't read as separate from the collapsed rows below it. This is 1.31:1: a genuine raised-panel step, not a new material (--field-line already uses this exact lightness as a hairline; here it's a fill). No color cast either way. */
  --field: #12161B;      /* C1 neutral slate — no green cast; green stays accent-only */
  --field-line: #212730;
  --line: #1C2420;
  --line-soft: #151B17;
  --text: #F4F6F5;
  --text-dim: #8A9490;
  --text-faint: #78827E; /* raised from #5C6662: 3.24:1 failed AA; 4.86:1 on ink, 4.58:1 on field, hierarchy vs --text-dim preserved */
  --green: #00D977;
  --green-ink: #04170D;
  --amber: #E8A33D;
  --red: #F25C3F;
  --display: "Archivo", sans-serif;
  /* The Signal panel edge (Jason, Sep 10 2026, chosen from seven rendered
     border treatments): painted in the border box behind a panel's own
     fill — green at the very top, dissolving down the sides, no line at
     the bottom. Every titled panel on the site uses it with a soft radius;
     the old 1px box with a green top rule is retired. */
  --panel-edge: linear-gradient(180deg, rgba(0, 217, 119, 0.6) 0, #2A323C 8%, rgba(42, 50, 60, 0) 62%);
  --body: "Inter", sans-serif;
  --fs-xs: 11px;
  --fs-sm: 12.5px;
  --fs-base: 14px;
  --fs-md: 15px;
  --fs-lg: 17px;
  --fs-xl: 19px;
  --fs-2xl: 24px;
}

/* ---------- reset ---------- */
* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  background: var(--ink);
  color: var(--text);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
button { background: none; border: 0; color: inherit; font: inherit; cursor: pointer; }

/* ---------- type ---------- */
.h-display {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(38px, 6vw, 62px); line-height: 1.05; letter-spacing: -0.03em;
}
.h-display em { font-style: normal; color: var(--green); }
h2.h-sec {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(26px, 3.6vw, 33px); line-height: 1.15; letter-spacing: -0.02em;
}
h2.h-sec em { font-style: normal; color: var(--green); }
h3 {
  font-family: var(--display); font-weight: 500;
  font-size: 20px; line-height: 1.3; letter-spacing: -0.01em;
}
h3 em { font-style: normal; color: var(--green); }
.lede { font-size: 16px; color: var(--text-dim); max-width: 58ch; }
.micro {
  font-family: var(--body); font-weight: 600; font-size: 11px;
  letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-dim);
}
.g { color: var(--green); }
.a { color: var(--amber); }
.r { color: var(--red); }

/* ---------- masthead / brand (costs.css metrics — see file header) ---------- */
.mast {
  display: flex; justify-content: space-between; align-items: center;
  padding: 20px 0; border-bottom: 1px solid var(--line); margin-bottom: 34px;
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand .mark { display: block; flex: 0 0 auto; }
.brand b { font-family: var(--display); font-weight: 700; font-size: 17px; letter-spacing: -0.01em; }
.mast nav { display: flex; align-items: center; gap: 26px; }
.mast nav a { font-size: 14px; color: var(--text-dim); }
.mast nav a:hover { color: var(--text); }
.mast nav a.btn { padding: 9px 16px; color: var(--green-ink); }
.mast nav a.btn:hover { color: var(--green-ink); }

/* ---------- site header (every public page; the app's own .mast is a
   <div> and carries no .site-mast, so none of this reaches it) ----------
   Markup: scripts/lib/site-header.mjs. Phone behaviour: site-nav.js.
   Brand left; the page's nav items and one green action right, evenly
   spaced by a single 26px gap that also separates nav from the action. */
.site-mast { justify-content: flex-start; gap: 26px; }
.site-mast nav { margin-left: auto; }
.site-mast nav button { font-size: 14px; color: var(--text-dim); }
.site-mast nav button:hover { color: var(--text); }
.site-mast nav [aria-current="page"] { color: var(--text); }
.site-mast .menu-toggle { display: none; }
/* Only Start free → reads green in the phone header — the toggle stays a
   quiet control (.act.dim), lighting to --text on hover/focus/expanded
   rather than the .act.dim default of green. */
.site-mast .menu-toggle.dim:hover,
.site-mast .menu-toggle.dim:focus-visible,
.site-mast .menu-toggle.dim[aria-expanded="true"] { color: var(--text); }

@media (max-width: 680px) {
  /* The row can't hold brand + three links + the action in 375px, so the
     links drop behind a text Menu — a word, not a hamburger glyph: these
     readers are parents in their 40s-50s and a label beats an icon. */
  .site-mast { flex-wrap: wrap; gap: 0 18px; }
  .site-mast .menu-toggle { display: inline-block; order: 2; margin-left: auto; }
  .site-mast .mast-cta { order: 3; }
  .site-mast nav {
    order: 4; flex-basis: 100%; margin-left: 0; display: none;
    flex-direction: column; align-items: stretch; gap: 0;
    margin-top: 16px;
  }
  /* nav only reappears via .menu-open, which site-nav.js toggles on click —
     so on a page where that script fails to load or run, the Guides/Costs/
     About links stay hidden behind Menu with no way to open them. Accepted
     trade-off: the brand link (home) and the green "Start free" CTA are
     both outside this nav and stay reachable either way, so the page never
     goes fully dead, only harder to navigate site-wide. */
  .site-mast.menu-open nav { display: flex; }
  /* Every row carries its own top hairline — including the first, so the
     rows are exactly equal height rather than 1px short at the top. */
  .site-mast nav a,
  .site-mast nav button {
    display: block; width: 100%; padding: 12px 0; text-align: left;
    border-top: 1px solid var(--line-soft);
  }
}

/* ---------- controls ---------- */
.btn {
  display: inline-block; background: var(--green); color: var(--green-ink);
  font-family: var(--display); font-weight: 500; font-size: 14px;
  padding: 12px 22px; border-radius: 14px; letter-spacing: 0.01em;
}
.btn:hover { filter: brightness(1.06); }
.act { color: var(--green); font-size: var(--fs-base); }
.act:hover { text-decoration: underline; text-underline-offset: 3px; }
.act.dim { color: var(--text-dim); }
.act.dim:hover { color: var(--green); }

/* ---------- focus / selection ---------- */
:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
::selection { background: var(--green); color: var(--green-ink); }

/* ---------- fade-in (app + landing) ---------- */
.fade { opacity: 0; transform: translateY(6px); animation: rise 0.6s ease forwards; }
.fade.d1 { animation-delay: 0.12s; }
.fade.d2 { animation-delay: 0.24s; }
.fade.d3 { animation-delay: 0.36s; }
@keyframes rise { to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .fade { animation: none; opacity: 1; transform: none; }
}

/* Touch hit areas: only the piece identical across all three surfaces.
   Each page's own halo overlays (a.act::after etc) differ in selector list
   and inset and stay page-specific — see the Task 4 report. */
@media (pointer: coarse) {
  /* overlays extend a few px past right-edge controls; clip (not hidden) so no new scroll container */
  html { overflow-x: clip; }
}
