/*
 * Dash + annunciator feed content — THE WALL AND THE RECORD (2026-10-25).
 * Owns: the dash rack (mast, territory fill, scale bar, KPI strip, panels,
 * team notes feed) and the happening pane CONTENT (rows, titles, kind lines —
 * the dock chrome and the pane-visibility rules keyed off
 * #happening-list[data-tab] stay in board.css).
 *
 * Laws honored here: every color a token; no animation inside the 5s-polled
 * containers (#dash-panels, #happening-list) — the single keyframe lives on
 * the stable page-load mast; mono is the machine voice, sans the human one.
 */

/* ==========================================================================
 * The rack — full-width units, 16px gaps
 * ========================================================================= */

.dash-wrap {
  position: relative; /* ride above the lattice (base.css lifts body > * tags) */
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  padding: var(--sp-4);
  /* Keep the fixed rain toggle clear of the last rows (feel-critique 2). */
  padding-bottom: var(--sp-8);
}

.dash-wrap .rack-unit {
  background: var(--s-panel);
  border: 1px solid var(--line);
  border-radius: var(--r-panel);
  box-shadow: var(--shadow-bevel);
  padding: var(--sp-4);
}

/* Unit mast: a machined label over an underline rule. State masts tint the
   glyph + text; the label always carries the meaning (never color alone). */
.dash-wrap .unit-mast {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-3);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--line);
  color: var(--text-label);
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.dash-wrap .unit-mast .icon {
  width: 14px;
  height: 14px;
  flex: none;
}

.dash-wrap .unit-mast.is-captured { color: var(--ch-captured); }
.dash-wrap .unit-mast.is-stuck { color: var(--ch-stuck); }
.dash-wrap .unit-mast.is-writeup { color: var(--ch-writeup); }

/* ==========================================================================
 * The mast unit — event plate, territory fill, scale bar (stable, page-load)
 * ========================================================================= */

.dash-mast-head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-width: 0;
}

.dash-mast-title { min-width: 0; }

.dash-mast-title h1 {
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dash-mast-meta {
  margin: 0;
  color: var(--text-label);
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: 0.04em;
}

/* Live seal: the SSE registration mark rides the stable mast only. */
.dash-live {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  margin-left: auto;
  color: var(--text-label);
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  flex: none;
}

/* -- territory fill: the event silhouette (hex-lamp shape), hatched in
      solved green proportional to the solved fraction. Wrapper stable; the
      server re-renders it only on page load, so the one-shot ink sweep
      never restarts under the 5s poll. ------------------------------------ */
.dash-territory {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  margin-top: var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line-soft);
}

.territory-fill {
  width: 72px;
  height: 72px;
  flex: none;
  color: var(--text-label);
}

.territory-outline {
  fill: var(--s-pit);
  stroke: currentColor;
  stroke-width: 1;
}

.territory-ink,
.territory-sweep {
  transform-box: fill-box;
  transform-origin: left center;
}

.territory-sweep {
  animation: territory-ink var(--dur-4) var(--ease-drawer) both;
}

@keyframes territory-ink {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

/* -- scale bar: the map-collar ruler. Filled portion = solved fraction. --- */
.scale-bar {
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--sp-2);
}

.scale-tick-label {
  color: var(--text-label);
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  font-variant-numeric: tabular-nums;
}

.scale-track {
  position: relative;
  height: 8px;
  border: 1px solid var(--line);
  background:
    repeating-linear-gradient(
      90deg,
      var(--line-tick) 0 1px,
      transparent 1px 10%
    ),
    var(--s-pit);
}

.scale-fill {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  background: var(--ch-solved-dim);
  border-right: 2px solid var(--ch-solved);
}

.scale-caption {
  grid-column: 1 / -1;
  color: var(--text-label);
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: 0.04em;
  text-align: right;
}

/* ==========================================================================
 * KPI strip (inside #dash-panels — polled; numerals only, no ceremony)
 * ========================================================================= */

.dash-kpi {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--sp-3);
}

.dash-kpi .kpi {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  min-width: 0;
  padding: var(--sp-3) var(--sp-3) var(--sp-5);
  background: var(--s-pit);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-chamfer);
  position: relative;
}

/* Tick ruler under every readout — the instrument strip grammar. */
.dash-kpi .kpi::after {
  content: "";
  position: absolute;
  left: var(--sp-3);
  right: var(--sp-3);
  bottom: var(--sp-2);
  height: 4px;
  background: repeating-linear-gradient(
    90deg,
    var(--line-tick) 0 1px,
    transparent 1px 8px
  );
}

.dash-kpi .kpi b {
  color: var(--text-max);
  font-size: var(--t-display-2);
  font-weight: 600;
  line-height: var(--t-display-2-lh);
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
 * The five panels (inside #dash-panels — polled; hairline rows only)
 * ========================================================================= */

.dash-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--sp-4);
  margin-top: var(--sp-4);
  align-items: start;
}

.dash-panel {
  background: var(--s-panel);
  border: 1px solid var(--line);
  border-radius: var(--r-panel);
  box-shadow: var(--shadow-bevel);
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
  min-width: 0;
}

