/* ============================================================
   HAVE I BEEN QWNED
   Campaign surface for Quip Network. Marketing tier: radius 0,
   no shadows, 1px borders, underline inputs, coral as the only
   interactive accent, glyph vocabulary limited to  ■ ✚ ● ◆.

   Everything below composes the design-system tokens. No new
   colours, no new typefaces. The single sanctioned extension is
   the status-colour set for verdict state, per docs/tiers.md.
   ============================================================ */

@import url('../tokens/core.css');
@import url('../tokens/accents.css');
@import url('../tokens/tier-marketing.css');

:root {
  /* core.css sets --muted to zinc-500, which is only 3.8:1 on our light
     surfaces. Overridden here rather than edited in the vendored token file,
     so the design system stays in sync. Dark sections set it back to zinc-400
     for the same reason in the other direction. */
  --muted: var(--zinc-600);

  /* Status colours — local extension, product-tier values. */
  --danger: var(--coral);
  --danger-text: #b3272d;
  --warning: #d97706;
  --warning-text: #9a5b00;
  --positive: #059669;
  --positive-text: #036147;

  /* On dark grounds the -text variants are too dark; these are the
     dark-ground counterparts, kept at AA against zinc-950. */
  /* Registration marks, borrowed from quip.network's margins. */
  --plus-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M5 0.6v8.8M0.6 5h8.8' stroke='%23000' stroke-width='1.1' stroke-linecap='round'/%3E%3C/svg%3E");

  /* Up-and-right arrow for links that leave the page. */
  --arrow-out: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M2.6 7.4L7.4 2.6M7.4 2.6H4.1M7.4 2.6V5.9' fill='none' stroke='%23000' stroke-width='1.3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");

  --danger-on-dark: #ff8a93;
  --warning-on-dark: #f0b34e;
  --positive-on-dark: #34d399;
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg-body);
  font-family: var(--font-body);
  font-feature-settings: 'case';
  -webkit-font-smoothing: antialiased;
}

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

/* Section rhythm is tightened for this surface. The shared --section-y is
   183px at desktop, tuned for quip.network's long editorial pages; here it
   put 38% of the page into padding alone. A microsite earns its whitespace
   at roughly half that. */
.section { padding-block: clamp(48px, 4.4vw, 84px); }
.section-tight { padding-block: clamp(28px, 2.6vw, 44px); }

.section-dark {
  background: var(--zinc-950);
  color: var(--fg-on-dark);
  --border: var(--zinc-700);
  --muted: var(--zinc-400);
  --fg-body: var(--zinc-50);
  --fg-strong: var(--zinc-50);
}

.stack { display: flex; flex-direction: column; }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.gap-4 { gap: var(--space-4); }
.gap-6 { gap: var(--space-6); }
.gap-8 { gap: var(--space-8); }
.gap-12 { gap: var(--space-12); }

/* Reading measure for running text and rule lists. */
/* Reading measure for running text and rule lists. */
.measure { max-width: 68ch; }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.nums { font-variant-numeric: tabular-nums; }

/* ============================================================
   HEADER
   ============================================================ */

.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--zinc-950);
  border-bottom: 1px solid var(--zinc-800);
  color: var(--zinc-50);
}

.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  height: 56px;
}

/* Wordmark.
   The domain is long and undifferentiated, so brightness does the work a
   logotype would: the host name recedes and QWNED carries the mark. The
   dot is pulled tight because a mono period sits centred in a full-width
   cell and otherwise floats away from both sides. */
.wordmark {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--zinc-400);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease);
}
.wordmark .mark {
  color: var(--zinc-50);
  font-weight: 600;
}
.wordmark .dot {
  color: var(--coral);
  margin-inline: -0.16em;
}
.wordmark .tld { color: var(--zinc-400); }
.wordmark:hover { color: var(--zinc-300); }
.wordmark:hover .tld { color: var(--zinc-300); }

.header-right {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

/* Secondary endorsement: the microsite carries its own name, Quip signs it. */
.built-by {
  display: inline-flex;
  align-items: center;
  color: var(--zinc-400);
  gap: var(--space-3);
  padding-left: var(--space-6);
  border-left: 1px solid var(--zinc-800);
  text-decoration: none;
  transition: opacity var(--dur-fast) var(--ease);
}
.built-by:hover { opacity: 0.75; }
.built-by-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--zinc-400);
  white-space: nowrap;
}
.built-by img { height: 20px; width: auto; display: block; }
@media (max-width: 720px) {
  .built-by { padding-left: 0; border-left: 0; }
  .built-by-label { display: none; }
}

