/* localgovdata.ai — the design system. One file, self-hosted, zero requests.
 *
 * This implements the token and class vocabulary of the seven Grier-approved
 * mocks (GovDataVault/19 Site Mocks, 2026-08-01). The mocks' framework, voice,
 * and structure are the design base; only their invented semantics get replaced.
 *
 * NO WEBFONTS. The mocks loaded Newsreader / Public Sans / IBM Plex Mono from
 * fonts.googleapis.com. A trust brand that leaks its readers to a font host is
 * telling on itself, and the charter forbids third-party assets outright, so
 * the stacks below are system faces only: nothing to host, nothing to license,
 * nothing that phones anywhere, no layout shift. If Grier wants Newsreader
 * specifically, self-hosting subset woff2 files is a follow-up that needs the
 * font files — it is not something to solve with a CDN link.
 */

:root {
  /* ---- ground and structure ---- */
  --paper:      #fbfaf7;   /* page ground */
  --card:       #ffffff;   /* raised surface: measures, cells, table blocks */
  --rule:       #e6e2d9;   /* hairline: row separators, internal grid gaps */
  --rule-2:     #d3cdc1;   /* stronger: the border around a card or panel */

  /* ---- ink ---- */
  --ink:        #1c2321;   /* body and headings */
  --ink-2:      #4a5450;   /* secondary prose */
  /* #78827d was 3.80:1 on paper — below AA for normal text, and this token
   * carries table column labels, captions and fine print. Darkened to
   * 4.56:1, same hue, still clearly lighter than --ink-2. */
  --ink-3:      #6c7570;   /* labels, eyebrows, meta, mono captions */

  /* ---- meaning, never decoration ----
   * Outcome colours come from the mocks' own legend. `condition` is darkened
   * from the mock's #B0761A, which fails contrast as text on paper. */
  --grant:          #4a7a2e;  --grant-pale:      #edf2e6;  /* approved */
  --condition:      #8a5c12;  --condition-pale:  #f8f1e1;  /* approved w/ conditions */
  --regulated:      #a8306b;  --regulated-pale:  #f9eaf1;  /* denied, withdrawn, absent */
  /* Verdigris. Citations, structure, and the one accent the brand allows. */
  --chart:          #2f6b5e;  --chart-pale:      #e6efec;

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --sans:  ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono:  ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, Consolas, monospace;

  --wrap: 68rem;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16.5px;
  line-height: 1.62;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }

/* ---- type ------------------------------------------------------------ */

h1, h2, h3, h4 { font-family: var(--serif); font-weight: 600; line-height: 1.18; margin: 0 0 12px; }
h1 { font-size: clamp(30px, 4.6vw, 44px); letter-spacing: -0.018em; }
h2 { font-size: clamp(23px, 3vw, 30px); letter-spacing: -0.014em; margin-bottom: 14px; }
h3 { font-size: 18px; letter-spacing: -0.005em; }
/* Footer column headings are peers of the page's other sections, so they
 * are h2 in the outline and only look small. Using h4 for the look made
 * every page skip a heading level. */
.foot-grid h2 { font-size: 12px; font-family: var(--mono); font-weight: 500;
                letter-spacing: 0.1em; text-transform: uppercase;
                color: var(--ink-3); margin-bottom: 12px; }

p { margin: 0 0 16px; }
a { color: var(--chart); text-underline-offset: 2px; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }
strong, b { font-weight: 600; }

.lede { font-family: var(--serif); font-size: clamp(18px, 2.2vw, 21px); line-height: 1.5;
        color: var(--ink-2); max-width: 58ch; }
.prose { max-width: 68ch; }
.prose p { color: var(--ink-2); }
.small { font-size: 13.5px; line-height: 1.6; }
.note  { font-size: 13px; color: var(--ink-3); max-width: 72ch; }
.mono  { font-family: var(--mono); font-size: 12.5px; letter-spacing: 0.02em; }

.eyebrow {
  display: block;
  font-family: var(--mono); font-size: 10.5px; font-weight: 500;
  letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--ink-3); margin-bottom: 10px;
}

/* ---- masthead -------------------------------------------------------- */

