/* GENERATED by packages/isana_ds/build.sh — edit core/, product/, web/ sources, then re-run. Do not edit. */
/* ────────────────────────────────────────────────────────────────
   ISANA · Design System v3 — CORE TOKENS
   AUTHORED SOURCE — edit here, then run packages/isana_ds/build.sh
   (core.css compiles into ../tokens.css and into the isana.css bundle)

   Rules this file obeys (docs/brand/BRAND_MANIFEST.md):
   · §8.1  N1 ladder in both polarities; absolute N0 is reserved for
           posters/print/plate elevation — it is NOT the UI ground.
   · §3.3  The accent (vermilion) never appears on data surfaces and never
           carries P&L / status meaning.
   · §3.4  Color assists labels; it never speaks alone (C1) — every status
           token is used together with a dot AND a text label.
   · §3.8  Hairline rules are the only ornament.
   · §3.9  No fake depth.

   THEME MECHANICS (4 blocks, in this order):
     1. bare :root                                   → the complete LIGHT set
     2. @media (prefers-color-scheme: dark)
          :root:not([data-theme="light"])            → dark, by system pref
     3. [data-theme="dark"]                          → dark, explicit / scopable
     4. [data-theme="light"]                         → light, explicit / scopable
   Blocks 2–4 override ONLY the mode-dependent tokens. No color is ever
   defined for the first time inside a media / [data-theme] block.

   DELIBERATE ABSENCES (manifest decisions, not oversights):
   · NO shadow tokens        — §3.9 "no fake depth"; elevation is hairline + ground.
   · NO radius scale         — one --radius (2px) only; a scale invites decoration.
   · NO fill/tint tokens     — status is dot + label + text tier, never a wash.
   ──────────────────────────────────────────────────────────────── */

:root {
  /* ── N1 ladder · LIGHT (the paper polarity) ───────────────── */
  --ground:        #FCFCFC;   /* page ground                                   */
  --card:          #FFFFFF;   /* raised surface (card / panel)                 */
  --ink:           #0A0A0A;   /* primary text                                  */
  --ink-2:         #505050;   /* secondary text — THE TEXT FLOOR               */
  /* USAGE RULE — --ink-3 is NON-TEXT ONLY: hairline-adjacent marks, disabled
     glyphs, neutral dots. It does not meet the contrast floor for reading.
     Every caption, label and micro-label uses --ink-2 or darker. */
  --ink-3:         #8E8E8E;
  --hairline:      #E4E4E4;   /* the only ornament (§3.8)                      */

  /* ── Status · DOT tier (fills, ≥9px marks — never text) ───── */
  /* C1: a status color NEVER ships alone. Always dot + label (contract §4). */
  --st-good:       #17A34A;
  --st-warn:       #B8801F;
  --st-crit:       #D24545;

  /* ── Status · TEXT tier (contrast-calibrated for reading) ─── */
  --st-good-text:  #187C44;
  --st-warn-text:  #8F6418;
  --st-crit-text:  #C83232;

  /* ── P&L aliases — resolve through the status text tier ───── */
  /* The sign is always printed by the content (contract §4); the color only
     assists it. Aliases, so P&L and status can never drift apart. */
  --pos-text:      var(--st-good-text);
  --neg-text:      var(--st-crit-text);

  /* ── The accent — one seal, budgeted ──────────────────────── */
  /* USAGE RULE (§3.3 / §5): vermilion is BRAND CHROME ONLY — masthead seal,
     colophon stamp, poster legend margin, link color. It never appears on a
     data surface (dashboard, tables, charts) and never encodes P&L or status.
     Consumers: web/web.css only. product/product.css must not reference it. */
  --vermilion:     #D9432F;   /* the seal fill — identical in both polarities  */
  --vermilion-text:#BC3521;   /* the readable tier (links, plate link)         */

  /* ── Absolute N0 — posters / print / plate ONLY ───────────── */
  /* Mode-independent by definition: §8.1 keeps pure #000/#FFF out of the UI
     so they stay available as the elevation + print channel. Never use these
     as a UI ground; the UI runs N1 (above). */
  --n0-ink:        #000000;
  --n0-ground:     #FFFFFF;

  /* ── Spacing · 4-pt grid ──────────────────────────────────── */
  --sp-1:  4px;
  --sp-2:  8px;
  --sp-3:  12px;
  --sp-4:  16px;
  --sp-5:  20px;
  --sp-6:  24px;
  --sp-8:  32px;
  --sp-10: 40px;
  --sp-12: 48px;
  --sp-16: 64px;

  /* ── Radius — exactly one ─────────────────────────────────── */
  --radius: 2px;

  /* ── Voices (§8.3) — sans on UI chrome · serif where reading is
        the job · mono on EVERY numeral, everywhere ───────────── */
  --font-mono:  "Geist Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-serif: "Newsreader", "Iowan Old Style", Georgia, ui-serif, serif;
  --font-sans:  "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* ── Weights ──────────────────────────────────────────────── */
  --fw-regular:  400;
  --fw-medium:   500;
  --fw-semibold: 600;
  --fw-bold:     700;

  /* ── Type scale ───────────────────────────────────────────── */
  --fs-kicker:   11px;     /* uppercase mono labels                 */
  --fs-data:     12.5px;   /* tables, stats, rows                   */
  --fs-body:     15px;     /* UI prose                              */
  --fs-block:    15px;     /* block titles                          */
  --fs-section:  18px;     /* section titles                        */
  --fs-display:  36px;     /* hero numbers                          */
  --fs-tales:    16.5px;   /* serif reading column (The Tales)      */

  /* ── Tracking ─────────────────────────────────────────────── */
  --tracking-kicker: 0.14em;
}

