/* ============================================================================
   PHASE 1 THEME  ·  DESIGN EXPERIMENT ONLY
   ----------------------------------------------------------------------------
   Loaded AFTER style.css, which it never edits. Remove the one <link> and the
   site is exactly as it was. Nothing here touches markup or JavaScript, so all
   1,467 lines of wizard.js keep working untouched: it writes the same class
   names, they just look different now.

   Scope is deliberately tokens, type, buttons and the two loudest surfaces.
   Restyling every component would quietly become the Phase 3 markup job.
   ========================================================================= */

:root {
  /* Near-monochrome with one restrained accent. The old palette put a
     saturated blue on large filled surfaces, which is the single strongest
     "generated template" cue. The blue survives, but it accents now. */
  --page:        #ffffff;
  --card:        #ffffff;
  --line:        rgba(13, 18, 20, .09);
  --line-strong: rgba(13, 18, 20, .16);
  --ink:         #0d1214;
  /* 2026-09-06 accessibility pass. Was #737d87, which is 4.19:1 on white and
     3.52:1 on --t-surface-3, so every hint, subhead and table detail on the
     site failed WCAG AA for body text. #606871 is 5.65:1 on white and 4.75:1
     on the darkest surface it is ever used on, so it clears AA everywhere.
     Web-accessibility demand letters are the most common legal action against
     a US consumer site by a wide margin, which is why this is a token change
     and not a backlog item. Ratios computed, not eyeballed. */
  --muted:       #606871;
  --accent:      #1b9de2;
  --accent-dark: #0d6b9c;
  --radius:      12px;
  --shadow:      0 1px 2px rgba(13, 18, 20, .04);

  /* Option D (owner call): the brand colour carries the action. The primary
     button is the deep end of the accent, not near-black, and the surfaces
     that stay dark are tinted toward it so they read as one family. The deep
     end matters: a SATURATED blue on a large filled surface is the strongest
     "generated template" cue there is, which is what the note above is about.
     #0d6b9c on white is 5.8:1, so white label text clears AA. */
  --cta:         #0d6b9c;
  --cta-hover:   #0a5a83;
  --surface-dark:#0e2231;

  /* Named here so the rules below read as decisions rather than magic values. */
  --t-ink-2:     #444e56;
  /* 2026-09-06 accessibility pass. Was #9aa3ac at 2.56:1 on white, which made
     the NON-AFFILIATION DISCLAIMER (.footer p) the least readable text on the
     site: the single most legally load-bearing sentence we publish, set in the
     one colour nobody could read. #616c77 is 5.36:1 on white, 4.51:1 on the
     darkest surface it appears on.
     ⚠️ The "faint" tier is no longer a CONTRAST step, and that is deliberate:
     four legible greys cannot fit between #0d1214 and white. Everything using
     this token separates itself by size, weight and letter-spacing instead
     (uppercase micro-labels, eyebrows), which is how those elements should
     have been distinguished in the first place. Do not re-lighten it to
     restore the old hierarchy. */
  --t-faint:     #616c77;
  --t-surface:   #f7f8fa;
  --t-surface-2: #f1f3f6;
  /* A third step down, for a panel that has to read as inset against a band
     that is ALREADY --t-surface. The instruction box was the same #f7f8fa as
     the band behind it, so only its border said it was there. */
  --t-surface-3: #e7ecf1;
  --t-shadow-2:  0 4px 12px -2px rgba(13, 18, 20, .07), 0 2px 4px rgba(13, 18, 20, .04);
  --t-ease:      cubic-bezier(.22, .61, .36, 1);
}

body { background: var(--t-surface); color: var(--ink); -webkit-font-smoothing: antialiased; }

/* ---- type -----------------------------------------------------------------
   Tracking is size-specific. One letter-spacing for every size is wrong
   somewhere: large text reads too loose as it grows, small text too tight. */
h1, h2, h3, .hero-title, .lb-title, .wordmark-name {
  letter-spacing: -.022em; line-height: 1.16;
}
h1, .hero-title { letter-spacing: -.03em; }
.wordmark-name { letter-spacing: -.017em; font-weight: 600; }
.pagehead h1 { letter-spacing: -.032em; line-height: 1.06; }

/* ---- top bar --------------------------------------------------------------
   Translucent, so content passes under it instead of being cut off by an
   opaque strip. The three accessibility contracts this creates are at the
   foot of this file. */
