/* Wellington emergency GIS catalogue — station-log visual language.
   Everything numeric is monospace; identifiers read as survey references.

   Layout rule: the page itself never scrolls. Header is fixed, the index and
   the record each scroll independently, and every panel that fills in later
   (map, image, payload) has its space reserved up front — so nothing moves
   under the reader's cursor. */

:root {
  --paper:      #eef1ee;
  --paper-2:    #e4e8e4;
  --card:       #f8faf8;
  --ink:        #14201c;
  --ink-2:      #4a5a54;
  --ink-3:      #7d8c86;
  --rule:       #ccd5d0;
  --rule-2:     #b3bfb9;
  --live:       #b8420f;
  --sea:        #1f4e5f;
  --ok:         #2f6b4f;
  --dead:       #99231b;
  --amber:      #b06c10;

  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --sans: "IBM Plex Sans", system-ui, -apple-system, sans-serif;
  --cond: "IBM Plex Sans Condensed", "IBM Plex Sans", system-ui, sans-serif;

  --header-h: 82px;
  --media-h: 340px;      /* reserved for the map / rendered image */
  --payload-h: 240px;    /* reserved for the response body */
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  overflow: hidden;            /* panes scroll, the page does not */
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.55;
  display: flex;
  flex-direction: column;
}

a { color: var(--sea); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--live); }
:focus-visible { outline: 2px solid var(--live); outline-offset: 2px; }

/* ---------------------------------------------------------------- header */

.masthead {
  flex: 0 0 auto;
  position: relative;
  z-index: 1200;          /* above Leaflet's controls (1000) */
  height: var(--header-h);
  display: flex;
  align-items: stretch;
  gap: 0;
  border-bottom: 1px solid var(--ink);
  background: var(--card);
}

.brand {
  flex: 0 0 auto;
  padding: 12px 20px;
  border-right: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 260px;
}

.eyebrow {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 2px;
}

h1 {
  font-family: var(--cond);
  font-weight: 600;
  font-size: 25px;
  line-height: 1;
  letter-spacing: -0.015em;
  margin: 0;
}

.gauge-strip {
  flex: 1 1 auto;
  display: flex;
  min-width: 0;
  overflow: hidden;
  font-family: var(--mono);
}

