/* GENERATED by scripts/build_css.py from src/styles/. Do not edit.
   Edit src/styles/tokens.css or src/styles/base.css instead. */
/* QuakeIndex design tokens — docs/DESIGN.md §1.
 *
 * tests/test_contrast.py reads THIS FILE and fails CI if a text token drops below
 * WCAG AA, or if one of the four fill tokens is ever declared as a `color:`.
 * Change a hex here and the test recomputes; it does not read the table in the
 * document, because a table you typed is a table you guessed.
 *
 * No dark mode at launch, deliberately: the brief names "glowing dark maps" as a
 * cliché to avoid and a dark theme is where that arrives by default. Survey white
 * is the identity. A dark survey-paper palette is a real design problem with its
 * own ticket.
 */
:root {
  /* Brief §6, unchanged. */
  --survey-white: #F7F8F6;
  --basalt: #1E2226;
  --seismo-blue: #2F5D8A;
  --sediment: #B9A27A;
  --fault-red: #C8322B;
  --calm-green: #3E7D5A;

  /* Derived. Each exists because a measured need appeared. */
  --basalt-70: #5A6068;   /* timestamps and source lines. 5.96:1 — NOT fine print. */
  --basalt-15: #DCDEDA;   /* hairlines, table rules, input borders. Fill only. */
  --basalt-06: #EDEEEB;   /* the answer block's fill. Fill only. */
  --sediment-25: #EFEAE0; /* the activity strip's normal band. Fill only. */

  /* Type. 1.25 ratio off a 17px base; clamped between the 360px floor and 1024px.
   * --t-body does not grow: 17px is already right, and a body size that scales
   * with the viewport just makes desktop lines too long. */
  --t-answer: clamp(2.125rem, 1.55rem + 2.6vw, 2.75rem);
  --t-h1:     clamp(1.6875rem, 1.35rem + 1.5vw, 2.0625rem);
  --t-h2:     clamp(1.3125rem, 1.19rem + 0.55vw, 1.5rem);
  --t-h3:     clamp(1.125rem, 1.1rem + 0.1vw, 1.1875rem);
  --t-body:   1.0625rem;
  --t-small:  0.9375rem;
  --t-micro:  0.8125rem;

  --lh-tight: 1.15;
  --lh-body: 1.5;

  /* 8px rhythm. --sp-section is the gap between major sections; --sp-block the
   * gap within one. Two values, used everywhere, so the page has a beat. */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-6: 1.5rem;
  --sp-block: 1rem;
  --sp-section: 2.5rem;

  --measure: 42rem;      /* ~680px: the content column */
  --gutter: 1rem;        /* 24px above 480px, see base.css */

  --radius: 3px;         /* survey stamp, not a pill */
  --hairline: 1px solid var(--basalt-15);
  --focus: var(--seismo-blue);

  --font: "Public Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* QuakeIndex base layer — docs/DESIGN.md §2, §3.
 * One column, left-aligned, all the way down. No sidebar: a sidebar on a page
 * somebody opened ninety seconds after feeling a quake is a second thing to read.
 */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--survey-white);
  color: var(--basalt);
  font-family: var(--font);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  /* Never synthesize weights; we ship 400 and 600 and nothing else. */
  font-synthesis: none;
}

/* Every number on this site is tabular. A magnitude that shifts sideways when it
 * is revised from 4.1 to 3.9 makes the revision look like a glitch. */
.num, td.num, .mag, time, .strip-axis {
  font-variant-numeric: tabular-nums;
}

h1, h2, h3 { line-height: var(--lh-tight); font-weight: 600; margin: 0 0 var(--sp-3); }
h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); margin-top: var(--sp-section); }
h3 { font-size: var(--t-h3); margin-top: var(--sp-6); }
p, ul, ol, table { margin: 0 0 var(--sp-block); }
ul, ol { padding-left: 1.25rem; }
li { margin-bottom: var(--sp-2); }

a { color: var(--seismo-blue); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

/* Focus is never removed. docs/DESIGN.md §6 checks for it. */
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 1px;
}

/* Nothing on this site needs to move. The only animation is Leaflet's own pan. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- shell ---------------------------------------------------------------- */

.skip {
  position: absolute; left: -9999px;
  background: var(--survey-white); color: var(--basalt);
  padding: var(--sp-3) var(--sp-4); z-index: 100;
}
.skip:focus { left: var(--gutter); top: var(--sp-2); }