/* ── 2 · DARK by system preference (opt out with [data-theme="light"]) ── */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground:        #080808;
    --card:          #101011;
    --ink:           #F7F7F7;
    --ink-2:         #ADADAF;
    --ink-3:         #6E6E70;
    --hairline:      #28282B;

    --st-good:       #17A34A;
    --st-warn:       #C9911C;
    --st-crit:       #C84343;

    --st-good-text:  #2FBF6B;
    --st-warn-text:  #D89A2B;
    --st-crit-text:  #EE5D5D;

    /* --vermilion is mode-independent (#D9432F in both polarities) — it is
       defined once in :root and deliberately NOT re-declared here. */
    --vermilion-text:#E86048;
  }
}

/* ── 3 · DARK, explicit — container-scopable ────────────────── */
[data-theme="dark"] {
  --ground:        #080808;
  --card:          #101011;
  --ink:           #F7F7F7;
  --ink-2:         #ADADAF;
  --ink-3:         #6E6E70;
  --hairline:      #28282B;

  --st-good:       #17A34A;
  --st-warn:       #C9911C;
  --st-crit:       #C84343;

  --st-good-text:  #2FBF6B;
  --st-warn-text:  #D89A2B;
  --st-crit-text:  #EE5D5D;

  --vermilion-text:#E86048;
}

/* ── 4 · LIGHT, explicit — the container-scoped light mirror.
      Wrap an absolute-N0 artifact (the daily plate) in this so its
      chrome keeps the light tier even on a dark page. ─────────── */
[data-theme="light"] {
  --ground:        #FCFCFC;
  --card:          #FFFFFF;
  --ink:           #0A0A0A;
  --ink-2:         #505050;
  --ink-3:         #8E8E8E;
  --hairline:      #E4E4E4;

  --st-good:       #17A34A;
  --st-warn:       #B8801F;
  --st-crit:       #D24545;

  --st-good-text:  #187C44;
  --st-warn-text:  #8F6418;
  --st-crit-text:  #C83232;

  --vermilion-text:#BC3521;
}
/* ────────────────────────────────────────────────────────────────
   ISANA · Design System v3 — FONT FACES
   AUTHORED SOURCE — edit here, then run packages/isana_ds/build.sh

   Three voices (BRAND_MANIFEST §8.3):
     Geist Mono  — every numeral, everywhere (variable 100–900)
     Newsreader  — serif, where reading is the job (The Tales) (200–800)
     Public Sans — sans, UI chrome (variable 100–900)

   url() is relative to the COMPILED file, which sits at
   packages/isana_ds/ — so "fonts/woff2/…" resolves for isana.css.
   Sources (ttf + OFL) live in fonts/ttf/; the woff2 files are the
   latin / latin-ext serving subsets. Unicode ranges are the canonical
   Google Fonts subset ranges.
   ──────────────────────────────────────────────────────────────── */