.gauge {
  flex: 1 1 0;
  min-width: 0;
  padding: 13px 16px;
  border-right: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.gauge-label {
  color: var(--ink-3);
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gauge-value {
  font-size: 18px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  min-height: 25px;               /* holds its line before the value lands */
}
.gauge-value .unit { font-size: 11px; color: var(--ink-3); margin-left: 3px; }
.gauge.pending .gauge-value { color: var(--ink-3); }
/* A reading that is real but old — shown, never presented as live. */
.gauge.stale .gauge-value { color: var(--ink-3); text-decoration: line-through; }
.gauge.stale .gauge-label { color: var(--dead); }
.gauge.pending .gauge-value::after { content: "▊"; animation: blink 1.1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

.masthead-actions {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 16px;
}
a.ghost { text-decoration: none; display: inline-block; }

.ghost {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 8px 13px;
  border: 1px solid var(--ink);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
}
.ghost:hover { background: var(--ink); color: var(--paper); }
.ghost:disabled { opacity: .5; cursor: progress; }

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

.shell {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: 340px 1fr;
}

.index {
  position: relative;
  z-index: 1050;
  border-right: 1px solid var(--rule);
  background: var(--card);
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.record {
  background: var(--card);
  overflow-y: auto;
  overscroll-behavior: contain;
  min-height: 0;
  padding-bottom: 50px;
}

/* --------------------------------------------------------------- filters */

.controls { padding: 12px; border-bottom: 1px solid var(--rule); flex: 0 0 auto; }

.search {
  width: 100%;
  font-family: var(--mono);
  font-size: 13px;
  padding: 8px 10px;
  border: 1px solid var(--rule-2);
  background: var(--paper);
  color: var(--ink);
  border-radius: 0;
}
.search::placeholder { color: var(--ink-3); }

.chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 9px; }

.chip {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 4px 7px;
  border: 1px solid var(--rule-2);
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
}
.chip:hover { border-color: var(--ink-2); }
.chip[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }

.tally {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
  padding: 7px 12px;
  border-bottom: 1px solid var(--rule);
  margin: 0;
  flex: 0 0 auto;
}

/* ------------------------------------------------------------------ list */

.list { overflow-y: auto; overscroll-behavior: contain; flex: 1 1 auto; min-height: 0; }

.row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  align-items: center;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  border: none;
  border-bottom: 1px solid var(--paper-2);
  border-left: 3px solid transparent;
  background: transparent;
  cursor: pointer;
  font: inherit;
  color: inherit;
}
.row:hover { background: var(--paper); }
.row[aria-current="true"] { background: var(--paper); border-left-color: var(--live); }

.row-main { min-width: 0; }
.row-id { font-family: var(--mono); font-size: 11px; color: var(--ink-3); display: block; }
.row[aria-current="true"] .row-id { color: var(--live); }
.row-title {
  font-family: var(--cond); font-size: 15px; font-weight: 500;
  line-height: 1.2; display: block;
}
.row-meta {
  font-family: var(--mono); font-size: 10px; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: 0.05em;
}

/* status dot from the endpoint check — fixed slot so rows never resize */
.dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; background: transparent; }
.dot.ok { background: var(--ok); }
.dot.fail { background: var(--dead); }
.dot.skip { background: var(--rule-2); }
.dot.busy { background: var(--amber); animation: blink .8s steps(1) infinite; }

/* ---------------------------------------------------------------- record */

.record-head {
  padding: 14px clamp(16px, 2.5vw, 28px) 0;
  position: sticky;
  top: 0;
  background: var(--card);
  z-index: 1100;          /* above Leaflet's panes (400) and controls (1000) */
  border-bottom: 1px solid var(--rule);
  padding-bottom: 10px;
  max-height: 40vh;        /* never let identity crowd out the content */
  overflow: hidden;
}

.record h2 {
  font-family: var(--cond); font-weight: 600;
  font-size: 24px; line-height: 1.12; margin: 2px 0 7px; letter-spacing: -0.01em;
}
.record-id { font-family: var(--mono); font-size: 12px; color: var(--live); letter-spacing: 0.04em; margin: 0; }
.desc { max-width: 78ch; color: var(--ink-2); margin: 0; }
.desc.clamped {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.more {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.05em;
  text-transform: uppercase; background: none; border: none; padding: 6px 0 0;
  color: var(--sea); cursor: pointer;
}
.more:hover { color: var(--live); }

.badges { display: flex; flex-wrap: wrap; gap: 5px; }
.badge {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em;
  text-transform: uppercase; padding: 3px 7px;
  border: 1px solid var(--rule-2); color: var(--ink-2);
}
.badge.live  { border-color: var(--ok);    color: var(--ok); }
.badge.dead  { border-color: var(--dead);  color: var(--dead); }
.badge.group { border-color: var(--amber); color: var(--amber); }

.note {
  border-left: 3px solid var(--amber);
  background: var(--paper);
  padding: 10px 13px;
  font-size: 14px;
  color: var(--ink-2);
  max-width: 80ch;
}
.note strong { color: var(--ink); }

section.block { padding: 20px clamp(16px, 2.5vw, 28px) 0; }

/* Two columns once there is room. The console goes right, so it is on screen
   without scrolling; reference material goes left at a readable measure. */
.record-cols { display: block; }
.col-main, .col-side { min-width: 0; }

@media (min-width: 1180px) {
  .record-cols {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(430px, 46%);
    gap: 0 clamp(8px, 1.5vw, 24px);
    align-items: start;
  }
  .col-side {
    position: sticky;
    top: 0;
    padding-right: clamp(16px, 2.5vw, 28px);
  }
  .col-side section.block { padding-right: 0; }
  .col-main section.block { padding-right: 0; }
  /* prose stays readable rather than stretching the full column */
  .col-main .desc, .col-main .note { max-width: 68ch; }
}

h3 {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--ink-3);
  border-bottom: 1px solid var(--rule); padding-bottom: 5px;
  margin: 0 0 11px; font-weight: 500;
}

.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 1px; background: var(--rule); border: 1px solid var(--rule); margin: 0; }
.fact { background: var(--card); padding: 7px 10px; }
.fact dt { font-family: var(--mono); font-size: 10px; letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-3); margin: 0; }
.fact dd { margin: 2px 0 0; font-size: 14px; }

.endpoint {
  font-family: var(--mono); font-size: 12px;
  background: var(--ink); color: #dfe6e2;
  padding: 10px 12px; overflow-x: auto;
  white-space: pre-wrap; word-break: break-all; line-height: 1.5;
}

/* --------------------------------------------------------- shape / types */