.wrap {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
@media (min-width: 30em) { :root { --gutter: 1.5rem; } }

/* The map and the activity strip are the only full-bleed elements. */
.bleed { max-width: 56rem; margin: 0 auto; padding: 0 var(--gutter); }

.site-head {
  border-bottom: var(--hairline);
  background: var(--survey-white);
}
.site-head .wrap {
  display: flex; align-items: baseline; gap: var(--sp-4);
  min-height: 3rem; padding-top: var(--sp-3); padding-bottom: var(--sp-3);
  flex-wrap: wrap;
}
.brand {
  font-weight: 600; font-size: 1.0625rem; color: var(--basalt);
  text-decoration: none; letter-spacing: -0.01em;
}
.brand:hover { text-decoration: underline; }
.site-nav { display: flex; gap: var(--sp-4); font-size: var(--t-small); margin-left: auto; }
/* 44px touch targets without making the header 44px tall. */
.site-nav a { padding: 0.6rem 0; }

main { padding: var(--sp-6) 0 var(--sp-section); }

.site-foot {
  border-top: var(--hairline);
  margin-top: var(--sp-section);
  padding: var(--sp-6) 0 var(--sp-section);
  font-size: var(--t-small);
  color: var(--basalt-70);
}
.site-foot a { color: var(--seismo-blue); }
.site-foot nav { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); margin-bottom: var(--sp-4); }

/* --- the evidentiary furniture ------------------------------------------- */

/* Every live value carries one of these. It is not fine print: it is the reason
 * to believe the number. 5.96:1 against the page, checked by CI. */
.source {
  font-size: var(--t-small);
  color: var(--basalt-70);
  margin: var(--sp-2) 0 0;
}
.source a { color: var(--seismo-blue); }

/* A feed that is down renders this, not an empty list and not a confident zero. */
.stale {
  border-left: 3px solid var(--sediment);
  background: var(--basalt-06);
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--t-small);
}

/* --- the answer block ---------------------------------------------------- */

.answer {
  background: var(--basalt-06);
  border-left: 2px solid var(--seismo-blue);
  padding: var(--sp-4);
  border-radius: 0 var(--radius) var(--radius) 0;
  margin: 0 0 var(--sp-6);
}
.answer > :last-child { margin-bottom: 0; }
.answer dl { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-2) var(--sp-4); margin: 0; }
.answer dt { color: var(--basalt-70); font-size: var(--t-small); }
.answer dd { margin: 0; font-variant-numeric: tabular-nums; }

/* The magnitude. Largest thing on the page, and NOT red — red is reserved for
 * felt and significant events, so a page that shouts at every M0.9 has nothing
 * left to say when an M6.4 arrives. docs/DESIGN.md §5 row 1. */
.mag-hero {
  font-size: var(--t-answer);
  font-weight: 600;
  line-height: var(--lh-tight);
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--basalt);
}
.mag-rule { width: 4rem; border: 0; border-top: 2px solid var(--basalt); margin: var(--sp-2) 0 var(--sp-3); }

.felt { color: var(--fault-red); font-weight: 600; }
.quiet, .typical { color: var(--calm-green); font-weight: 600; }
.elevated { color: var(--basalt); font-weight: 600; }
.unusual { color: var(--fault-red); font-weight: 600; }

/* --- tables -------------------------------------------------------------- */

table { border-collapse: collapse; width: 100%; font-size: var(--t-small); }
th, td { text-align: left; padding: var(--sp-2) var(--sp-3) var(--sp-2) 0; border-bottom: var(--hairline); }
th { color: var(--basalt-70); font-weight: 600; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
.scroll-x { overflow-x: auto; }

/* --- the activity strip -------------------------------------------------- */
/* The one place the design spends its boldness. Everything else stays quiet. */
.strip { width: 100%; height: auto; display: block; }
.strip-band { fill: var(--sediment-25); }
.strip-mark { fill: var(--seismo-blue); fill-opacity: 0.75; }
.strip-mark-felt { fill: var(--fault-red); fill-opacity: 0.8; }
.strip-axis { fill: var(--basalt-70); font-size: var(--t-micro); }
.strip-base { stroke: var(--basalt-15); stroke-width: 1; }

/* --- the map ------------------------------------------------------------- */
/* A fixed-height placeholder at the exact final height, so lazy-loading the map
 * cannot shift the text below it. */
.map-slot {
  aspect-ratio: 16 / 10;
  background: var(--sediment-25);
  border: var(--hairline);
  border-radius: var(--radius);
  display: grid; place-items: center;
  color: var(--basalt-70); font-size: var(--t-small);
}
.map-slot .leaflet-container { width: 100%; height: 100%; border-radius: var(--radius); }

/* --- ad slots ------------------------------------------------------------ */
/* Rendered empty until AdSense approves the site. Never inside .answer, never
 * inside .felt-answer, never inside .hazard-result — preflight.py fails the
 * build if a slot appears inside one. */
.ad { margin: var(--sp-section) 0 0; min-height: 0; }
.ad:empty { display: none; }

/* --- forms -------------------------------------------------------------- */
input[type="text"], input[type="search"], select {
  font: inherit; padding: 0.6rem var(--sp-3);
  border: var(--hairline); border-radius: var(--radius);
  background: #fff; color: var(--basalt); min-height: 44px; width: 100%;
}
button {
  font: inherit; font-weight: 600; min-height: 44px;
  padding: 0.6rem var(--sp-6);
  background: var(--seismo-blue); color: #fff;
  border: 0; border-radius: var(--radius); cursor: pointer;
}
button:hover { background: #26496d; }
button.secondary { background: transparent; color: var(--seismo-blue); border: 1px solid var(--seismo-blue); }

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