/* ── Geist Mono — roman ─────────────────────────────────────── */
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/woff2/geist-mono-roman-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/woff2/geist-mono-roman-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── Newsreader — roman ─────────────────────────────────────── */
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("fonts/woff2/newsreader-roman-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("fonts/woff2/newsreader-roman-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── Newsreader — italic ────────────────────────────────────── */
@font-face {
  font-family: "Newsreader";
  font-style: italic;
  font-weight: 200 800;
  font-display: swap;
  src: url("fonts/woff2/newsreader-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Newsreader";
  font-style: italic;
  font-weight: 200 800;
  font-display: swap;
  src: url("fonts/woff2/newsreader-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── Public Sans — roman ────────────────────────────────────── */
@font-face {
  font-family: "Public Sans";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/woff2/public-sans-roman-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Public Sans";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/woff2/public-sans-roman-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── Public Sans — italic ───────────────────────────────────── */
@font-face {
  font-family: "Public Sans";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/woff2/public-sans-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Public Sans";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/woff2/public-sans-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* ────────────────────────────────────────────────────────────────
   ISANA · Design System v3 — PRODUCT (data-surface components)
   AUTHORED SOURCE — edit here, then run packages/isana_ds/build.sh

   This layer is the DATA SURFACE: dashboard, tables, reports' data blocks.
   Standing constraints (docs/brand/BRAND_MANIFEST.md):
   · Every value flows through var() — ZERO raw hex here (tests enforce).
   · NO vermilion. The accent is brand chrome only (web/web.css); it never
     appears on a data surface and never carries P&L/status meaning (§3.3).
   · Hairlines are the only ornament (§3.8) — no shadows, no gradients,
     no zebra striping, no fills behind status.
   · Color assists labels, never speaks alone (C1) — every status class is
     built to ship as dot + label (MODULE_CONTRACT §4).
   · Reduction is spent on chrome, never on data (§3.1): air between blocks,
     never inside tables (§3.2).
   ──────────────────────────────────────────────────────────────── */

/* ── Card — the module container (MODULE_CONTRACT §2) ───────── */
.card {
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: var(--sp-5);
}

/* ── Kicker — the mono uppercase module label; ordinals are derived
      from the registry, never hand-numbered (contract §2.2). ───── */
.kicker {
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-kicker);
  color: var(--ink-2); /* text floor — never --ink-3 (non-text only) */
}
/* Kicker + trailing hairline rule — the sub-block separator. */
.kicker-ruled {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.kicker-ruled::after {
  content: "";
  flex: 1 1 auto;
  height: 0;
  border-top: 1px solid var(--hairline);
}

/* ── Titles — sans owns UI chrome; weight is hierarchy, never
      magnitude (§4: the house primitive does not travel to UI). ── */
.section-title {
  font-family: var(--font-sans);
  font-size: var(--fs-section);
  font-weight: var(--fw-semibold);
  color: var(--ink);
  margin: 0;
}
.block-title {
  font-family: var(--font-sans);
  font-size: var(--fs-block);
  font-weight: var(--fw-medium);
  color: var(--ink);
  margin: 0;
}

/* ── Honesty banner — "PAPER · verifies costs/execution/ops, NOT edge".
      A bordered mono chip: the disclosure is chrome, so it is quiet, but
      it is always present on paper surfaces (§10 register). ────── */
.honesty {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  font-weight: var(--fw-regular);
  letter-spacing: var(--tracking-kicker);
  text-transform: uppercase;
  color: var(--ink-2);
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: var(--sp-2) var(--sp-3);
}

/* ── Data table — mono numerals, hairline row rules, no zebra.
      Zebra is ornament; hairlines are the only ornament (§3.8). ── */
table.data {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-mono);
  font-size: var(--fs-data);
  font-variant-numeric: tabular-nums; /* set on the table: every cell aligns */
  color: var(--ink);
}
table.data th {
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--tracking-kicker);
  color: var(--ink-2);
  border-bottom: 1px solid var(--ink); /* the header rule is the strong one */
  padding: var(--sp-2) var(--sp-3);
  text-align: left;
  white-space: nowrap;
}
table.data td {
  border-bottom: 1px solid var(--hairline);
  padding: var(--sp-2) var(--sp-3);
  text-align: left;
}
/* Numeric columns right-align; the first column is the label column. */
table.data th.num,
table.data td.num { text-align: right; }
table.data th:first-child,
table.data td:first-child { text-align: left; }
table.data tbody tr:last-child td { border-bottom: none; }

/* ── KPI tiles ──────────────────────────────────────────────── */
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--sp-4);
}
.tile {
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: var(--sp-4);
}
.tile-label {
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-kicker);
  color: var(--ink-2);
}
.tile-value {
  font-family: var(--font-mono);
  font-size: var(--fs-section);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  margin-top: var(--sp-1);
}
/* Captions read like tertiary information but must NOT use --ink-3:
   --ink-3 is non-text only. The caption tier is --ink-2 at a smaller size. */
.tile-caption {
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  color: var(--ink-2);
  margin-top: var(--sp-1);
}

/* ── Status dots — the DOT tier, always paired with a label (C1) ── */
.dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex: none;
}
.dot-good    { background: var(--st-good); }
.dot-warn    { background: var(--st-warn); }
.dot-crit    { background: var(--st-crit); }
/* Unmapped status renders neutral — never a guessed color (v2 harness lesson). */
.dot-neutral { background: var(--ink-3); }

