/* ============================================================================
   OPHIS · components
   ----------------------------------------------------------------------------
   Everything here resolves through a token in ophis-tokens.css. No literal
   colour appears below except where a value encodes data rather than style.
   ========================================================================== */

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

html {
  /* The A- / A / A+ control moves --zoom; everything sized in rem follows. */
  font-size: calc(16px * var(--zoom));
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

/* A warm, very low-contrast wash so a full-bleed dark page is not a flat void. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(1100px 620px at 12% -8%, rgba(216, 169, 67, 0.055), transparent 62%),
    radial-gradient(900px 560px at 96% 4%, rgba(86, 188, 208, 0.04), transparent 60%);
}

#app { position: relative; z-index: 1; }

h1, h2, h3 { margin: 0; font-weight: 600; line-height: var(--lh-tight); }
p { margin: 0 0 var(--sp-3); max-width: var(--measure); color: var(--prose); }
a { color: var(--cyan); text-underline-offset: 2px; }

:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
  border-radius: var(--r-1);
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------- topbar -- */

.topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  gap: var(--gutter);
  padding: 0 var(--gutter);
  min-height: 58px;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(14px) saturate(1.3);
  border-bottom: 1px solid var(--line);
}

.brand {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 800;
  letter-spacing: 0.1em;
  color: var(--gold-2);
  white-space: nowrap;
}
.brand small {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.08em;
  color: var(--dim);
}

.screens {
  display: flex;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.screens::-webkit-scrollbar { display: none; }

.screens button {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--dim);
  font: 600 var(--fs-btn)/1 var(--font-body);
  letter-spacing: var(--ls-btn);
  text-transform: uppercase;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-1);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
/* The rule between the places and the operations. */
.navrule {
  flex: 0 0 auto;
  align-self: center;
  width: 1px;
  height: 18px;
  margin: 0 var(--sp-2);
  background: var(--line-flat);
}
/* Doing something to the document is secondary to being somewhere in it. */
.screens button[data-kind='data'] { color: var(--faint); font-weight: 500; }
.screens button[data-kind='data']:hover { color: var(--ink); }
.screens button:hover { color: var(--ink); background: var(--panel); }
.screens button[aria-current='page'] {
  color: var(--gold-2);
  background: var(--panel-2);
  box-shadow: inset 0 -2px 0 var(--gold);
}

.chrome { display: flex; align-items: center; gap: var(--sp-2); }

.zoomctl {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: var(--r-1);
  overflow: hidden;
}
.zoomctl button {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--dim);
  font: 600 11px/1 var(--font-mono);
  padding: 6px 9px;
  cursor: pointer;
}
.zoomctl button:hover { background: var(--panel-2); color: var(--ink); }
.zoomctl button + button { border-left: 1px solid var(--line); }

/* Fixed width so flipping Saved <-> Not saved never shifts the layout. */
.savedbadge {
  min-width: 92px;
  text-align: center;
  font: 600 var(--fs-label)/1 var(--font-body);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  padding: 6px var(--sp-2);
  border-radius: var(--r-pill);
  border: 1px solid currentColor;
  color: var(--green);
}
.savedbadge[data-dirty='true'] { color: var(--red); }

/* --------------------------------------------------------------- screens -- */

.screen { display: none; padding: var(--gutter); }
.screen[data-active='true'] { display: block; }

.screen-head { margin-bottom: var(--sp-5); }
.eyebrow {
  font: 600 var(--fs-eyebrow)/1 var(--font-body);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: var(--sp-2);
}
.screen-head h1 {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  color: var(--ink);
}
/* The heading is focused on a screen change so a screen reader announces it.
   That is a programmatic focus, not a keyboard one, so it takes no ring. */
.screen-head h1:focus { outline: none; }
.screen-head .lede { margin-top: var(--sp-2); color: var(--dim); font-size: var(--fs-ui); }

/* The working surface: a control rail beside the output. On the original this
   was four cramped panels stacked above the table, each two rows tall. */
.work {
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr);
  gap: var(--gutter);
  align-items: start;
}

.rail {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  position: sticky;
  top: calc(58px + var(--gutter));
  max-height: calc(100vh - 58px - var(--gutter) * 2);
  overflow-y: auto;
  padding-right: 4px;
}
/* Flex children in a scrolling column must not shrink, or every panel is
   squeezed to fit and the last few lose their content. */