.site-head { border-bottom: 1px solid var(--rule-2); background: var(--paper);
             position: sticky; top: 0; z-index: 20; }
.site-head .wrap { display: flex; align-items: center; justify-content: space-between;
                   gap: 20px; flex-wrap: wrap; padding-top: 14px; padding-bottom: 14px; }

.brand { display: inline-flex; align-items: baseline; gap: 7px; text-decoration: none; color: var(--ink); }
.brand b { font-family: var(--serif); font-size: 17px; font-weight: 600; letter-spacing: 0.01em; }
.brand span { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.16em;
              text-transform: uppercase; color: var(--chart); }

.site-nav { display: flex; gap: 20px; flex-wrap: wrap; }
.site-nav a { font-size: 13.5px; color: var(--ink-2); text-decoration: none; padding-bottom: 2px;
              border-bottom: 1px solid transparent; }
.site-nav a:hover { color: var(--ink); border-bottom-color: var(--rule-2); }
.site-nav a.on { color: var(--ink); border-bottom-color: var(--chart); }

/* ---- sections -------------------------------------------------------- */

.ruled { border-top: 1px solid var(--rule); padding: 54px 0; }
.ruled.tight { padding: 30px 0; }
.ruled:first-of-type { border-top: 0; }

/* ---- buttons --------------------------------------------------------- */

.btn {
  display: inline-block; font-size: 14px; font-weight: 500;
  padding: 11px 20px; border: 1px solid var(--ink); border-radius: 2px;
  background: var(--ink); color: var(--paper); text-decoration: none;
}
.btn:hover { background: #000; border-color: #000; }
.btn.ghost { background: transparent; color: var(--ink); border-color: var(--rule-2); }
.btn.ghost:hover { background: var(--card); border-color: var(--ink); }

/* ---- grids and cells ------------------------------------------------- */

.grid { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
.grid.c2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid.c3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cell { background: var(--card); padding: 18px 20px; }
.cell .eyebrow { margin-bottom: 6px; }
.cell p:last-child { margin-bottom: 0; }
@media (max-width: 820px) { .grid.c3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .grid.c2, .grid.c3 { grid-template-columns: 1fr; } }

/* ---- panels ---------------------------------------------------------- */

.panel { background: var(--card); border: 1px solid var(--rule-2); padding: 20px 24px; }
.panel h3 { margin-top: 0; }
.panel p:last-child { margin-bottom: 0; }
.panel.flush { padding: 0; }

.aside { border-left: 2px solid var(--chart); background: var(--chart-pale);
         padding: 16px 20px; font-size: 14.5px; color: var(--ink-2); }
.aside p:last-child { margin-bottom: 0; }

/* ---- tables: the ledger ---------------------------------------------- */

.tbl-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tbl { border-collapse: collapse; width: 100%; font-size: 13.5px; }
.tbl th, .tbl td { text-align: left; padding: 10px 16px 10px 0; border-bottom: 1px solid var(--rule);
                   vertical-align: top; }
.tbl th { font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: 0.1em;
          text-transform: uppercase; color: var(--ink-3); border-bottom: 1px solid var(--rule-2);
          white-space: nowrap; }
.tbl td.num, .tbl th.num { text-align: right; font-variant-numeric: tabular-nums; }
.tbl tr:last-child td { border-bottom: 0; }

/* A rate exists, or it does not. Never a hedge in between. */
.rate-yes { color: var(--grant); font-weight: 600; }
.rate-no  { color: var(--ink-3); font-style: italic; }

/* ---- citations as design elements ------------------------------------ */

.cite {
  font-family: var(--mono); font-size: 11.5px; color: var(--chart); text-decoration: none;
  border-bottom: 1px solid var(--chart-pale); white-space: nowrap;
}
.cite:hover { border-bottom-color: var(--chart); }

.chip {
  display: inline-block; font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 3px 7px; border-radius: 2px;
  background: var(--chart-pale); color: var(--chart); border: 1px solid var(--chart-pale);
}
.chip.grant { background: var(--grant-pale); color: var(--grant); border-color: var(--grant-pale); }
.chip.con   { background: var(--condition-pale); color: var(--condition); border-color: var(--condition-pale); }
.chip.reg   { background: var(--regulated-pale); color: var(--regulated); border-color: var(--regulated-pale); }

/* The as-of stamp. Every published number carries one. */
.stamp { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.07em;
         text-transform: uppercase; color: var(--ink-3); }

/* ---- pending: content awaiting real data ----------------------------
 * Anything carrying data-pending is visibly marked in a dev build and is
 * REFUSED by `python build.py --strict`. Placeholders must be loud, and they
 * must be impossible to ship by accident. */
[data-pending] { outline: 1px dashed var(--regulated); outline-offset: 3px; position: relative; }
[data-pending]::after {
  content: "PENDING — " attr(data-pending);
  display: block; margin-top: 8px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--regulated); background: var(--regulated-pale); padding: 4px 7px; border-radius: 2px;
}

/* ---- the scale strip -------------------------------------------------
 * Grier's approved home-page stats. "at least" is set in the accent rather
 * than hidden: on the largest numbers we publish, the floor is the honest
 * part and the last thing that should read as fine print. */
.statstrip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1px;
             background: var(--rule); border: 1px solid var(--rule); }