/* The C1 pairing itself: dot + label, one inline unit. */
.stat {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-data);
  color: var(--ink-2);
}

/* ── Badge — bordered mono chip. Square-ish (var(--radius)), never a
      pill: one radius exists in this system. No fill behind status. ── */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-kicker);
  color: var(--ink-2);
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 2px var(--sp-2);
}
.badge-good { color: var(--st-good-text); }
.badge-warn { color: var(--st-warn-text); }
.badge-crit { color: var(--st-crit-text); }
/* A badge's own dot follows its text tier, so the pair reads as one mark. */
.badge-good .dot { background: var(--st-good-text); }
.badge-warn .dot { background: var(--st-warn-text); }
.badge-crit .dot { background: var(--st-crit-text); }

/* ── P&L — the sign is PRINTED BY THE CONTENT ("+0.41%", "−2.4%").
      Color assists the sign; it never replaces it (C1, contract §4). ── */
.pl-pos { color: var(--pos-text); }
.pl-neg { color: var(--neg-text); }

/* ── Error isolation — a raising module renders in place (contract §2.1) ── */
.errbox {
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--card);
  padding: var(--sp-3);
  font-family: var(--font-mono);
  font-size: var(--fs-data);
  color: var(--ink-2);
}
.errbox-title {
  display: block;
  color: var(--st-crit-text);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-kicker);
  margin-bottom: var(--sp-2);
}

/* ── Shell banners — the shell's, never a module's (contract §2.4) ── */
.halt-banner,
.stale-banner {
  display: block;
  width: 100%;
  box-sizing: border-box;
  font-family: var(--font-mono);
  font-size: var(--fs-data);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-kicker);
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: var(--sp-2) var(--sp-3);
}
.halt-banner  { color: var(--st-crit-text); }
.stale-banner { color: var(--st-warn-text); }

/* ── Row list — hairline separators, no card per row ────────── */
.row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-top: 1px solid var(--hairline);
  font-family: var(--font-mono);
  font-size: var(--fs-data);
  color: var(--ink);
}
.row:first-child { border-top: none; }
.row .meta { color: var(--ink-2); white-space: nowrap; }

/* ── Glance board (MODULE_CONTRACT §1) — the calm page, read from
      across the room. It never grows another table. ───────────── */
.glance-hero {
  text-align: center;
  padding: var(--sp-12) var(--sp-4) var(--sp-6);
}
/* The one number you can read from the couch. */
.gl-big {
  font-family: var(--font-mono);
  font-size: clamp(44px, 7vw, 72px);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  line-height: 1.05;
  color: var(--ink);
}
.gl-day {
  font-family: var(--font-mono);
  font-size: clamp(18px, 2.6vw, 26px);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  margin-top: var(--sp-2);
}
/* The four status facts — DD · VOL · OPS · LOOKS. */
.gl-row {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--sp-8);
  margin-top: var(--sp-6);
  font-family: var(--font-mono);
  font-size: var(--fs-data);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}
.gl-row .i { display: inline-flex; align-items: center; gap: var(--sp-2); }
.gl-row b  { color: var(--ink); font-weight: var(--fw-medium); }
/* Section nav — one hairline, then the four sections. */
.gl-nav {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--sp-6);
  margin-top: var(--sp-6);
  padding: var(--sp-5) 0 var(--sp-2);
  border-top: 1px solid var(--hairline);
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  letter-spacing: var(--tracking-kicker);
  color: var(--ink-2);
}
/* One section: name + a dot+micro-label state line (contract §3, C1). */
.gl-sect {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-1);
}
.gl-sect .name  { color: var(--ink); letter-spacing: 0.16em; }
.gl-sect .state {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: 9px;
  letter-spacing: normal;
  color: var(--ink-2);
}

/* ── Kujira-maku band — black/white blocks, the funeral curtain named
      for the whale's back and belly (§7). HARD STOPS ONLY: this is a
      stripe, not a gradient — no ramp exists between the blocks. ── */
