/* ============================================================================
   The Council timeline — the product's signature component. Ticket E3.4.
   Spec: docs/DESIGN_SYSTEM.md §7.   Requires shared/ui.css.

   Time runs down. Each model owns a lane, a 2px rail in its own colour. Events
   land as nodes on their lane. Disagreement spans the lanes and tints them. At
   synthesis the lanes converge into one rail, which resolves to the verdict
   colour and terminates in a chip: verdict, and what the run cost.

   The structural device is lane position and convergence, not numbering — the
   run is not a fixed sequence, and which phases occur depends on the mode.
   ========================================================================== */

.council {
  --lane-w: 22px;          /* horizontal pitch between lanes */
  --rail-w: 2px;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  font-size: var(--t-sm);
  color: var(--fg);
}

/* ---- Header: mode, who is deliberating, what it cost --------------------- */

.council-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--border);
}
.council-mode {
  font-family: var(--font-display);
  font-size: var(--t-xs);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
}
.council-head .spacer { flex: 1; }
.council-cost {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-xs);
  color: var(--muted);
}

/* ---- Empty / error ------------------------------------------------------ */

.council-empty {
  color: var(--muted);
  padding: var(--sp-5) 0;
  text-align: center;
}

/* ---- Lane heads --------------------------------------------------------- */

.council-lanes {
  display: flex;
  gap: var(--sp-2);
  flex-wrap: wrap;
}
.lane-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-2);
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--lane-color, var(--muted));
  border-radius: var(--r-sm);
  min-width: 0;
}
.lane-name {
  font-family: var(--font-display);
  font-size: var(--t-xs);
  color: var(--fg);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 16ch;
}
.lane-meta {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-xs);
  color: var(--muted);
}
.lane-head[data-state="failed"] { border-left-color: var(--danger); }
.lane-head[data-state="failed"] .lane-name { color: var(--danger); }

/* A running model shows life. Static fallback: the dot is still visible. */
.lane-dot {
  width: 6px; height: 6px;
  border-radius: var(--r-full);
  background: var(--lane-color, var(--muted));
  flex: none;
}
.lane-head[data-state="running"] .lane-dot { animation: council-pulse 1.4s ease-in-out infinite; }
@keyframes council-pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: .35; transform: scale(.72); }
}

/* ---- Timeline ----------------------------------------------------------- */

.council-timeline { display: flex; flex-direction: column; }

.cn-row {
  display: grid;
  grid-template-columns: var(--rails-w, 66px) 1fr;
  gap: var(--sp-3);
  min-height: 34px;
}

/* The rails column. One <i> per lane, each a full-height 2px line. */
.cn-rails {
  position: relative;
  display: flex;
  justify-content: flex-start;
  gap: calc(var(--lane-w) - var(--rail-w));
}
.cn-rails i {
  width: var(--rail-w);
  background: var(--rail-color, var(--muted));
  opacity: .32;
  display: block;
}
.cn-rails i[data-live="1"] { opacity: .85; }
.cn-rails i[data-dead="1"] { opacity: .12; }

/* The node itself: a dot on one lane, drawn over the rails. */
.cn-dot {
  position: absolute;
  top: 12px;
  width: 9px; height: 9px;
  border-radius: var(--r-full);
  background: var(--bg);
  border: 2px solid var(--rail-color, var(--muted));
  transform: translateX(-3.5px);
}
.cn-dot[data-fill="1"] { background: var(--rail-color, var(--muted)); }

.cn-body { padding: var(--sp-1) 0 var(--sp-3); min-width: 0; }
.cn-label {
  font-family: var(--font-display);
  font-size: var(--t-sm);
  color: var(--fg);
}
.cn-sub {
  color: var(--muted);
  font-size: var(--t-xs);
  margin-top: 2px;
  overflow-wrap: anywhere;
}
.cn-excerpt {
  margin-top: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-2);
  border-left: 2px solid var(--rail-color, var(--border));
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  color: var(--muted);
  font-size: var(--t-xs);
  line-height: 1.5;
  max-height: 5.4em;
  overflow: hidden;
}

/* ---- Source cards (E6.2): web evidence with real excerpts --------------- */