.statstrip > div { background: var(--card); padding: 18px 20px; }
.statstrip .v { font-family: var(--serif); font-size: 28px; line-height: 1.1;
                font-variant-numeric: tabular-nums; }
.statstrip .atleast { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
                      text-transform: uppercase; color: var(--chart); display: block;
                      margin-bottom: 2px; }
.statstrip .k { font-size: 13px; color: var(--ink); margin-top: 6px; line-height: 1.4; }
.statstrip .k2 { font-size: 12px; color: var(--ink-2); margin-top: 6px; line-height: 1.45; }
@media (max-width: 900px) { .statstrip { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .statstrip { grid-template-columns: 1fr; } }

/* ---- the docket plot ------------------------------------------------
 * A component, so it lives in the design system rather than in one page:
 * it renders on the index page and standalone in preview/, and an
 * unstyled preview is a preview nobody can review. */
/* The docket plot. Drawn at build time — no script on this page or any other. */
.docket{background:var(--card);border:1px solid var(--rule-2);padding:22px 26px 18px;margin-top:36px}
.docket-head{display:flex;justify-content:space-between;align-items:baseline;gap:20px;flex-wrap:wrap}
.docket-head .q{font-family:var(--serif);font-size:19px;letter-spacing:-.01em}
.docket-head .scope{font-family:var(--mono);font-size:10px;letter-spacing:.06em;color:var(--chart)}
.docket .tally{font-size:13.5px;color:var(--ink-2);margin:8px 0 20px}
.docket .tally b{font-family:var(--serif);font-size:18px;font-weight:400;color:var(--ink)}
.plot{position:relative;height:150px;margin-bottom:6px}
.plot .axis{position:absolute;left:0;right:0;top:70px;height:1px;background:var(--ink)}
.plot .years{position:absolute;left:0;right:0;top:78px;height:14px}
.plot .yr{position:absolute;transform:translateX(-50%);font-family:var(--mono);font-size:9px;color:var(--ink-3)}
.tick{position:absolute;width:5px;transform:translateX(-50%);border-radius:1px;display:block}
.tick.up,.tick.cond{bottom:81px;height:44px}
.tick.up{background:var(--grant)}
.tick.cond{background:var(--condition)}
.tick.down{top:71px;height:44px;background:var(--regulated)}
.tick:hover{outline:2px solid var(--ink);outline-offset:1px}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.legend{display:flex;gap:18px;flex-wrap:wrap;padding-top:14px;border-top:1px solid var(--rule);
  font-size:12.5px;color:var(--ink-2);margin:0}
.legend i{display:inline-block;width:9px;height:9px;border-radius:1px;margin-right:6px}
.legend i.up{background:var(--grant)} .legend i.cond{background:var(--condition)}
.legend i.down{background:var(--regulated)}
.legend .src{color:var(--ink-3)}


/* ---- entrance -------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .reveal { animation: rise 620ms cubic-bezier(.2, .7, .3, 1) both; }
  @keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
}

/* ---- footer ---------------------------------------------------------- */

.site-foot { border-top: 1px solid var(--rule-2); margin-top: 20px; padding: 40px 0 48px; }
.foot-grid { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 32px; margin-bottom: 32px; }

.foot-grid a { display: block; font-size: 13.5px; color: var(--ink-2); text-decoration: none;
               margin-bottom: 7px; }
.foot-grid a:hover { color: var(--ink); text-decoration: underline; }
/* The wordmark is a flex row; the rule above would flatten it to a block and
   collapse the gap, printing LOCALGOVDATACHARLESTON. */
.foot-grid .brand { display: inline-flex; }
.foot-grid .brand:hover { text-decoration: none; }
@media (max-width: 720px) { .foot-grid { grid-template-columns: 1fr 1fr; } }

.legal {
  font-family: var(--mono); font-size: 10.5px; line-height: 2; letter-spacing: 0.05em;
  color: var(--ink-3); border-top: 1px solid var(--rule); padding-top: 20px; margin: 0;
}

/* ---- accessibility --------------------------------------------------- */

:focus-visible { outline: 2px solid var(--chart); outline-offset: 2px; }
.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--ink); color: var(--paper); padding: 10px 16px; z-index: 100;
  font-size: 14px; text-decoration: none;
}
.skip:focus { left: 8px; top: 8px; }