.maku {
  height: 14px;
  background: repeating-linear-gradient(90deg, var(--ink) 0 26px, var(--ground) 26px 52px);
  border-bottom: 1px solid var(--ink);
}

/* ── Utility — mono owns every numeral; this keeps them in column. ── */
.tabular { font-variant-numeric: tabular-nums; }
/* ────────────────────────────────────────────────────────────────
   ISANA · Design System v3 — WEB (brand chrome)
   AUTHORED SOURCE — edit here, then run packages/isana_ds/build.sh

   THIS LAYER IS BRAND CHROME — the ONLY place vermilion may appear
   (BRAND_MANIFEST §3.3 + §5: the accent budget is seal motif + active
   state + link color). NEVER import this layer into a dashboard or any
   other data surface: on data surfaces the accent does not exist.

   Every value flows through var() — ZERO raw hex here (tests enforce).
   Hairlines are the only ornament; no shadows, no gradients.
   ──────────────────────────────────────────────────────────────── */

/* ── Eyebrow — the mono kicker above a document masthead ────── */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-kicker);
  color: var(--ink-2);
}

/* ── Links — one of the three accent slots. Underlined always:
      color assists, it never carries the affordance alone (C1). ── */
a.link,
.link {
  color: var(--vermilion-text);
  text-decoration: underline;
  text-underline-offset: 3px;
}
a.link:focus-visible,
.link:focus-visible {
  outline: 2px solid var(--vermilion);
  outline-offset: 3px;
}

/* ── The seal (§5) — square vermilion field, N0-white glyph.
      Face 勇 is a placeholder; final mark design is M7.
      One impression per surface; dashboards and data surfaces NEVER. ── */
.hanko {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  font-size: 17px;
  line-height: 1;
  flex: none;
  background: var(--vermilion);
  color: var(--n0-ground);
  border-radius: var(--radius);
  transform: rotate(-3deg);
  user-select: none;
}
.hanko-sm { width: 24px; height: 24px; font-size: 13px; }
.hanko-lg { width: 38px; height: 38px; font-size: 21px; }

/* The PRESSED stamp — rotation and offset are seeded per artifact by the
   generator from the artifact's own seed (date / prereg hash), bounded to
   ±8° and to the colophon / corner zone (manifest §5, rule 14). A real
   hanko never lands twice the same way. The impression MAY break the frame
   line of its box — that is the point; on print it never breaks the sheet
   edge. Set --stamp-rot / --stamp-dx / --stamp-dy inline per impression;
   the fallbacks below are the unseeded resting position. */
.hanko-stick {
  position: absolute;
  transform: rotate(var(--stamp-rot, -3deg)) translate(var(--stamp-dx, 0), var(--stamp-dy, 0));
}

/* ── The daily plate (§6) — absolute N0, both polarities identical.
      The plate is a print/poster artifact, not a UI surface, so it uses
      --n0-ink / --n0-ground rather than the N1 ladder. Wrap it in a
      [data-theme="light"] container so its chrome (the plate link) keeps
      the light vermilion tier even when the host page runs dark. ────── */
.plate {
  position: relative; /* the anchor for .hanko-stick */
  background: var(--n0-ground);
  color: var(--n0-ink);
  border: 1px solid var(--n0-ink);
  border-radius: var(--radius);
  padding: var(--sp-6);
}
/* Top line: ISANA · DAILY PLATE № NNNN · date. */
.plate-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-4);
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  text-transform: uppercase;
  letter-spacing: var(--tracking-kicker);
  border-bottom: 1px solid var(--n0-ink);
  padding-bottom: var(--sp-3);
}
/* Legend block: encoding line · stats line · seed line. Provenance is
   printed on the artifact itself, never on a certificate beside it. */
.plate-legend {
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  line-height: 1.7;
  border-top: 1px solid var(--n0-ink);
  margin-top: var(--sp-6);
  padding-top: var(--sp-3);
}
/* The way in, printed INSIDE the frame below the legend ("Enter the ledger →").
   The gate's single accent — the third accent slot. */
.plate-link {
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  text-transform: uppercase;
  letter-spacing: var(--tracking-kicker);
  color: var(--vermilion-text);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ── The Tales — the serif reading column (§8.3: serif where reading
      is the job). 66ch keeps the measure in the editorial band. ──── */
.tales {
  font-family: var(--font-serif);
  font-size: var(--fs-tales);
  line-height: 1.62;
  max-width: 66ch;
  color: var(--ink);
}
.tales h1,
.tales h2 {
  font-family: var(--font-serif);
  font-weight: var(--fw-semibold);
  text-wrap: balance;
}