.header-links {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.header-links a {
  color: var(--zinc-400);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}
.header-links a:hover { color: var(--zinc-50); }
@media (max-width: 720px) {
  .header-links .opt { display: none; }
}

/* ============================================================
   HERO
   ============================================================ */

.hero {
  position: relative;
  color: var(--fg-on-dark);
  --border: var(--zinc-700);
  --muted: var(--zinc-400);
  --fg-strong: var(--zinc-50);
  --fg-body: var(--zinc-50);
}

/* The field runs behind both the hero and the deadline section, so it carries
   past the splash instead of stopping at its edge. It holds through the hero,
   thins as the deadline copy begins, and is gone by the time the clock and the
   sourced figures need a clean ground. */
/* Two stages. The page opens as the tool and nothing else; everything that
   explains it arrives once a result does, which is when someone actually has
   a reason to read it. */
body[data-stage="splash"] .after-check { display: none; }

/* The splash fills the screen, so the tool is the whole first impression. */
body[data-stage="splash"] .hero { min-height: calc(100svh - 56px); display: grid; align-items: center; }
body[data-stage="splash"] .hero .wrap { width: 100%; }

.field-zone {
  position: relative;
  background: var(--zinc-950);
  overflow: hidden;
}
/* With the sections below hidden the zone is only as tall as the hero, so the
   field has to fade lower down or it dissolves halfway up the splash. */
body[data-stage="splash"] #glyph-field {
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 68%, rgba(0,0,0,0.4) 86%, transparent 97%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 68%, rgba(0,0,0,0.4) 86%, transparent 97%);
}
.field-zone > section { position: relative; z-index: 1; background: transparent; }

/* Generative glyph field — the brand's pixel/glyph backdrop, rendered to
   canvas rather than hand-authored so it stays cheap and non-repeating. */
#glyph-field {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* Kept at full presence. The page reads calmer because there is less
     competing with it, not because the field was dimmed. */
  opacity: 0.5;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 40%, rgba(0,0,0,0.66) 48%, rgba(0,0,0,0.28) 55%, transparent 63%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 40%, rgba(0,0,0,0.66) 48%, rgba(0,0,0,0.28) 55%, transparent 63%);
}

.hero .wrap {
  position: relative;
  z-index: 1;
  /* The page is a single tool. It reads calmer with real air around it. */
  padding-block: clamp(72px, 9vw, 156px) clamp(80px, 10vw, 172px);
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 560px);
  gap: clamp(32px, 5vw, 80px);
  /* The columns are unequal by about a hundred pixels. Top-aligning them left
     the text hanging below the panel with nothing to align to, and the panel's
     border sat on the same line as the first text rather than with it.
     Centring reads as a deliberate pair. */
  align-items: center;
}
/* An explicit display beats the hidden attribute, so restate it. */
.hero-grid[hidden] { display: none; }

/* Holds whichever state is showing. Pinned to the tallest of them so the
   page never moves between the form, the readout and the result. */
.hero-stage { min-height: var(--stage-h, auto); }
.scanner-body[hidden] { display: none; }
@media (max-width: 1024px) {
  .hero-grid { grid-template-columns: minmax(0, 1fr); align-items: start; }
}

.hero-thesis { display: flex; flex-direction: column; gap: var(--space-6); }

.hero h1 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: clamp(40px, 5.2vw + 12px, 82px);
  line-height: 1.02;
  letter-spacing: -0.025em;
  margin: 0;
  color: var(--zinc-50);
  text-wrap: balance;
}

.hero-sub {
  font-size: clamp(16px, 0.5vw + 15px, 19px);
  line-height: 1.5;
  color: var(--zinc-300);
  max-width: 42ch;
  margin: 0;
  /* Even the lines out. Without this the second sentence starts two words
     before the wrap and leaves them stranded at the end of line one. */
  text-wrap: balance;
}

/* The marks earn their place by being recognisable, so they are larger and
   brighter than a decorative row would be. A hairline sets them apart from
   the paragraph above without adding another block of colour. */
.hero-chains {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4) var(--space-8);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--zinc-800);
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--zinc-300);
}
.hero-chains span {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  white-space: nowrap;
}
/* Carrying their own brand colours, so the currentColor tint has to come off.
   The label stays zinc so three foreign palettes do not spread beyond the
   marks themselves, and coral remains the only colour that means "act". */