.shape {
  font-family: var(--mono); font-size: 12px; line-height: 1.7;
  background: var(--paper); border: 1px solid var(--rule); padding: 11px 13px;
  white-space: pre; overflow-x: auto; margin: 0;
}
.shape .key { color: var(--sea); }
.shape .t { color: var(--ink-3); }

table.fields { width: 100%; border-collapse: collapse; font-size: 13px; }
table.fields th {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-3); text-align: left;
  border-bottom: 1px solid var(--rule); padding: 5px 8px 5px 0; font-weight: 500;
}
table.fields td { padding: 4px 8px 4px 0; border-bottom: 1px solid var(--paper-2); vertical-align: top; }
table.fields td.name { font-family: var(--mono); font-size: 12px; }
table.fields td.type { font-family: var(--mono); font-size: 11px; color: var(--ink-3); white-space: nowrap; }
.fields-scroll { max-height: 260px; overflow-y: auto; border-bottom: 1px solid var(--rule); }

/* -------------------------------------------------------------- console */

.console { border: 1px solid var(--ink); background: var(--card); }

.console-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 11px; border-bottom: 1px solid var(--rule); background: var(--paper);
}

.run {
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em;
  text-transform: uppercase; padding: 7px 14px;
  border: 1px solid var(--live); background: var(--live); color: #fff; cursor: pointer;
}
.run:hover:not(:disabled) { background: #96350c; border-color: #96350c; }
.run:disabled { opacity: .45; cursor: not-allowed; }

.console select, .console input[type="number"] {
  font-family: var(--mono); font-size: 12px; padding: 5px 6px;
  border: 1px solid var(--rule-2); background: var(--card); color: var(--ink);
}

.readout {
  font-family: var(--mono); font-size: 11.5px; line-height: 1.65;
  padding: 9px 12px; border-bottom: 1px solid var(--rule);
  color: var(--ink-2);
  height: 62px;                  /* fixed: status text never resizes the panel */
  overflow: hidden;
}
.readout .t { color: var(--ink-3); }
.readout .ok { color: var(--ok); }
.readout .err { color: var(--dead); }

/* One media slot, always reserved. Holds the map or the rendered image. */
.media {
  height: var(--media-h);
  border-bottom: 1px solid var(--rule);
  background: var(--paper-2);
  position: relative;
  display: flex; align-items: center; justify-content: center;
}
.media .placeholder {
  font-family: var(--mono); font-size: 11px; color: var(--ink-3);
  text-align: center; padding: 0 20px;
}
.media { isolation: isolate; }   /* contain Leaflet's stacking to this box */
.media .leaflet-container { position: absolute; inset: 0; height: 100%; width: 100%; }
.media img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }

.payload {
  font-family: var(--mono); font-size: 11.5px; line-height: 1.6;
  margin: 0; padding: 11px;
  height: var(--payload-h);      /* fixed: response length never moves the page */
  overflow: auto;
  background: var(--ink); color: #d7e0db; white-space: pre;
}
.payload .s { color: #b7d4a8; }
.payload .n { color: #e0b978; }
.payload .key { color: #8fb8a8; }
.payload.idle { color: #6c7f77; }

.snippet {
  font-family: var(--mono); font-size: 12px;
  background: var(--paper); border: 1px solid var(--rule);
  padding: 10px 12px; overflow-x: auto; white-space: pre; margin: 0;
}

.children { display: flex; flex-wrap: wrap; gap: 5px; }
.child {
  font-family: var(--mono); font-size: 11px; padding: 5px 9px;
  border: 1px solid var(--rule-2); background: transparent; color: var(--ink); cursor: pointer;
}
.child[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.child:disabled { opacity: .4; cursor: not-allowed; }
.child.raster { border-color: var(--amber); }

/* --------------------------------------------------------- status report */

.report { padding: 20px clamp(16px, 2.5vw, 28px); }
.report-summary { display: flex; gap: 0; border: 1px solid var(--rule); margin-bottom: 16px; }
.report-summary div { flex: 1; padding: 10px 13px; border-right: 1px solid var(--rule); }
.report-summary div:last-child { border-right: none; }
.report-summary dt { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); }
.report-summary dd { margin: 2px 0 0; font-family: var(--mono); font-size: 22px; font-variant-numeric: tabular-nums; }

table.status { width: 100%; border-collapse: collapse; font-size: 13px; }
table.status th {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-3); text-align: left; border-bottom: 1px solid var(--rule);
  padding: 5px 10px 5px 0; font-weight: 500;
}
table.status td { padding: 5px 10px 5px 0; border-bottom: 1px solid var(--paper-2); }
table.status td.id { font-family: var(--mono); font-size: 12px; }
table.status td.result { font-family: var(--mono); font-size: 11px; white-space: nowrap; }
table.status tr.bad td.result { color: var(--dead); }
table.status tr.good td.result { color: var(--ok); }
table.status button {
  background: none; border: none; padding: 0; font: inherit;
  color: var(--sea); cursor: pointer; text-align: left;
}

.progress { height: 3px; background: var(--paper-2); margin-bottom: 14px; }
.progress span { display: block; height: 100%; background: var(--live); width: 0; transition: width .2s linear; }

.route { border: 1px solid var(--rule); border-left: 3px solid var(--sea); padding: 9px 12px; margin-bottom: 8px; background: var(--paper); }
.route-kind { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--sea); }
.route-label { margin: 2px 0 5px; font-size: 14px; color: var(--ink-2); }
.route-url { font-family: var(--mono); font-size: 11.5px; word-break: break-all; display: block; }

.empty { padding: 50px 28px; color: var(--ink-3); font-family: var(--mono); font-size: 13px; }

/* ---------------------------------------------------------------- mobile */

@media (max-width: 900px) {
  body { overflow: auto; }
  .masthead { height: auto; flex-wrap: wrap; }
  .brand { min-width: 100%; border-right: none; border-bottom: 1px solid var(--rule); }
  .gauge-strip { flex-basis: 100%; overflow-x: auto; }
  .gauge { min-width: 150px; }
  .masthead-actions { width: 100%; border-top: 1px solid var(--rule); padding: 10px 16px; }
  .shell { grid-template-columns: 1fr; }
  .index { border-right: none; border-bottom: 1px solid var(--rule); }
  .list { max-height: 280px; }
  .record { overflow: visible; }
  .record-head { position: static; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}


/* ------------------------------------------------------------- monitor */

.mon-bar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 10px; }

.mon-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
             gap: 1px; background: var(--rule); border: 1px solid var(--rule); margin-bottom: 18px; }
.mon-tile { background: var(--card); padding: 11px 14px; }
.mon-tile-label { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
                  text-transform: uppercase; color: var(--ink-3); }
.mon-tile-value { font-family: var(--mono); font-size: 26px; font-variant-numeric: tabular-nums;
                  line-height: 1.15; margin-top: 2px; }
.mon-tile-note { font-family: var(--mono); font-size: 10px; color: var(--ink-3); }

.mon-chart { width: 100%; height: auto; display: block; background: var(--card); }
.mon-legend { display: flex; gap: 16px; margin-top: 6px; font-family: var(--mono);
              font-size: 11px; color: var(--ink-2); }
.mon-legend-item { display: flex; align-items: center; gap: 6px; }
.mon-swatch { width: 12px; height: 3px; border-radius: 2px; display: inline-block; }

.mon-sources { display: flex; flex-direction: column; }
.mon-source { display: grid; grid-template-columns: 82px minmax(0, 1fr) 62px 74px auto;
              gap: 10px; align-items: center; padding: 6px 0;
              border-bottom: 1px solid var(--paper-2); }
.mon-state { font-family: var(--mono); font-size: 11px; white-space: nowrap; }
.mon-glyph { font-size: 10px; }
.mon-name { min-width: 0; }
.mon-id { font-family: var(--mono); font-size: 11px; color: var(--ink-3); display: block; }
.mon-title { font-family: var(--cond); font-size: 14px; display: block;
             overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mon-uptime, .mon-latency { font-family: var(--mono); font-size: 12px;
                            font-variant-numeric: tabular-nums; text-align: right; }

/* Each cell is one sample; a 2px surface gap keeps adjacent fills apart. */
.mon-strip { display: flex; gap: 2px; }
.mon-cell { width: 4px; height: 16px; display: block; border-radius: 1px; }
.mon-cell.empty { background: var(--paper-2); }

.mon-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.mon-table th { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
                text-transform: uppercase; color: var(--ink-3); text-align: left;
                border-bottom: 1px solid var(--rule); padding: 5px 10px 5px 0; font-weight: 500; }
.mon-table td { padding: 4px 10px 4px 0; border-bottom: 1px solid var(--paper-2); }
.mon-table td.mon-id { font-family: var(--mono); font-size: 12px; }