.rail > * { flex: 0 0 auto; }
.output { display: flex; flex-direction: column; gap: var(--gutter); min-width: 0; }

/* ---------------------------------------------------------------- panels -- */

/* ---------------------------------------------------------------- surfaces --
   Three roles, three treatments. Everything on the working surface used to be
   one rectangle -- same fill, same gold hairline, same radius, same glow -- so
   the rail of inputs, the readout and the chart all claimed equal weight and
   the eye had nowhere to land.

   Gold had the same problem. It marked the nav's active tab, every button,
   every panel edge, the arcs, the pills and the checkboxes, which is six jobs
   and therefore none: an accent that outlines everything cannot also mean
   "this one". Borders are neutral from here. Gold now means live or chosen --
   the current screen, the primary action, an enabled control -- and the chart
   keeps its own hit-count ramp, which encodes data rather than emphasis.     */

.panel {
  background: var(--panel);
  border: 1px solid var(--line-flat);
  border-radius: var(--r-2);
  overflow: hidden;
}

.panel > header {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line-flat);
  background: transparent;
}
/* The mono, not the serif. EB Garamond has a small x-height and delicate
   strokes; uppercased, tracked to 0.18em and set at 11.5px it turns to mush,
   which is what ISO-EVENTS, X-DATES and TIMELINE looked like. IBM Plex Mono is
   drawn for exactly this job and holds its shape at the size. Cinzel and
   Garamond keep the headings and the prose, where they are handsome. */
.panel > header h3 {
  font: 500 var(--fs-h3)/1 var(--font-mono);
  letter-spacing: var(--ls-h3);
  text-transform: uppercase;
  color: var(--gold);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.panel > header .count {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--faint);
  letter-spacing: 0;
}
.panel > header .spacer { margin-left: auto; display: flex; gap: 4px; align-items: center; }
.panel .body { padding: var(--sp-3) var(--sp-4) var(--sp-4); }
/* These carry the explanations a first-time reader needs -- what an Iso-Event
   is, why two X-Dates are the minimum -- and they were the least readable text
   on the surface: 12px Garamond at 5.2:1. Prose at 13.5px is 10.6:1. */
.panel .note {
  font-size: 13.5px;
  color: var(--prose);
  margin: 0 0 var(--sp-3);
  line-height: 1.55;
}

/* A scrollable list that shows roughly two rows before it scrolls, as the
   original's panels did — but with a real scrollbar and a fade at the edge. */
.rowlist {
  display: flex;
  flex-direction: column;
  gap: 5px;
  max-height: 220px;
  overflow-y: auto;
  margin-bottom: var(--sp-3);
}
.rowlist.tall { max-height: 320px; }
/* On a screen of its own a list has the page to scroll in and needs no cap. */
.rowlist.full { max-height: none; overflow: visible; }

.row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 7px var(--sp-2) 7px var(--sp-3);
  background: var(--panel-2);
  border: 1px solid var(--line-flat);
  border-radius: var(--r-2);
  font-size: var(--fs-ui);
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.row:hover { border-color: var(--line-2); }
.row[data-off='true'] { opacity: var(--opacity-disabled); }
.row[data-current='true'] {
  border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) 8%, var(--panel-2));
}
.row .tag {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--gold);
  min-width: 22px;
}
.row .grow { flex: 1 1 auto; min-width: 0; }
.row .sub { font-size: 11px; color: var(--dim); }

.rowerr { color: var(--red); font-size: 11px; min-height: 14px; margin-top: 2px; }

/* ------------------------------------------------------------ form fields -- */

.field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.field > label {
  font: 600 var(--fs-label)/1 var(--font-body);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--dim);
}

input[type='text'], input[type='number'], input[type='time'], select, textarea {
  width: 100%;
  background: var(--well);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--r-1);
  padding: 7px 9px;
  font: 400 var(--fs-ui)/1.3 var(--font-mono);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
input:hover, select:hover, textarea:hover { border-color: var(--line-2); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--cyan);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cyan) 22%, transparent);
}
input:disabled, select:disabled { opacity: var(--opacity-disabled); cursor: not-allowed; }
input[aria-invalid='true'] { border-color: var(--red); }
textarea { font-family: var(--font-body); resize: vertical; min-height: 90px; }
select { cursor: pointer; }