/* ---- print ----------------------------------------------------------- */

/* ---- print ------------------------------------------------------------
 * The page most likely to be printed here is the coverage table — someone
 * checking whether we can answer for their jurisdiction before a meeting. It
 * has to survive that intact. */
@media print {
  @page { margin: 15mm 13mm 17mm; }

  /* Secondary ink is tuned for a backlit screen. On paper the same greys go
   * washy, and the ones carrying real content -- a coverage row's reason, a
   * table's units -- are exactly the ones that must stay readable. Darkened
   * here rather than flattened to black, so the hierarchy survives. */
  :root { --ink-2: #1a1a1a; --ink-3: #3d3d3d; --rule: #ccc; --rule-2: #999; }

  body { background: #fff; color: #000; font-size: 10pt; line-height: 1.45; }
  .wrap { max-width: none; padding: 0; }

  /* Navigation is not information on paper. The wordmark is. */
  .site-nav, .btn, .skip, .foot-grid a { display: none !important; }
  .site-head { position: static; border-bottom: 1px solid #000; padding: 0 0 3mm;
               margin-bottom: 8mm; }
  .foot-grid { display: none; }
  .reveal { animation: none !important; }

  h1 { font-size: 18pt; }
  h2 { font-size: 13pt; margin-top: 7mm; }
  h1, h2, h3 { break-after: avoid; page-break-after: avoid; }
  p, li { orphans: 3; widows: 3; }
  .ruled { border-top: 0; padding: 5mm 0; break-inside: auto; }

  a { color: #000; text-decoration: none; }
  .prose a[href^="http"]::after, .cite[href^="http"]::after {
    content: " (" attr(href) ")"; font-family: var(--mono); font-size: 7.5pt;
    word-break: break-all;
  }
  .cite { color: #000; border-bottom: 0; }

  /* The coverage table is the reason this block matters: a scroll container
   * crops columns on paper without telling anyone. */
  .tbl-scroll { overflow: visible !important; }
  .tbl { font-size: 8.5pt; }
  .tbl thead { display: table-header-group; }
  .tbl tr { page-break-inside: avoid; }
  .tbl th { border-bottom: 1px solid #000; }
  .tbl td { border-bottom: 1px solid #ccc; }
  .rate-yes, .rate-no { color: #000; }
  .rate-yes { font-weight: 700; }
  .rate-no { font-style: italic; }

  .panel, .cell, .card, .axis, .corr, .tier { border: 1px solid #999; background: #fff;
                                              break-inside: avoid; page-break-inside: avoid; }
  .grid, .tiers, .terms, .absence, .beliefs, .sources, .tally { border: 1px solid #999; }
  .aside { border-left: 2px solid #000; background: #fff; }

  .legal { border-top: 1px solid #000; color: #000; font-size: 7.5pt;
           break-inside: avoid; }

  /* A placeholder that reached paper is worse than one on screen: nobody can
   * see the build refused it. Make it impossible to mistake for content. */
  [data-pending] { outline: 2px solid #000; }
}