.chain-mark {
  width: 22px;
  height: 22px;
  flex: none;
}
@media (max-width: 560px) {
  .hero-chains { gap: var(--space-3) var(--space-5); font-size: 12px; }
  .chain-mark { width: 18px; height: 18px; }
}

/* Real chain marks, rendered in one colour so they sit inside the zinc
   palette instead of importing three foreign brand colours. */
/* Hidden without display:none. A gradient referenced out of a non-rendered
   SVG does not resolve, which silently drops any mark that uses one while
   plain currentColor paths keep working. */
.icon-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
  pointer-events: none;
}
.chain-icon {
  width: 15px;
  height: 15px;
  flex: none;
  color: var(--zinc-400);
  vertical-align: middle;
}
.chain-icon-card { width: 20px; height: 20px; color: var(--muted); }

/* ============================================================
   SCANNER — the instrument
   ============================================================ */

.scanner {
  background: var(--zinc-900);
  border: 1px solid var(--zinc-700);
  display: flex;
  flex-direction: column;
}

.scanner-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  background: var(--zinc-850);
  border-bottom: 1px solid var(--zinc-700);
}
/* The panel title has to outrank the field labels below it, otherwise the
   whole thing reads as a menu bar rather than a named instrument. */
.scanner-title {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--zinc-100);
}
/* The Consumers glyph. This tool is aimed at people holding their own
   coins, and that audience is the diamond. Rendered zinc, because audience
   tint is opt-in and reserved for surfaces that compare all four. */
.scanner-glyphs {
  display: inline-flex;
  color: var(--zinc-500);
  font-size: 11px;
  line-height: 1;
}

.scanner-body { padding: var(--space-6) var(--space-5) var(--space-5); }

.field-label {
  display: block;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--zinc-400);
  margin-bottom: var(--space-3);
}

.input-qwned {
  width: 100%;
  padding: var(--space-3) 0;
  border: 0;
  border-bottom: 1px solid var(--zinc-600);
  border-radius: 0;
  background: transparent;
  font-family: var(--font-mono);
  font-size: 15px;
  color: var(--zinc-50);
  transition: border-color var(--dur-fast) var(--ease);
}
.input-qwned::placeholder { color: var(--zinc-600); }
.input-qwned:focus {
  outline: none;
  border-bottom-color: var(--coral);
}
.input-qwned:disabled { opacity: 0.5; }

/* Chain detection chips */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-4);
  min-height: 30px;
}
.chip {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 5px var(--space-3);
  border: 1px solid var(--zinc-700);
  background: transparent;
  color: var(--zinc-500);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.chip:hover { color: var(--zinc-300); border-color: var(--zinc-600); }
.chip[aria-pressed='true'] {
  color: var(--zinc-950);
  background: var(--zinc-50);
  border-color: var(--zinc-50);
}
.chip-hint {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--zinc-400);
  align-self: center;
}

.btn-check {
  width: 100%;
  margin-top: var(--space-5);
  padding: 14px var(--space-6);
  border: 0;
  border-radius: 0;
  /* White, not coral. Coral has to carry risk on this site, and a coral slab
     here collides with the coral verdict that lands in the same panel. On
     near black, white is also the stronger affordance of the two. */
  background: var(--zinc-50);
  color: var(--zinc-950);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 16px;
  line-height: 1;
  font-feature-settings: 'case';
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease);
}
.btn-check:hover:not(:disabled) { background: var(--zinc-300); }
.btn-check:disabled { background: var(--zinc-700); color: var(--zinc-400); cursor: default; }

.privacy-note {
  margin: var(--space-4) 0 0;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: 0.03em;
  /* Was zinc-500 at 3.67:1. This line is the trust message, so it has to be
     the easiest small text to read on the panel rather than the hardest. */
  color: var(--zinc-400);
}

/* Diagnostic notice.
   Not a tinted box with an accent rail. This is a hairline rule, a mono
   label and a drawn marker: the same devices the rest of the system uses,
   and it reads like a readout from the instrument rather than a web alert.
   The marker is the brand's plus glyph turned 45 degrees, drawn in CSS
   because the voice guide forbids unicode characters standing in for icons. */
.error-note {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--zinc-700);
}
.error-note[hidden] { display: none; }

.error-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--danger-on-dark);
}
.error-label::before {
  content: '';
  width: 9px;
  height: 9px;
  flex: none;
  background: currentColor;
  clip-path: polygon(40% 0, 60% 0, 60% 40%, 100% 40%, 100% 60%, 60% 60%,
                     60% 100%, 40% 100%, 40% 60%, 0 60%, 0 40%, 40% 40%);
  transform: rotate(45deg);
}
.error-msg {
  margin: var(--space-2) 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--zinc-300);
}