.topbar {
  background: rgba(255, 255, 255, .72);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  /* The hairline is a SHADOW, not a border. A border is inside the element, so
     on a backdrop-filtered bar that 1px strip paints the bar's own translucent
     white over the raw, unblurred page behind it. Over a white page that is
     pure white, which is exactly the bright seam it used to leave along the
     bottom edge while everything above it carried the blur's colour. A shadow
     is drawn outside the box, so the filtered region reaches the true edge and
     there is no strip to go wrong.

     Rounding down to a whole pixel matters too: the bar measured 72.75px tall,
     and a fractional edge is its own source of seams. */
  /* No hairline at all while the glass is on. The blur IS the boundary: it
     separates the bar from the page by making everything under it soft and
     lighter, which a 1px rule can only compete with. Any line here, border or
     shadow, is one more thing at the exact edge that can render as a seam, and
     that edge has now produced two of them. The divider comes back in the
     opaque fallback below, where there is no blur to do the job. */
  border-bottom: 0;
  box-shadow: none;
}
.topbar-inner { min-height: 60px; }
/* No border-radius here. This element carries a heavy bottom border from
   style.css, and a radius makes that border curl up at the ends into a
   bracket. The active-state treatment lives in theme-phase2.css. */
.mainnav a { font-weight: 500; }
.regchip {
  background: var(--t-surface-2); color: var(--t-ink-2);
  border-color: transparent; font-weight: 550;
}

/* ---- the hero -------------------------------------------------------------
   The blue gradient card was the loudest thing on the page. It becomes a calm
   surface, which means every piece of white text on it has to flip to ink.
   All of that is below: miss one and it turns invisible. */
.hero-card {
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--t-shadow-2);
  padding-bottom: 0;
}
.hero-card .hero-title { color: var(--ink); text-shadow: none; font-weight: 600; }
.hero-sub { color: var(--t-ink-2); }
.hero-head .hint { color: var(--muted); }
.hero-badge {
  background: var(--t-surface-2); border-color: transparent; box-shadow: none;
  color: var(--muted); font-weight: 600; letter-spacing: .085em; font-size: 11px;
}
.hero-dot { background: var(--accent); box-shadow: none; animation: none; }
/* Decoration that carried no information. */
.hero-sparkles, .lb-sparkles { display: none; }
.hero-head::after { display: none; }
.hero-sheet {
  margin: 0; padding: 0 18px 18px;
  background: transparent; box-shadow: none; border-radius: 0;
}

/* ---- buttons --------------------------------------------------------------
   Ink, not a blue gradient, and sentence case rather than shouted uppercase.
   This is the single most effective move away from looking generated. */