/* Attention edges reinforce the labeled mast — quiet, not loud. */
.dash-panel--claimed { border-left: 2px solid var(--ch-claimed); }
.dash-panel--awaiting { border-left: 2px solid var(--ch-captured); }
.dash-panel--stuck { border-left: 2px solid var(--ch-stuck); }
.dash-panel--drafts { border-left: 2px solid var(--ch-writeup); }

.dash-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-top: 1px solid var(--line-soft);
  color: var(--text-body);
  font-size: var(--t-ui);
  min-width: 0;
}

.dash-row:first-of-type { border-top: none; }

.dash-row .avatar {
  width: 16px;
  height: 16px;
  vertical-align: -3px;
}

.dash-actor {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-width: 0;
  color: var(--text-max);
}

/* Presence lamps: claimed-mint when on a card, an empty socket otherwise. */
.dash-row .lamp-idle { background: var(--line-tick); }
.dash-row .lamp.lit { color: var(--ch-claimed); }

.dash-state,
.dash-holder {
  text-align: right;
  flex: none;
  max-width: 60%;
}

.dash-holder {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  justify-content: flex-end;
  white-space: nowrap;
}

.dash-chal-wrap {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-max);
}

a.dash-chal { color: var(--sig); }

/* Captions and secondary values — the machine's aside voice. */
.dash-sub {
  color: var(--text-label);
  font-family: var(--font-mono);
  font-size: var(--t-meta);
}

.dash-kpi .dash-sub {
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ==========================================================================
 * Team notes feed (dash page; SSE notes swaps land inside #team-notes-list)
 * ========================================================================= */

#team-notes-list {
  max-height: 300px;
  overflow-y: auto;
}

.activity-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Declared in full against board.css's shared .activity-* base (card fill,
   left edge, floated timestamp): on the dash the notes are ruled rows in the
   rack's voice, and this sheet loads last. */
.activity-item {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  padding: var(--sp-2) 0;
  background: transparent;
  border-top: 1px solid var(--line-soft);
  border-left: none;
  border-radius: 0;
  min-width: 0;
}

.activity-item:first-child { border-top: none; }

.activity-item .avatar {
  width: 16px;
  height: 16px;
  align-self: center;
  flex: none;
}

.activity-time {
  float: none;
  margin-left: 0;
  color: var(--text-label);
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  font-variant-numeric: tabular-nums;
  flex: none;
}

.note-author {
  color: var(--text-max);
  white-space: nowrap;
  font-size: var(--t-ui);
  flex: none;
}

.note-text {
  flex: 1;
  min-width: 0;
  color: var(--text-body);
  font-size: var(--t-ui);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Author voice: agents speak mono, humans sans. */
.note-agent .note-author { font-family: var(--font-mono); }
.note-human .note-author { font-family: var(--font-sans); }
.note-agent .note-text { font-family: var(--font-mono); font-size: var(--t-meta); }
.note-human .note-text { font-family: var(--font-sans); }

.note-del { flex: none; align-self: center; }

.dash-notes-empty {
  color: var(--text-label);
  text-align: center;
  padding: var(--sp-3);
  font-size: var(--t-ui);
}

.dash-back { margin-top: var(--sp-3); }

/* ==========================================================================
 * Happening pane content (served into #happening-list on the board page —
 * chrome and pane visibility stay in board.css; nothing here animates)
 * ========================================================================= */

.happening-pane {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  min-width: 0;
}

.happening-pane h4 {
  margin: 0;
  color: var(--text-label);
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Feed rows are ruled, not boxed: transparent rows, hairline between
   neighbors. Declared in full because board.css carries a provisional
   chrome-level recipe (pit fill + left edge) that this sheet supersedes —
   dash.css loads after board.css, so these wins are the content truth. */
.happening-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) 0;
  background: transparent;
  border-left: none;
  border-radius: 0;
  color: var(--text-body);
  font-size: var(--t-ui);
  min-width: 0;
}

.happening-row + .happening-row { border-top: 1px solid var(--line-soft); }

.happening-row .chip { flex: none; }
.happening-row .chip .chip-op { flex: none; white-space: nowrap; }

.happening-title {
  color: var(--text-max);
  min-width: 0;
  flex: 0 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.happening-text {
  color: var(--text-body);
  min-width: 0;
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.happening-row .activity-kind,
.happening-row .activity-time { flex: none; }

.activity-kind {
  color: var(--text-label);
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.happening-empty {
  color: var(--text-label);
  font-size: var(--t-ui);
  padding: var(--sp-1) 0;
}

/* ==========================================================================
 * Responsive — the rack stacks under 1024px
 * ========================================================================= */

@media (max-width: 1023px) {
  .dash-kpi {
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  }

  .dash-kpi .kpi b {
    font-size: var(--t-title-lg);
    line-height: var(--t-title-lg-lh);
  }

  .dash-grid {
    grid-template-columns: 1fr;
  }

  .dash-territory {
    flex-direction: column;
    align-items: stretch;
    gap: var(--sp-4);
  }

  .territory-fill {
    width: 56px;
    height: 56px;
  }

  .dash-mast-head {
    flex-wrap: wrap;
  }

  .dash-live { margin-left: 0; }

  .dash-row {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-1);
  }

  .dash-state,
  .dash-holder {
    text-align: left;
    max-width: 100%;
    justify-content: flex-start;
  }
}