/* Tie the error back to the field that caused it. */
.input-qwned.is-error { border-bottom-color: var(--danger-on-dark); }

/* ============================================================
   TERMINAL
   ============================================================ */

.terminal {
  padding: var(--space-5);
  min-height: 268px;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.7;
  color: var(--zinc-400);
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.terminal[hidden] { display: none; }
.term-line { white-space: pre-wrap; word-break: break-word; }
.term-line.is-accent { color: var(--coral); }
.term-line.is-dim { color: var(--zinc-600); }

/* ============================================================
   RESULT
   Takes over the hero width rather than stacking inside the
   scanner column, so a scan never grows the page.
   ============================================================ */

.result {
  border: 1px solid var(--zinc-700);
  background: var(--zinc-900);
}
.result[hidden] { display: none; }

/* Top bar: score, verdict, and the four headline metrics on one line. */
.result-bar {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: center;
  gap: clamp(20px, 3vw, 48px);
  padding: var(--space-5) var(--space-6);
  border-bottom: 1px solid var(--zinc-800);
}
@media (max-width: 900px) {
  .result-bar { grid-template-columns: auto minmax(0, 1fr); }
  .result-bar .metrics { grid-column: 1 / -1; }
}
@media (max-width: 560px) {
  .result-bar { grid-template-columns: minmax(0, 1fr); }
}

.score-block { display: flex; flex-direction: column; gap: 2px; }
.score-value {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: clamp(48px, 4vw + 22px, 68px);
  line-height: 0.9;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--zinc-50);
}
.score-caption {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--zinc-400);
}

/* The verdict stamp is the page's one bold gesture. */
.stamp {
  display: inline-flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-start;
  border: 1px solid currentColor;
  padding: var(--space-3) var(--space-4);
  font-family: var(--font-mono);
  color: var(--danger-on-dark);
}
.stamp-label {
  font-size: clamp(16px, 1vw + 11px, 22px);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
}
.stamp-sub {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.75;
}
.stamp.is-clean { color: var(--positive-on-dark); }
.stamp.is-warn { color: var(--warning-on-dark); }
.stamp.is-neutral { color: var(--zinc-400); }

.metrics {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-4);
}
@media (max-width: 700px) { .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.metric { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.metric-key {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--zinc-400);
}
.metric-val {
  font-family: var(--font-mono);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--zinc-50);
  overflow-wrap: anywhere;
}
.metric-val.is-danger { color: var(--danger-on-dark); }
.metric-val.is-clean { color: var(--positive-on-dark); }

/* Detail sits in three columns so it reads wide instead of deep. */
.result-cols {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-bottom: 1px solid var(--zinc-800);
}
@media (max-width: 900px) { .result-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) { .result-cols { grid-template-columns: minmax(0, 1fr); } }

.result-col {
  padding: var(--space-5) var(--space-6);
  border-right: 1px solid var(--zinc-800);
  min-width: 0;
}
.result-col:last-child { border-right: 0; }
@media (max-width: 900px) {
  .result-col { border-right: 0; border-top: 1px solid var(--zinc-800); }
  .result-col:first-child { border-top: 0; }
}

.block-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--zinc-400);
  margin-bottom: var(--space-4);
}

.chain-rows { display: flex; flex-direction: column; }
.chain-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: var(--space-3);
  align-items: baseline;
  padding: 5px 0;
  border-bottom: 1px solid var(--zinc-800);
  font-family: var(--font-mono);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.chain-row:last-child { border-bottom: 0; }
.chain-name { color: var(--zinc-300); }
.chain-bal { color: var(--zinc-500); text-align: right; white-space: nowrap; }
.chain-state {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: right;
  white-space: nowrap;
}
.chain-state.is-danger { color: var(--danger-on-dark); }
.chain-state.is-clean { color: var(--positive-on-dark); }

.deductions { display: flex; flex-direction: column; }
.deduction {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--zinc-800);
}
.deduction:last-child { border-bottom: 0; }
.deduction-label { font-size: 13px; color: var(--zinc-200); }
.deduction-detail { font-size: 11px; color: var(--zinc-500); margin-top: 2px; }
.deduction-amt {
  font-family: var(--font-mono);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--danger-on-dark);
  white-space: nowrap;
}