.formrow { display: flex; gap: var(--sp-2); align-items: flex-end; flex-wrap: wrap; }
.formrow .field { flex: 1 1 90px; }
.formrow .field.narrow { flex: 0 0 64px; }
.formrow .field.wide { flex: 1 1 100%; }

/* Checkbox and radio, restyled so they read at the same weight as the text. */
input[type='checkbox'], input[type='radio'] {
  appearance: none;
  width: 15px; height: 15px;
  flex: 0 0 15px;
  margin: 0;
  border: 1px solid var(--line-2);
  border-radius: 3px;
  background: var(--well);
  display: grid;
  place-content: center;
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
input[type='radio'] { border-radius: 50%; }
input[type='checkbox']:checked, input[type='radio']:checked {
  background: var(--gold);
  border-color: var(--gold);
}
input[type='checkbox']:checked::after {
  content: '';
  width: 8px; height: 4px;
  border: 2px solid var(--on-accent);
  border-top: 0; border-right: 0;
  transform: translateY(-1px) rotate(-45deg);
}
input[type='radio']:checked::after {
  content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--on-accent);
}
input[type='checkbox']:indeterminate { background: var(--gold); border-color: var(--gold); }
input[type='checkbox']:indeterminate::after {
  content: ''; width: 8px; height: 2px; background: var(--on-accent); border: 0; transform: none;
}

.check {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-ui);
  cursor: pointer;
  padding: 5px 0;
}
.check span { color: var(--prose); }
.check input:disabled + span { opacity: var(--opacity-disabled); }

/* --------------------------------------------------------------- buttons -- */

.btn {
  appearance: none;
  cursor: pointer;
  border: 1px solid var(--line-2);
  background: var(--raised);
  color: var(--ink);
  border-radius: var(--r-1);
  padding: 7px 13px;
  font: 600 var(--fs-btn)/1 var(--font-body);
  letter-spacing: var(--ls-btn);
  text-transform: uppercase;
  white-space: nowrap;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
              color var(--dur) var(--ease), transform var(--dur-fast) var(--ease);
}
.btn:hover { border-color: var(--gold); color: var(--gold-2); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: var(--opacity-disabled); cursor: not-allowed; transform: none; }
.btn:disabled:hover { border-color: var(--line-2); color: var(--ink); }

.btn.sm { padding: 4px 8px; font-size: 10px; }
.btn.icon { padding: 5px 7px; font-family: var(--font-mono); letter-spacing: 0; }
.btn.primary {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--on-accent);
}
.btn.primary:hover { background: var(--gold-2); border-color: var(--gold-2); color: var(--on-accent); }
.btn.danger:hover { border-color: var(--red); color: var(--red); }

.btn.cast {
  width: 100%;
  padding: 13px;
  font-size: 13px;
  letter-spacing: 0.14em;
  background: linear-gradient(180deg, var(--gold), color-mix(in srgb, var(--gold) 76%, #000));
  border-color: var(--gold);
  color: var(--on-accent);
  box-shadow: 0 0 30px -10px var(--gold);
}
.btn.cast:hover { filter: brightness(1.08); }

.btnrow { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

/* Segmented control — used for scope, scoring system, theme. */
.segmented {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: var(--r-1);
  overflow: hidden;
  background: var(--well);
}
.segmented button {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--dim);
  font: 600 10px/1 var(--font-body);
  letter-spacing: var(--ls-btn);
  text-transform: uppercase;
  padding: 7px 11px;
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.segmented button + button { border-left: 1px solid var(--line); }
.segmented button:hover { color: var(--ink); }
.segmented button[aria-pressed='true'] { background: var(--gold); color: var(--on-accent); }

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

.tablewrap {
  overflow-x: auto;
  border-radius: var(--r-3);
  border: 1px solid var(--line);
  background: var(--panel);
  box-shadow: var(--glow);
}

table { width: 100%; border-collapse: collapse; font-size: var(--fs-table); }
caption { text-align: left; padding: var(--sp-3) var(--sp-4); color: var(--dim); font-size: 12px; }

thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--panel-2);
  border-bottom: 1px solid var(--line-2);
  padding: var(--sp-3) var(--sp-3);
  text-align: left;
  font: 700 var(--fs-th)/1 var(--font-body);
  letter-spacing: var(--ls-th);
  text-transform: uppercase;
  color: var(--gold);
  white-space: nowrap;
}
thead th button {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
thead th button:hover { color: var(--gold-2); }
/* Colour is never the only signal: the active sort shows an arrow too. */
thead th[aria-sort] button { color: var(--gold-2); }
thead th .arrow { font-family: var(--font-mono); font-size: 9px; opacity: 0; }
thead th[aria-sort] .arrow { opacity: 1; }

tbody td {
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--line-flat);
  vertical-align: top;
  color: var(--prose);
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr { transition: background var(--dur-fast) var(--ease); }
tbody tr:hover { background: var(--panel-2); }

/* A result row opens the audit. Say so: the table header promises "click a row
   to audit it", and without a cursor, a hover lift and a focus ring the row
   looks like static output. */
tbody tr.hit { cursor: pointer; }
tbody tr.hit:hover { background: color-mix(in srgb, var(--gold) 7%, var(--panel-2)); }
tbody tr.hit:focus-visible {
  outline: none;
  background: color-mix(in srgb, var(--gold) 9%, var(--panel-2));
  box-shadow: inset 2px 0 0 var(--gold);
}
tbody tr[data-highlight='true'] {
  background: color-mix(in srgb, var(--gold) 11%, transparent);
  box-shadow: inset 2px 0 0 var(--gold);
}

td.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; text-align: right; }
td.zlabel {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--faint);
  white-space: nowrap;
}
.hidden-col { visibility: hidden; }