.cn-sources {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}
.cn-source {
  display: block;
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  text-decoration: none;
  color: var(--fg);
  transition: border-color var(--dur-1) var(--ease);
}
.cn-source:hover { border-color: var(--muted); }
.cn-source-title {
  display: block;
  font-size: var(--t-sm);
  color: var(--fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cn-source-host {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--accent);
  margin-top: 1px;
}
.cn-source-excerpt {
  display: block;
  font-size: var(--t-xs);
  color: var(--muted);
  margin-top: var(--sp-1);
  line-height: 1.45;
  max-height: 4.4em;
  overflow: hidden;
}

/* ---- Disagreement: the lanes visibly separate ---------------------------- */

.cn-row[data-kind="dispute"] .cn-rails::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 15px;
  height: 1px;
  background: var(--verdict-dispute);
  opacity: .55;
}
.cn-row[data-kind="dispute"] .cn-body { border-radius: var(--r-sm); }
.cn-row[data-kind="dispute"] .cn-label { color: var(--verdict-dispute); }

/* ---- Convergence: the lanes braid into one ------------------------------ */

.cn-row[data-kind="synthesis"] .cn-rails { overflow: visible; }
.cn-merge { display: block; }
.cn-merge path {
  fill: none;
  stroke-width: var(--rail-w);
  opacity: .85;
}
/* Draw the merge in, once, when it arrives. */
.cn-merge path {
  stroke-dasharray: var(--len, 80);
  stroke-dashoffset: 0;
}
.council[data-animate="1"] .cn-merge path {
  animation: council-draw var(--dur-2) var(--ease) both;
}
@keyframes council-draw {
  from { stroke-dashoffset: var(--len, 80); }
  to   { stroke-dashoffset: 0; }
}

/* The Moment of Agreement. Fires only when synthesis_completed.council is true,
   which the backend now computes from the models that actually ran. */
.cn-row[data-council="1"] .cn-dot {
  background: var(--verdict-ok);
  border-color: var(--verdict-ok);
}
.council[data-animate="1"] .cn-row[data-council="1"] .cn-dot {
  animation: council-resolve 900ms var(--ease) 1;
}
@keyframes council-resolve {
  0%   { box-shadow: 0 0 0 0 var(--gpt); }
  33%  { box-shadow: 0 0 0 4px color-mix(in srgb, var(--claude) 45%, transparent); }
  66%  { box-shadow: 0 0 0 7px color-mix(in srgb, var(--grok) 25%, transparent); }
  100% { box-shadow: 0 0 0 12px transparent; }
}

/* ---- Verdict + terminal ------------------------------------------------- */

.council-verdict {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  margin-top: var(--sp-2);
}
.verdict-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 2px var(--sp-2);
  border-radius: var(--r-full);
  font-size: var(--t-xs);
  font-family: var(--font-display);
  background: var(--chip);
  border: 1px solid var(--border);
  color: var(--muted);
}
/* Colour is never the only signal: each verdict carries a glyph and a word. */
.verdict-chip[data-state="verified"] { color: var(--verdict-ok);      border-color: color-mix(in srgb, var(--verdict-ok) 45%, var(--border)); }
.verdict-chip[data-state="checking"] { color: var(--verdict-watch);   border-color: color-mix(in srgb, var(--verdict-watch) 45%, var(--border)); }
.verdict-chip[data-state="unverified"] { color: var(--muted); }
.verdict-chip[data-state="disputed"] { color: var(--verdict-dispute); border-color: color-mix(in srgb, var(--verdict-dispute) 45%, var(--border)); }
.verdict-chip[data-state="failed"]   { color: var(--verdict-dispute); border-color: var(--verdict-dispute); }

.cn-row[data-kind="failed"] .cn-label { color: var(--danger); }
.cn-row[data-kind="failed"] .cn-dot { border-color: var(--danger); background: var(--danger); }

/* ---- Compare mode: lanes run parallel to the bottom and never braid ------ */

.council[data-mode="compare"] .cn-row[data-kind="synthesis"] .cn-label::after {
  content: " — side by side, not a council";
  color: var(--muted);
  font-family: var(--font-body);
  font-weight: 400;
}

/* ---- Motion off: every state must still be legible ---------------------- */

@media (prefers-reduced-motion: reduce) {
  .lane-head[data-state="running"] .lane-dot { animation: none; }
  .council[data-animate="1"] .cn-merge path,
  .council[data-animate="1"] .cn-row[data-council="1"] .cn-dot { animation: none; }
  .cn-merge path { stroke-dashoffset: 0; }
}

/* ---- Narrow ------------------------------------------------------------- */

@media (max-width: 640px) {
  .council { --lane-w: 16px; }
  .cn-excerpt { display: none; }   /* the structure survives; the prose doesn't fit */
  .lane-name { max-width: 10ch; }
}