.advice-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.advice-list li {
  position: relative;
  padding-left: var(--space-5);
  font-size: 13px;
  line-height: 1.45;
  color: var(--zinc-300);
}
.advice-list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.4em;
  width: 6px;
  height: 7px;
  background: var(--coral);
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}

.result-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-6);
}
.btn-solid,
.btn-ghost {
  flex: 1 1 160px;
  padding: 12px var(--space-5);
  border-radius: 0;
  font-family: var(--font-body);
  font-weight: 450;
  font-size: 14px;
  line-height: 1;
  font-feature-settings: 'case';
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.btn-solid { background: var(--zinc-50); color: var(--zinc-950); border: 1px solid var(--zinc-50); }
.btn-solid:hover { background: var(--zinc-300); border-color: var(--zinc-300); }
.btn-ghost { background: transparent; color: var(--zinc-300); border: 1px solid var(--zinc-700); }
.btn-ghost:hover { color: var(--zinc-50); border-color: var(--zinc-500); }

.notify {
  border-top: 1px solid var(--zinc-800);
  padding: var(--space-5) var(--space-6);
}
.notify[hidden] { display: none; }
.notify-row { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.notify-row .input-qwned { flex: 1 1 220px; font-family: var(--font-body); }
.notify-row button { flex: 0 0 auto; padding: 10px var(--space-5); }
.notify-msg { margin-top: var(--space-3); font-size: 13px; color: var(--positive-on-dark); }

/* ============================================================
   TYPE + SHARED SECTION FURNITURE
   ============================================================ */

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-strong);
}
.eyebrow::before {
  content: '';
  width: 4px;
  height: 1em;
  background: var(--coral);
  flex: none;
}

h2.h-display {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: clamp(30px, 2.4vw + 20px, 52px);
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--fg-strong);
  text-wrap: balance;
  max-width: 20ch;
}

h3.h-card {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 22px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin: 0;
  color: var(--fg-strong);
}

p.lede {
  font-size: 17px;
  line-height: 1.55;
  color: var(--fg-body);
  max-width: 62ch;
  margin: 0;
  text-wrap: pretty;
}
p.body { font-size: 15px; line-height: 1.6; color: var(--fg-body); margin: 0; text-wrap: pretty; }
.muted-text { color: var(--muted); }

/* Deadline section: argument on the left, the clock beside it. */
.deadline-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 440px);
  gap: clamp(32px, 4vw, 72px);
  align-items: start;
}
@media (max-width: 1024px) {
  .deadline-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   CONTENT LINKS
   Without this the browser's own visited-link purple shows up
   and breaks the palette. Colour stays inherited; the coral
   underline carries the affordance.
   ============================================================ */

.lede a,
.body a,
.faq-answer a,
.footer-note a,
.prose p a,
.prose li a,
table.data a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--coral);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color var(--dur-fast) var(--ease);
}
.lede a:hover,
.body a:hover,
.faq-answer a:hover,
.footer-note a:hover,
.prose p a:hover,
.prose li a:hover,
table.data a:hover { color: var(--coral); }



/* ============================================================
   REGISTRATION MARKS
   The plus marks from quip.network's margins. Painted with the
   section's own colour through a mask, so a light section gets
   dark marks and a dark section gets light ones without a
   second rule.
   ============================================================ */

.marks { position: relative; }
.marks > .wrap { position: relative; z-index: 1; }

.marks::before,
.marks::after {
  content: '';
  position: absolute;
  top: clamp(28px, 4vw, 56px);
  bottom: clamp(28px, 4vw, 56px);
  width: 10px;
  background: currentColor;
  opacity: 0.28;
  -webkit-mask: var(--plus-mark) repeat-y center top / 10px clamp(96px, 9vw, 150px);
  mask: var(--plus-mark) repeat-y center top / 10px clamp(96px, 9vw, 150px);
  pointer-events: none;
}
.marks::before { left: clamp(8px, 1.6vw, 30px); }
.marks::after { right: clamp(8px, 1.6vw, 30px); }

/* Below this the gutter is too narrow to hold marks without crowding. */
@media (max-width: 860px) {
  .marks::before, .marks::after { display: none; }
}

/* A third tone, so the page stops alternating strictly black and white
   and the questions read as a separate part of the site. */
.section-muted {
  position: relative;
  overflow: hidden;
  background: var(--surface-2);
  border-top: 1px solid var(--border);
}
.section-muted > .wrap { position: relative; z-index: 1; }

/* The questions sit on a panel so the field reads around them rather than
   behind the text, the same move quip.network makes with its FAQ. */