.datepill {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink);
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--r-1);
  padding: 3px 7px;
  white-space: nowrap;
  display: inline-block;
}

/* Hit-count glyph. The shape carries the count as well as the number does, so
   the column is readable at a glance and without colour. */
.hits { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); }
.hits .glyph { font-size: 13px; line-height: 1; }
.hits[data-n='3'] .glyph { color: var(--hits-3); }
.hits[data-n='4'] .glyph { color: var(--hits-4); }
.hits[data-n='5'] .glyph { color: var(--hits-5plus); }

.scorecell { display: flex; flex-direction: column; gap: 3px; min-width: 58px; }
.scorecell b { font: 600 13px/1 var(--font-mono); color: var(--ink); }
.scoremeter { height: 3px; border-radius: 2px; background: var(--line-flat); overflow: hidden; }
.scoremeter i { display: block; height: 100%; background: var(--gold); }

/* ----------------------------------------------------------------- pills -- */

.pills { display: flex; flex-wrap: wrap; gap: 4px; max-height: 62px; overflow-y: auto; }

.pill {
  font-family: var(--font-mono);
  font-size: var(--fs-pill);
  line-height: 1;
  padding: 4px 7px;
  border-radius: var(--r-pill);
  border: 1px solid currentColor;
  background: color-mix(in srgb, currentColor 12%, transparent);
  white-space: nowrap;
  cursor: default;
}
.pill.normal    { color: var(--msrf-normal); }
.pill.important { color: var(--msrf-important); }
.pill.vortex    { color: var(--msrf-vortex); }
.pill.alpha     { color: var(--op-alpha); }
.pill.beta      { color: var(--op-beta); }
.pill sub { font-size: 8px; }

/* --------------------------------------------------------------- tooltip -- */

.tip {
  position: fixed;
  z-index: var(--z-pop);
  max-width: 340px;
  background: var(--raised);
  border: 1px solid var(--line-2);
  border-radius: var(--r-2);
  box-shadow: var(--shadow-pop);
  padding: var(--sp-3);
  font-size: 11.5px;
  color: var(--prose);
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.tip[data-show='true'] { opacity: 1; }
.tip dl { display: grid; grid-template-columns: auto 1fr; gap: 3px var(--sp-3); margin: 0; }
.tip dt { color: var(--dim); font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; }
.tip dd { margin: 0; font-family: var(--font-mono); font-size: 11px; color: var(--ink); }

/* ------------------------------------------------------------ status bar -- */

/* The readout is the one thing worth looking at before anything else, so it
   is the only surface that carries the gold hairline and sits raised. */
.statusbar {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  flex-wrap: wrap;
  padding: var(--sp-4) var(--sp-5);
  background: linear-gradient(180deg, var(--raised), var(--panel));
  border: 1px solid var(--line-2);
  border-radius: var(--r-3);
  box-shadow: var(--glow);
  font-size: var(--fs-ui);
}
.statusbar .grow { flex: 1 1 auto; }
.statusbar .stat { display: flex; align-items: baseline; gap: 6px; }
.statusbar .stat b {
  font: 500 22px/1 var(--font-mono);
  color: var(--gold-2);
  font-variant-numeric: tabular-nums;
}
.statusbar .stat span {
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--dim);
}
.statusbar .state { font-family: var(--font-mono); font-size: 11px; color: var(--green); }
.statusbar .state[data-stale='true'] { color: var(--red); }