button.primary, #btn-copy, .lb-btn, .showcase-cta .primary {
  background: var(--cta);
  color: #fff;
  border: 1px solid transparent;
  border-radius: 9px;
  font-weight: 550;
  font-size: 14px;
  text-transform: none;
  letter-spacing: -.008em;
  padding: 11px 18px;
  transition: background .18s var(--t-ease);
}
button.primary:hover, .lb-btn:hover, .showcase-cta .primary:hover {
  background: var(--cta-hover); filter: none;
}
button.primary:active, .lb-btn:active { transform: scale(.985); }
#btn-copy {
  background: var(--card); color: var(--ink);
  border: 1px solid var(--line-strong);
}
#btn-copy:hover { background: var(--t-surface); }
.acct-btn.primary { background: var(--cta); color: #fff; border-color: transparent; }

/* ---- surfaces -------------------------------------------------------------
   Hairlines and tone instead of drawn borders, and one shadow scale. */
.panel {
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
}
.wiz-card, .showcase-card {
  border-radius: 12px;
  border-color: var(--line);
  transition: border-color .2s var(--t-ease), box-shadow .25s var(--t-ease);
}
.wiz-card:hover, .showcase-card:hover {
  border-color: var(--line-strong); box-shadow: var(--t-shadow-2);
}
.wiz-progress i { border-radius: 999px; background: var(--t-surface-2); }
.wiz-progress i.on { background: var(--accent); }

/* ---- the launch offer -----------------------------------------------------
   A gold, sparkling, animated banner. The offer is good enough to survive
   being said quietly, so it is stated instead of performed. */
.launch-banner {
  background: var(--t-surface);
  border: 1px solid var(--line);
  box-shadow: none;
  color: var(--ink);
}
.launch-banner::after { display: none; }
.lb-badge {
  background: var(--t-surface-2); color: var(--muted);
  border-color: transparent; letter-spacing: .085em;
}
.lb-badge-dot { background: var(--accent); animation: none; box-shadow: none; }
.lb-title { color: var(--ink); font-weight: 600; text-shadow: none; }
.lb-sub, .lb-fine { color: var(--t-ink-2); }
.lb-token-ring { display: none; }
.lb-token img { animation: none; transform: none; }

/* ---- footer --------------------------------------------------------------- */
.footer { border-top: 1px solid var(--line); }
.footer p { color: var(--t-faint); }

/* ---- accessibility contracts ----------------------------------------------
   Translucency and motion each carry obligations. These are them. */
@media (prefers-reduced-motion: reduce) {
  button.primary, .lb-btn, .wiz-card, .showcase-card { transition: none !important; }
  button.primary:active, .lb-btn:active { transform: none !important; }
}
@media (prefers-reduced-transparency: reduce) {
  /* Opaque, and now the hairline is needed: with no blur there is nothing else
     telling the reader where the bar stops and the page starts. A shadow, not
     a border, for the reason given above. */
  .topbar {
    background: #fff; -webkit-backdrop-filter: none; backdrop-filter: none;
    box-shadow: 0 1px 0 var(--line);
  }
}
@media (prefers-contrast: more) {
  :root { --line: rgba(13,18,20,.28); --line-strong: rgba(13,18,20,.45); --muted: #4d565e; }
  .topbar {
    background: #fff; -webkit-backdrop-filter: none; backdrop-filter: none;
    box-shadow: 0 1px 0 var(--line);
  }
}

/* ---- the showcase bar -----------------------------------------------------
   With the blue gradient gone, this amber bar became the loudest thing on the
   page by default rather than by decision. Two competing accent colours on one
   screen is one too many, so it joins the same quiet system. */
.showcase-head {
  background: var(--t-surface);
  border-bottom: 1px solid var(--line);
  padding: 14px 16px;
}
.showcase-title { color: var(--ink); font-weight: 600; letter-spacing: -.014em; }
.showcase-chev { color: var(--t-faint); font-size: 26px; }
.showcase-panel.closed .showcase-head { border-bottom: 0; }

/* ---- shouting -------------------------------------------------------------
   ALL-CAPS nav and buttons read as louder, not clearer. Weight and colour
   carry the same hierarchy without raising the voice. Small internal labels
   keep their caps: at 9-10px, letterforms are what make them scannable. */
.mainnav a {
  text-transform: none; letter-spacing: -.005em; font-size: 14px;
  padding: 19px 11px 17px;
}
.wordmark-sub { text-transform: none; letter-spacing: .01em; color: var(--muted); }

/* ---- disabled states ------------------------------------------------------
   The bug this fixes, kept as a note because the shape of it will recur:
   this layer forced `color: #fff` on button.primary, but style.css repaints
   the DISABLED background through `.wiz-nav button[disabled]`, which at
   (0,2,1) outranks `button.primary` at (0,1,1). Result was white text on a
   pale blue gradient: legible enough to pass a glance, and a real contrast
   failure. An override layer has to cover every STATE that repaints, not just
   the default appearance.

   These selectors match or beat the originals and come later, so they win. */
.wiz-nav button[disabled],
button.primary[disabled],
button.primary:disabled,
.acct-btn.primary[disabled] {
  background: var(--t-surface-2);
  background-image: none;
  color: var(--t-faint);
  border-color: transparent;
  cursor: default;
  filter: none;
}
.pager-arrow:disabled { background: var(--t-surface-2); color: var(--t-faint); }

/* Remaining places the old palette painted the accent as a filled surface.
   Kept as accent where the element is small and the colour IS the signal
   (progress fill, tags); flattened where it was decoration. */
.budgetbar i { background: var(--accent); }
.budgetbar.over i { background: var(--fail); }
.wiz-card.reco { border-color: var(--line-strong); background: var(--t-surface); }

/* ---- secondary buttons ----------------------------------------------------
   Ghost, Skip and Import all wore a 2px blue outline in shouted uppercase, so
   next to an ink primary they read as the LOUDER control. A secondary action
   should recede: hairline border, ink label, sentence case. */
.wiz-nav .ghost, button.ghost, #btn-skip, #btn-import, #btn-from-builder {
  background: var(--card);
  border: 1px solid var(--line-strong);
  color: var(--ink);
  font-weight: 500;
  font-size: 14px;
  text-transform: none;
  letter-spacing: -.008em;
  border-radius: 9px;
  padding: 11px 18px;
  transition: background .18s var(--t-ease), border-color .18s var(--t-ease);
}
.wiz-nav .ghost:hover, button.ghost:hover, #btn-skip:hover,
#btn-import:hover, #btn-from-builder:hover {
  background: var(--t-surface);
  border-color: var(--line-strong);
  color: var(--ink);
}
/* Back is the quietest thing in the row: it undoes, it does not advance. */
.wiz-nav .ghost { color: var(--muted); border-color: var(--line); }
.wiz-nav .ghost:hover { color: var(--ink); }