.faq-panel {
  position: relative;
  z-index: 1;
  max-width: 1100px;
  margin-inline: auto;
  /* The section already supplies the outer rhythm and the space the field
     reads through. The panel only needs enough inset to hold its own edge. */
  margin-block: 0;
  padding: clamp(24px, 2.2vw, 40px) clamp(20px, 2.2vw, 40px);
  background: color-mix(in srgb, var(--zinc-100) 88%, transparent);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
}

#faq-field {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0.42;
  pointer-events: none;
  /* Softened at both edges so the field belongs to this section rather than
     butting against the ones above and below it. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 22%, #000 78%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 22%, #000 78%, transparent 100%);
}

/* ============================================================
   LINK-OUT
   A standalone link line. Kept out of running prose so a link
   phrase can never break across two lines, and marked with an
   arrow that is drawn (masked SVG) rather than typed, since the
   voice guide forbids characters standing in for icons.
   ============================================================ */

.link-out {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 24px;
  padding-block: var(--space-1);
  align-self: flex-start;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-strong);
  text-decoration: underline;
  text-decoration-color: var(--coral);
  text-underline-offset: 4px;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease);
}
.link-out:hover { color: var(--coral); }

.link-out::after,
.lede a[href^="http"]::after,
.body a[href^="http"]::after,
.faq-answer a[href^="http"]::after,
.prose p a[href^="http"]::after {
  content: '';
  display: inline-block;
  width: 9px;
  height: 9px;
  flex: none;
  background: currentColor;
  -webkit-mask: var(--arrow-out) no-repeat center / contain;
  mask: var(--arrow-out) no-repeat center / contain;
}
.lede a[href^="http"]::after,
.body a[href^="http"]::after,
.faq-answer a[href^="http"]::after,
.prose p a[href^="http"]::after { margin-left: 4px; }

/* ============================================================
   DOOMSDAY CLOCK
   The small-clock pattern from hello.quip.network, rebuilt on
   these tokens. Same deadline, same digit rhythm, same link out
   to quantumdoomclock.com.
   ============================================================ */

.doomclock {
  border: 1px solid var(--zinc-800);
  padding: clamp(20px, 1.8vw + 12px, 32px);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  background: var(--zinc-900);
}

.doomclock-head { display: flex; flex-direction: column; gap: var(--space-3); }
.doomclock-title {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--zinc-50);
}
.doomclock-note {
  font-size: 14px;
  line-height: 1.5;
  color: var(--zinc-400);
  max-width: 52ch;
  margin: 0;
}

.clock {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
}
.clock-unit {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  flex: 1 1 auto;
  color: var(--zinc-50);
}
.clock-digit {
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: clamp(26px, 2.2vw, 34px);
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.clock-label {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 13px;
  line-height: 1.15;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.clock-sep {
  font-family: var(--font-heading);
  font-size: clamp(26px, 2.2vw, 34px);
  line-height: 1.1;
  color: var(--zinc-600);
}

.doomclock-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 24px;
  padding-block: var(--space-1);
  align-self: flex-start;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--zinc-400);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color var(--dur-fast) var(--ease);
}
.doomclock-link:hover { color: var(--zinc-50); }
.doomclock-link::after {
  content: '';
  display: inline-block;
  width: 9px; height: 9px; flex: none;
  background: currentColor;
  -webkit-mask: var(--arrow-out) no-repeat center / contain;
  mask: var(--arrow-out) no-repeat center / contain;
}

@media (max-width: 640px) {
  .clock { gap: var(--space-3); }
  .clock-unit { min-width: 0; flex: 1 1 0; }
  .clock-digit, .clock-sep { font-size: 24px; letter-spacing: -0.48px; }
  .clock-label { font-size: 11px; }
}

/* ============================================================
   READINGS
   Outputs of the instrument, so they sit on the hero's own
   ground under a hairline rather than floating in a light band
   of their own between two dark sections.
   ============================================================ */

.statbar {
  display: flex;
  flex-wrap: wrap;
  margin-top: clamp(28px, 3vw, 48px);
  border-top: 1px solid var(--zinc-800);
}
.stat {
  flex: 1 1 170px;
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-5) 0 0;
  min-width: 0;
}
.stat-val {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 22px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--zinc-50);
}
.stat-key {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--zinc-500);
}
@media (max-width: 700px) {
  .stat { flex: 1 1 50%; padding-right: var(--space-4); }
}

/* Numbered steps. The status pill was doing double duty here and read as a
   state tag rather than a sequence, which is what threw the balance off. */