/* Results dim rather than re-render when inputs change: what is on screen stays
   honest, and a slow recalculation never shows half-updated rows. */
.stale { opacity: 0.5; transition: opacity var(--dur) var(--ease); }

/* ------------------------------------------------------------ empty state -- */

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-8) var(--sp-4);
  text-align: center;
  color: var(--dim);
}
.empty .mark { font-size: 30px; color: var(--faint); }
.empty h3 { font-family: var(--font-display); font-size: 17px; color: var(--ink); }
.empty p { max-width: 42ch; margin: 0; font-size: var(--fs-ui); }

.banner {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-2);
  border: 1px solid var(--red);
  background: color-mix(in srgb, var(--red) 10%, transparent);
  color: var(--ink);
  font-size: var(--fs-ui);
  margin-bottom: var(--sp-4);
}
.banner ul { margin: 4px 0 0; padding-left: 18px; }

/* ----------------------------------------------------------------- chart -- */

/* Recessed, not boxed. The arcs are the signature image of this instrument and
   they were sitting in the same card as a list of date inputs. */
.chartpanel { position: relative; background: var(--well); }
.chartpanel canvas { display: block; width: 100%; height: 420px; }
.chartbar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-top: 1px solid var(--line-flat);
  font-size: 11px;
  color: var(--dim);
}
.chartbar .grow { flex: 1 1 auto; }

/* The timeline takes wheel and drag gestures, so it says so with its cursor. */
.chartpanel canvas { cursor: crosshair; touch-action: none; }
.chartpanel canvas[data-panning] { cursor: grabbing; }
.chartpanel header .spacer { display: flex; align-items: center; gap: var(--sp-3); }
.legend { display: flex; gap: var(--sp-3); flex-wrap: wrap; font-family: var(--font-mono); font-size: 10px; }
.legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 5px; }

/* --------------------------------------------------------------- dialogs -- */

dialog {
  border: 1px solid var(--line-2);
  border-radius: var(--r-3);
  background: var(--panel);
  color: var(--ink);
  padding: 0;
  max-width: min(560px, 92vw);
  box-shadow: var(--shadow-pop);
}
dialog::backdrop { background: var(--scrim); backdrop-filter: blur(3px); }
dialog header { padding: var(--sp-4); border-bottom: 1px solid var(--line); }
dialog header h3 { font-family: var(--font-display); font-size: 16px; }
dialog .body { padding: var(--sp-4); font-size: var(--fs-ui); color: var(--prose); }
dialog footer { display: flex; justify-content: flex-end; gap: var(--sp-2); padding: var(--sp-4); border-top: 1px solid var(--line); }

/* ---------------------------------------------------------- map picker -- */

.mapdlg { max-width: min(1040px, 96vw); width: 1040px; }
.mapdlg header { display: flex; align-items: center; gap: var(--sp-2); }
.mapdlg header .grow { flex: 1 1 auto; }
.mapdlg .body { padding: var(--sp-4); }
.mapdlg .note { margin: var(--sp-3) 0 0; font-size: 11px; color: var(--dim); max-width: none; }

.mapzoom {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--dim);
  min-width: 22px;
  text-align: center;
}

.mapsurface {
  position: relative;
  overflow: hidden;
  height: min(58vh, 520px);
  border: 1px solid var(--line-2);
  border-radius: var(--r-2);
  background: var(--map-sea);
  cursor: crosshair;
  touch-action: none;
  user-select: none;
}
.mapsurface:focus-visible { outline: none; box-shadow: var(--glow-focus); }

/* The shipped tiles are a bright political basemap. In a dark room they are the
   only thing on screen with a white ground, so they get tinted into the palette
   rather than left to glare. `--map-tint` is `none` under a light theme. */