/* The amber note block, matched to the same restrained system. */
.notes {
  background: var(--t-surface); color: var(--t-ink-2);
  border: 1px solid var(--line); border-radius: 10px;
}

/* ---------------------------------------------------------------------------
   Screen-reader-only text. One shared utility so a label a sighted user does
   not need (a table caption, a form label the placeholder already implies, the
   skip link before it is focused) still reaches assistive technology.
   `clip` is the legacy property and `clip-path` the modern one; both are here
   because Safari still honours the old one in some versions. Never use
   display:none for this - that removes the text from the accessibility tree,
   which is the exact opposite of the intent.
   --------------------------------------------------------------------------- */
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
/* ---------------------------------------------------------------------------
   Header-aware anchor targets.

   .topbar is `position: sticky; top: 0; z-index: 50`, so an anchor link scrolls
   its target to viewport y=0 and the bar then paints over it. On the legal
   pages that cut the top off every section heading the table of contents
   pointed at; the same applies to the skip link's #main.

   scroll-margin-top is the browser's own answer: it tells the scroller to stop
   that many pixels short. It takes a fixed number, though, and this header's
   height is NOT fixed: when the top row runs out of width the reg chip wraps
   onto a second line and the bar goes 74px -> 130px. Hand-written numbers were
   wrong in exactly that band, so the number is now MEASURED and published as
   --header-h by static/header-offset.js, and the arithmetic happens in calc().

   Why not simply add a breakpoint for the wrapped band: the width at which the
   wrap happens is itself variable, because it depends on how wide the
   right-hand cluster is. Measured on the Manual Builder, the bar becomes two
   rows below 963px with no account UI, 1061px signed out, 1196px signed in as
   "Rob", and 1243px signed in as "Christopher". The last two differ only by
   the length of a person's name. No breakpoint is right for every reader.

   The values below are the DEFAULTS, used until the script runs and if it
   never does: 74px is the one-row bar, 139px the phone layout where the nav
   takes its own row. Both measured. So a page that loads straight to a #hash
   behaves exactly as it did before rather than worse, and JS only ever makes
   it more accurate. +16px so the heading clears the bar instead of touching it.

   ⚠️ Deliberately scoped to `main[id]` and `.legal [id]`, NOT to `[id]`
   globally: scroll-margin also affects scrollIntoView(), and the species
   pickers in app.js / wizard.js scroll options with `block: "nearest"` inside
   a small dropdown, where a 90px margin would shove the list around.
   --------------------------------------------------------------------------- */
:root { --header-h: 74px; }
main[id], .legal [id] { scroll-margin-top: calc(var(--header-h) + 16px); }
@media (max-width: 940px) {
  :root { --header-h: 139px; }
}

/* The skip link: hidden until a keyboard user tabs to it, then a real target. */
.skip-link:focus {
  position: fixed !important;
  top: 8px; left: 8px;
  width: auto; height: auto;
  padding: 10px 16px; margin: 0;
  clip: auto; clip-path: none;
  overflow: visible;
  z-index: 1000;
  background: var(--t-surface, #fff);
  color: var(--ink, #10161c);
  border: 2px solid var(--cta, #0d6b9c);
  border-radius: 8px;
  font-weight: 600;
  text-decoration: none;
}