.steps { list-style: none; margin: 0; padding: 0; }
.steps li {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  gap: var(--space-4);
  align-items: baseline;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--zinc-800);
  font-size: 14px;
  line-height: 1.5;
  color: var(--fg-body);
}
.steps li:first-child { padding-top: 0; }
.steps li:last-child { padding-bottom: 0; border-bottom: 0; }
.step-n {
  font-family: var(--font-mono);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--zinc-400);
}

/* ============================================================
   DATA TABLE
   ============================================================ */

.table-scroll { overflow-x: auto; }
table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  min-width: 560px;
}
table.data th,
table.data td {
  text-align: left;
  padding: var(--space-4) var(--space-4) var(--space-4) 0;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
table.data th {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  border-bottom-color: var(--fg-strong);
}
table.data td.figure {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--fg-strong);
  white-space: nowrap;
}
table.data td.src { color: var(--muted); font-size: 13px; }
/* Sources link out in place. A citation should be checkable in one click
   without a separate call to action pulling people off the page. */
table.data td.src a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--zinc-600);
  text-underline-offset: 3px;
  transition: color var(--dur-fast) var(--ease), text-decoration-color var(--dur-fast) var(--ease);
}
table.data td.src a:hover {
  color: var(--fg-strong);
  text-decoration-color: var(--coral);
}

/* ============================================================
   CHAIN CARDS
   ============================================================ */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-6);
}

.chain-card {
  border: 1px solid var(--border);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  background: var(--surface-1);
}
.section-dark .chain-card { background: var(--zinc-900); border-color: var(--zinc-800); }

.chain-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.chain-tag {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

/* One grid for the whole list, not one per row. When each <li> owned its own
   grid the tag column sized to that row's own tag, so every row's text began
   at a different x. Sharing one track aligns them. */
.rule-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-3) var(--space-4);
  align-items: start;
}
.rule-list li {
  display: contents;
  font-size: 14px;
  line-height: 1.5;
  color: var(--fg-body);
}
.rule-state {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 3px 6px;
  border: 1px solid currentColor;
  height: fit-content;
  white-space: nowrap;
  /* Fill the shared track and centre the label. Sized to their own text the
     tags left-align in a track set by the longest one, which leaves the
     column with a clean left edge and a ragged right one. */
  width: 100%;
  text-align: center;
}
.rule-state.exposed { color: var(--danger-text); }
.rule-state.shielded { color: var(--positive-text); }
.section-dark .rule-state.exposed { color: var(--danger-on-dark); }
.section-dark .rule-state.shielded { color: var(--positive-on-dark); }

/* ============================================================
   CTA + FAQ + FOOTER
   ============================================================ */

.cta-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  gap: clamp(32px, 5vw, 80px);
  align-items: start;
}
@media (max-width: 900px) { .cta-grid { grid-template-columns: minmax(0, 1fr); } }

.cta-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }
/* Same treatment as every other primary action, so one job looks like one
   job across the site. */
.btn-primary {
  display: inline-flex;
  align-items: center;
  padding: 14px var(--space-6);
  background: var(--zinc-50);
  color: var(--zinc-950);
  border: 1px solid var(--zinc-50);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 15px;
  line-height: 1;
  text-decoration: none;
  font-feature-settings: 'case';
  transition: background-color var(--dur-fast) var(--ease);
}
.btn-primary:hover { background: var(--zinc-300); border-color: var(--zinc-300); }

.btn-outline-light {
  display: inline-flex;
  align-items: center;
  padding: 14px var(--space-6);
  background: transparent;
  color: var(--zinc-50);
  border: 1px solid var(--zinc-600);
  font-family: var(--font-body);
  font-weight: 450;
  font-size: 15px;
  line-height: 1;
  text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease);
}
.btn-outline-light:hover { border-color: var(--zinc-400); }

.faq-list { border-top: 1px solid var(--border); }
.faq-item { border-bottom: 1px solid var(--border); }
.faq-item summary {
  list-style: none;
  cursor: pointer;
  padding: var(--space-5) 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 18px;
  line-height: 1.3;
  color: var(--fg-strong);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: '';
  flex: none;
  width: 10px;
  height: 10px;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
  transition: transform var(--dur-fast) var(--ease);
}
.faq-item[open] summary::after { transform: rotate(-135deg) translateY(-2px); }
.faq-answer { padding: 0 var(--space-10) var(--space-5) 0; max-width: none; }