.maptiles { position: absolute; inset: 0; filter: var(--map-tint); }
.maptiles img {
  position: absolute;
  top: 0;
  left: 0;
  width: 256px;
  height: 256px;
  image-rendering: auto;
  pointer-events: none;
}
/* A tile that is not in the shipped rows leaves the ground showing, rather
   than a broken-image glyph. */
.maptiles img.missing { visibility: hidden; }

.mapoverlay { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }

.maphud {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
  font-family: var(--font-mono);
  font-size: var(--fs-ui);
  color: var(--prose);
}
.maphud b { color: var(--gold-2); font-weight: 500; white-space: pre; }
.maphud .sep { color: var(--faint); }

@media (max-width: 720px) {
  .mapsurface { height: 46vh; }
}

/* ---------------------------------------------------------------- toasts -- */

.toasts {
  position: fixed;
  bottom: var(--sp-5);
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  align-items: center;
  pointer-events: none;
}
.toast {
  background: var(--raised);
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  padding: 9px var(--sp-4);
  font-size: var(--fs-ui);
  color: var(--ink);
  box-shadow: var(--shadow-pop);
  animation: rise var(--dur) var(--ease);
}
@keyframes rise { from { opacity: 0; transform: translateY(8px); } }

/* -------------------------------------------------------------- prose/doc -- */

.doc { max-width: var(--measure); }
.doc h2 {
  font-family: var(--font-display);
  font-size: 17px;
  color: var(--gold-2);
  margin: var(--sp-6) 0 var(--sp-3);
}
.doc h2:first-child { margin-top: 0; }
.doc code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--well);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 1px 5px;
}
.doc dl { display: grid; grid-template-columns: minmax(140px, auto) 1fr; gap: var(--sp-2) var(--sp-4); }
.doc dt { font-family: var(--font-mono); font-size: 12px; color: var(--gold); }
.doc dd { margin: 0; font-size: var(--fs-ui); color: var(--prose); }

pre.blob {
  background: var(--well);
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  padding: var(--sp-3);
  overflow: auto;
  max-height: 380px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--prose);
  white-space: pre-wrap;
  word-break: break-word;
}

.logfeed { display: flex; flex-direction: column; gap: 2px; max-height: 320px; overflow-y: auto; }
.logline {
  display: flex;
  gap: var(--sp-3);
  padding: 5px var(--sp-2);
  font-family: var(--font-mono);
  font-size: 11px;
  border-bottom: 1px solid var(--line-flat);
}
.logline time { color: var(--faint); flex: 0 0 66px; }
.logline .kind { flex: 0 0 84px; color: var(--gold); text-transform: uppercase; font-size: 9.5px; letter-spacing: 0.1em; }
.logline p { margin: 0; color: var(--prose); }

/* ------------------------------------------------------------ responsive -- */

@media (max-width: 1080px) {
  .work { grid-template-columns: 1fr; }
  .rail { position: static; max-height: none; }
}

/* The nav needs 732px of its own. Beside a 265px brand and a 439px chrome
   cluster that is 1436px before any gutters, so on anything narrower the tail
   of the nav was quietly cut off: About went first, then Audit, then Z-Dates.
   About is where the build stamp and Clear saved data live -- the screen you
   want most on the day something looks wrong -- and at 1280px, which is most
   laptops, it could not be reached at all.

   Shaving pixels off the brand bought one breakpoint and lost the next, so the
   nav takes its own full-width row instead, well before it runs out of room.
   Measured at 1152, 1280, 1366 and 1440: nothing cut at any of them. */
@media (max-width: 1500px) {
  .topbar { flex-wrap: wrap; min-height: auto; padding-block: var(--sp-2); }
  .screens { order: 3; width: 100%; }
}

@media (max-width: 880px) {
  :root { --gutter: 12px; }

  /* Narrow enough that even a full row will not hold nine items. Scroll the row
     on its own rather than letting it take the document sideways, which is what
     put the saved badge off the right edge. */
  .screens {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }
  .screens::-webkit-scrollbar { display: none; }
  .screens button { flex: 0 0 auto; }

  /* Wrap rather than clip, so the badge stays on screen. */
  .chrome { flex-wrap: wrap; row-gap: var(--sp-2); }

  .chartpanel canvas { height: 260px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