.site-footer {
  background: var(--zinc-950);
  color: var(--zinc-400);
  border-top: 1px solid var(--zinc-800);
  padding-block: var(--space-12);
  font-size: 14px;
}
.footer-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-8);
}
.footer-links { display: flex; flex-wrap: wrap; gap: var(--space-6); }
.site-footer a { color: var(--zinc-400); text-decoration: none; }
.site-footer a:hover { color: var(--zinc-50); }
.footer-note { max-width: 46ch; line-height: 1.6; font-size: 13px; color: var(--zinc-400); }
.footer-brand { color: var(--zinc-50); font-family: var(--font-mono); font-size: 13px; letter-spacing: 0.06em; text-transform: uppercase; }
.footer-logo { display: inline-block; transition: opacity var(--dur-fast) var(--ease); }
.footer-logo:hover { opacity: 0.75; }
.footer-logo img { height: 32px; width: auto; display: block; }

/* ============================================================
   PROSE (methodology page)
   ============================================================ */

.prose { max-width: 68ch; display: flex; flex-direction: column; gap: var(--space-5); }
.prose h2 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 30px;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: var(--space-8) 0 0;
  color: var(--fg-strong);
}
.prose h3 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 20px;
  margin: var(--space-6) 0 0;
  color: var(--fg-strong);
}
.prose p { font-size: 16px; line-height: 1.65; margin: 0; }
.prose ul { margin: 0; padding-left: var(--space-5); display: flex; flex-direction: column; gap: var(--space-2); }
.prose li { font-size: 16px; line-height: 1.6; }
.prose code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--surface-2);
  padding: 2px 5px;
}
.prose a { color: var(--fg-strong); text-underline-offset: 3px; }

/* ============================================================
   NOTICE
   The informational sibling of the error diagnostic. Rules above
   and below, a mono label, a drawn marker. No accent rail on a
   tinted box.
   ============================================================ */

.notice {
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: var(--space-5) 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.notice-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.notice-label::before {
  content: '';
  width: 8px;
  height: 8px;
  flex: none;
  background: var(--coral);
}
.notice p { margin: 0; font-size: 15px; line-height: 1.65; color: var(--fg-body); }

/* Cards carrying the per-chain rules, so the reference page speaks the
   same visual language as the homepage instead of inventing a second one. */
.rule-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-5);
}
.rule-card {
  border: 1px solid var(--border);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}
.rule-card h3 {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 20px;
  margin: 0;
  color: var(--fg-strong);
}
.rule-card .rule-list li { font-size: 13px; }
.rule-card code { background: transparent; padding: 0; color: var(--muted); }
/* Lift the cards off a dark ground. Without a fill they are a black panel on
   a black section, distinguishable only by a hairline. */
.section-dark .rule-card {
  background: var(--zinc-900);
  border-color: var(--zinc-800);
}

/* ============================================================
   ENTRANCE MOTION
   ============================================================ */

/* Progressive enhancement: content is visible by default and only starts
   hidden once JS has confirmed it can reveal it again. A failed observer or a
   blocked script must never leave a section permanently invisible. */
.js .enter {
  opacity: 0;
  transform: translateY(var(--enter-y));
  transition: opacity var(--dur-enter) var(--ease), transform var(--dur-enter) var(--ease);
}
.js .enter.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js .enter { opacity: 1; transform: none; transition: none; }
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--coral);
  outline-offset: 2px;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 560px) {
  .result-head { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
  .metrics { grid-template-columns: minmax(0, 1fr); }
  .metric { border-right: 0; }
  .metric:nth-child(n + 2) { border-top: 1px solid var(--zinc-800); }
  .score-value { font-size: 64px; }
}

/* Grouped score table. Rows previously repeated an empty first cell, which
   left nine of twelve rows with a hole where the label should be. Grouping
   by signal states the structure instead of implying it. */
.score-table tbody + tbody th[scope="row"],
.score-table tbody + tbody td { border-top: 1px solid var(--fg-strong); }
.score-table th[scope="row"] {
  vertical-align: top;
  text-align: left;
  font-family: var(--font-body);
  font-weight: 450;
  font-size: 14px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--fg-strong);
  white-space: nowrap;
  padding-right: var(--space-6);
  border-bottom: 0;
}
.score-table td.num, .score-table th.num { text-align: right; }
.score-table tbody tr:not(:last-child) td { border-bottom: 1px solid var(--border); }
.score-table tbody tr:last-child td { border-bottom: 0; }

/* Closing call to action on reference pages. */
.cta-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
}
.cta-strip-text {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: clamp(20px, 1.4vw + 14px, 26px);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--zinc-50);
}
