/* ==========================================================================
   turnstone — coordinator.css
   Coordinator-specific chrome.  Loaded only by coordinator/index.html;
   not part of console/static/style.css (the admin dashboard sheet).
   ==========================================================================
   Tokens (--panel, --hair, --ok, --warn, etc.) come from shared_static/
   base.css.  Form controls + .btn / .ghost / .appbar primitives come
   from shared_static/ui-base.css.  This file holds the patterns specific
   to the coordinator view: the right-rail sidebar, the inline tool-batch
   construct (paired tool calls + approval flow + results), and the
   drag-and-drop overlay.
   ========================================================================== */

/* ==========================================================================
   Sidebar — coordinator right-rail container.  The .sidebar rule defines
   the visual chrome (panel bg, hair border, padding); the coord page's
   inline <style> overrides position/top/height/border-right to flex the
   rail into its grid column.  Section labels are 10px uppercase.
   ========================================================================== */
.sidebar {
  position: sticky;
  top: 48px;
  align-self: start;
  height: calc(100vh - 48px);
  padding: 16px 10px;
  background: var(--panel);
  border-right: 1px solid var(--hair);
  overflow: auto;
}

.side-section {
  margin-bottom: 18px;
}

.side-label {
  padding: 0 8px 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-4);
}

/* ==========================================================================
   Drag-and-drop overlay — applied to #coord-main while the user is
   dragging files from the OS over the chat pane. Composer wires this on
   construction (dragDrop.targetEl=coord-main, dropClass=coord-drop-target).
   The dashed outline + "Drop file to attach" overlay mirror the interactive
   pane's pattern so the affordance reads the same in both surfaces.
   ========================================================================== */
#coord-main {
  position: relative; /* anchors the ::after overlay */
}
#coord-main.coord-drop-target {
  outline: 2px dashed var(--accent);
  outline-offset: -6px;
}
#coord-main.coord-drop-target::after {
  content: "Drop file to attach";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  pointer-events: none;
  z-index: 10;
}

/* ==========================================================================
   Tool batch construct — pairs tool calls with their results and
   embeds the approval flow.  Replaces the bottom approval dock + the
   duplicate .msg.tool bubbles for tool-call rendering.

   One construct per dispatch turn:
     - solo (1 call, serial):       .coord-tool-batch--solo
     - parallel (≥2 calls):         .coord-tool-batch--parallel
                                    rows share a left rail so the
                                    operator reads them as siblings
                                    of one assistant decision.

   Sub-elements:
     .coord-tool-batch-head      label + count + tier glyph
     .coord-tool-row             per-call row (call line + verdict + result)
       .coord-tool-row-call      [idx] name args ellipsized
       .coord-tool-row-verdict   judge verdict chip + rationale teaser
       .coord-tool-row-result    paired tool_result <pre> under the row
       .coord-tool-row-status    per-row pill (auto-approved / error)
     .coord-tool-actions         approve / deny / always
     .coord-tool-status          resolved status pill (replaces actions)

   States (modifiers on the batch):
     .coord-tool-batch--pending  approval gate visible
     .coord-tool-batch--approved resolved approve
     .coord-tool-batch--denied   resolved deny — rows dimmed
     .coord-tool-batch--auto     all auto-approved, no gate ever shown
     .coord-tool-batch--running  replay-time orphan (dispatched but no
                                 matching tool_result yet) — no actions.
                                 SSE upgrades to --pending or --auto
                                 when it knows more.
   ========================================================================== */
.coord-tool-batch {
  margin: 4px 0;
  background: var(--panel);
  border: 1px solid var(--hair);
  border-left: 3px solid var(--hair-2);
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  overflow: hidden;
}

/* State left-stripe — neutral default; warn when gating; ok when
   resolved-approved; err when denied or any row errored.  Three stacked
   non-colour cues for WCAG 1.4.1: pill text in the head, rail colour,
   row dimming on deny. */
.coord-tool-batch--pending {
  border-left-color: var(--warn);
}
.coord-tool-batch--approved {
  border-left-color: color-mix(in srgb, var(--ok) 65%, var(--hair-2));
}
.coord-tool-batch--auto {
  border-left-color: var(--hair-2);
}
.coord-tool-batch--running {
  /* Subtle accent stripe so the operator can tell a still-in-flight
     replayed batch apart from a resolved one without it screaming
     for attention.  Not warn (which would imply approval-needed). */
  border-left-color: color-mix(in srgb, var(--accent) 50%, var(--hair-2));
}
.coord-tool-batch--denied,
.coord-tool-batch--error {
  border-left-color: var(--err);
}
.coord-tool-batch--denied .coord-tool-row {
  opacity: 0.6;
}

/* Header strip — small uppercase kicker + per-batch metadata. */
.coord-tool-batch-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  padding: 6px 10px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--hair);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.coord-tool-batch-kicker {
  color: var(--ink-3);
}
.coord-tool-batch--pending .coord-tool-batch-kicker {
  color: var(--warn);
}
.coord-tool-batch--approved .coord-tool-batch-kicker {
  color: color-mix(in srgb, var(--ok) 70%, var(--ink-2));
}
.coord-tool-batch--denied .coord-tool-batch-kicker {
  color: var(--err);
}
.coord-tool-batch-summary {
  font-family: var(--font-mono);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-2);
}
.coord-tool-batch-tier {
  margin-left: auto;
  font-family: var(--font-mono);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-4);
  font-size: 10px;
}

/* Row container.  In parallel batches, rows are framed by a left rail
   so they read as siblings of a single assistant decision; in solo
   batches the rail is suppressed to keep visual weight low. */
.coord-tool-row {
  position: relative;
  padding: 8px 10px;
}
.coord-tool-row + .coord-tool-row {
  border-top: 1px solid var(--hair);
}
.coord-tool-batch--parallel .coord-tool-row {
  padding-left: 28px;
}
.coord-tool-batch--parallel .coord-tool-row::before {
  /* Vertical rail tick — connects rows visually as a parallel group.
     Stops 4px short of the row's top + bottom edges so consecutive
     rows look continuous; the dot at the row's center marks the call. */
  content: "";
  position: absolute;
  left: 14px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--hair-2);
}
/* Tuck the rail 4px in from the very first / last row's edge so the
   line doesn't butt against the batch's inner top/bottom.  Class
   markers (set in JS at row-build time) instead of :first-of-type /
   :last-of-type because the batch contains other ``<div>`` siblings
   (.coord-tool-batch-head, .coord-tool-actions / .coord-tool-status)
   that are also of type ``div`` — :first-of-type would never select
   the first .coord-tool-row, and the rule would silently no-op. */
.coord-tool-batch--parallel .coord-tool-row.coord-tool-row--first::before {
  top: 4px;
}
.coord-tool-batch--parallel .coord-tool-row.coord-tool-row--last::before {
  bottom: 4px;
}
.coord-tool-batch--parallel .coord-tool-row::after {
  content: "";
  position: absolute;
  left: 11px;
  top: 14px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--panel);
  border: 1.5px solid var(--hair-2);
}
.coord-tool-batch--parallel.coord-tool-batch--approved .coord-tool-row::after {
  border-color: color-mix(in srgb, var(--ok) 65%, var(--hair-2));
}
.coord-tool-batch--parallel.coord-tool-batch--denied .coord-tool-row::after,
.coord-tool-row.error::after {
  border-color: var(--err);
}

/* Call line — index/N pill, monospace tool name, ellipsized args. */
.coord-tool-row-call {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}
.coord-tool-row-idx {
  flex-shrink: 0;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-3);
  background: var(--panel-2);
  border: 1px solid var(--hair);
  border-radius: 3px;
}
.coord-tool-row-name {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-weight: 600;
  color: var(--ink);
}
.coord-tool-row.error .coord-tool-row-name {
  color: var(--err);
}
.coord-tool-row-args {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-mono);
  color: var(--ink-3);
}

/* Verdict line — judge chip + optional rationale teaser. */
.coord-tool-row-verdict {
  margin-top: 4px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  color: var(--ink-3);
}
.coord-tool-row-verdict code {
  padding: 1px 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--ink-2);
  background: var(--panel-2);
  border: 1px solid var(--hair);
  border-radius: 3px;
}
.coord-tool-row-verdict code.rec-approve {
  color: color-mix(in srgb, var(--ok) 70%, var(--ink-2));
  border-color: color-mix(in srgb, var(--ok) 38%, var(--hair));
  background: color-mix(in srgb, var(--ok) 12%, var(--panel-2));
}
.coord-tool-row-verdict code.rec-review {
  color: color-mix(in srgb, var(--warn) 70%, var(--ink-2));
  border-color: color-mix(in srgb, var(--warn) 38%, var(--hair));
  background: var(--warn-tint);
}
.coord-tool-row-verdict code.rec-deny {
  color: color-mix(in srgb, var(--err) 70%, var(--ink-2));
  border-color: color-mix(in srgb, var(--err) 38%, var(--hair));
  background: color-mix(in srgb, var(--err) 12%, var(--panel-2));
}
.coord-tool-row-verdict code.judging {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--ink-3);
}
.coord-tool-row-verdict code.judging .spin {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1.5px solid var(--accent);
  border-top-color: transparent;
  animation: ts-spin 0.9s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .coord-tool-row-verdict code.judging .spin { animation: none; }
}

/* Rationale disclosure — collapsible block under a row.  Renders the
   judge's reasoning prose; `details` element so a click toggles without
   stealing focus. */
.coord-tool-row-rationale {
  margin-top: 4px;
  font-size: 11px;
  color: var(--ink-3);
}
.coord-tool-row-rationale > summary {
  cursor: pointer;
  color: var(--accent);
  font-size: 11px;
  list-style: none;
  user-select: none;
}
.coord-tool-row-rationale > summary::before {
  content: "▸ ";
  display: inline-block;
  margin-right: 2px;
  transition: transform 120ms ease;
}
.coord-tool-row-rationale[open] > summary::before {
  transform: rotate(90deg);
}
.coord-tool-row-rationale-body {
  margin: 4px 0 0 14px;
  padding: 6px 10px;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.5;
  color: var(--ink-3);
  background: var(--panel-2);
  border-left: 2px solid var(--hair);
  border-radius: 0 3px 3px 0;
  white-space: pre-wrap;
}

/* Per-row status pill (auto-approved, error). */
.coord-tool-row-status {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-radius: 3px;
  border: 1px solid var(--hair);
  color: var(--ink-3);
}
.coord-tool-row-status--auto {
  color: color-mix(in srgb, var(--ok) 70%, var(--ink-2));
  border-color: color-mix(in srgb, var(--ok) 38%, var(--hair));
  background: color-mix(in srgb, var(--ok) 12%, var(--panel-2));
}
.coord-tool-row-status--error {
  color: var(--err);
  border-color: color-mix(in srgb, var(--err) 38%, var(--hair));
  background: color-mix(in srgb, var(--err) 12%, var(--panel-2));
}

/* Output-guard finding rendered under its specific .coord-tool-row.
   Stays anchored to the call that tripped the guard rather than
   floating into the chat log as a generic "[output guard]" line —
   matches interactive's `.output-warning` placement convention.
   Severity drives the hue (matches .verdict-badge.verdict-* palette
   so an operator scanning a workstream reads risk consistently
   across both surfaces). */
.coord-tool-row-warning {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  padding: 2px 8px;
  font-size: 11px;
  font-family: var(--font-mono);
  border: 1px solid var(--hair);
  border-radius: 3px;
  border-left-width: 3px;
  background: var(--panel-2);
  color: var(--ink-2);
  max-width: max-content;
}
.coord-tool-row-warning--low {
  color: color-mix(in srgb, var(--ok) 70%, var(--ink-2));
  border-left-color: var(--ok);
  background: color-mix(in srgb, var(--ok) 12%, var(--panel-2));
}
.coord-tool-row-warning--medium {
  color: color-mix(in srgb, var(--warn) 70%, var(--ink-2));
  border-left-color: var(--warn);
  background: var(--warn-tint);
}
.coord-tool-row-warning--high,
.coord-tool-row-warning--critical {
  color: color-mix(in srgb, var(--err) 70%, var(--ink-2));
  border-left-color: var(--err);
  background: color-mix(in srgb, var(--err) 12%, var(--panel-2));
}
.coord-tool-row-warning-redacted {
  color: var(--ink-3);
  font-size: 10px;
}

/* Storage-truncation indicator — same convention as the interactive
   UI's `.tool-output-truncated` pill (transparent bg, dim border,
   small font) so the operator reads the affordance the same way on
   both surfaces.  Sibling node next to .coord-tool-row-result rather
   than text-in-content so a future "best-effort JSON repair" pass
   on the result body doesn't have to strip a marker string. */
.coord-tool-truncated {
  display: inline-block;
  margin-top: 4px;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 10px;
  font-family: var(--font-mono);
  color: var(--ink-3);
  background: transparent;
  border: 1px solid var(--ink-3);
  border-radius: 3px;
}

/* memory/recall calls are background metadata — the audit trail is
   useful but they crowd the tree on workstreams with heavy memory
   usage.  Dim the row by default; full opacity on hover so they
   stay inspectable.  Mirrors the interactive UI's metacog dim rule
   (style.css `.ts-approval-tool[data-func-name="memory"]`).  The
   row stamps `data-tool-name` from item.func_name in coordinator.js
   so this selector has something to match. */
.coord-tool-row[data-tool-name="memory"],
.coord-tool-row[data-tool-name="recall"] {
  opacity: 0.55;
  transition: opacity 120ms ease-out;
}
.coord-tool-row[data-tool-name="memory"]:hover,
.coord-tool-row[data-tool-name="memory"]:focus-within,
.coord-tool-row[data-tool-name="recall"]:hover,
.coord-tool-row[data-tool-name="recall"]:focus-within {
  opacity: 1;
}

/* Tool result block — paired under its row, mono pre-block.  Capped
   at 240px with internal scroll so a long tool output doesn't push
   the rest of the chat off-screen.  The interactive UI uses a
   click-to-expand "collapsed" affordance (see ui/static/style.css
   .tool-output.collapsed) — coord deliberately doesn't, since the
   construct is read-only history once results land and a scroll
   pane is the lower-friction read for a diagnostic surface. */
.coord-tool-row-result {
  margin-top: 6px;
  padding: 6px 10px;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.5;
  color: var(--ink-2);
  background: var(--panel-2);
  border-left: 2px solid var(--hair);
  border-radius: 0 3px 3px 0;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 240px;
  overflow: auto;
}
.coord-tool-row.error .coord-tool-row-result {
  border-left-color: var(--err);
  color: color-mix(in srgb, var(--err) 75%, var(--ink-2));
}
.coord-tool-row-result-lead {
  display: inline-block;
  margin-right: 4px;
  color: var(--ink-4);
  font-weight: 600;
}

/* Action row — Approve / Deny / Always.  Renders inside a pending
   tool-batch construct as the operator's gate for the dispatch.  The
   .act button vocabulary (primary/always/danger) is local to this
   surface; the children-tree's .ch-row .approval-actions reuses the
   same colour/border treatment in compact .sm sizing. */
.coord-tool-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  background: var(--panel-2);
  border-top: 1px solid var(--hair);
}
.coord-tool-actions .spacer { flex: 1; }
.coord-tool-actions button.act {
  padding: 6px 14px;
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-2);
  background: var(--panel);
  border: 1.5px solid var(--hair-2);
  border-radius: var(--r-md);
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.coord-tool-actions button.act:hover {
  color: var(--ink);
  border-color: var(--ink-4);
}
.coord-tool-actions button.act:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.coord-tool-actions button.act:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.coord-tool-actions button.act.primary {
  background: color-mix(in srgb, var(--ok) 28%, var(--panel));
  color: var(--ok-text);
  border-color: color-mix(in srgb, var(--ok) 65%, var(--hair));
  font-weight: 600;
}
.coord-tool-actions button.act.primary:hover {
  background: color-mix(in srgb, var(--ok) 40%, var(--panel));
  color: var(--ink);
  border-color: var(--ok);
}
.coord-tool-actions button.act.always {
  background: transparent;
  border-style: dashed;
  border-color: color-mix(in srgb, var(--ok) 65%, var(--hair));
  color: var(--ok-text);
}
.coord-tool-actions button.act.always:hover {
  background: color-mix(in srgb, var(--ok) 15%, var(--panel));
  color: var(--ink);
  border-color: var(--ok);
}
.coord-tool-actions button.act.danger {
  color: var(--err);
  border-color: color-mix(in srgb, var(--err) 42%, var(--hair));
}
.coord-tool-actions button.act.danger:hover {
  background: var(--err-soft);
  color: var(--err);
  border-color: var(--err);
}
.coord-tool-actions button.act .kbd {
  margin-left: 6px;
  padding: 0 3px;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--ink-3);
  border: 1px solid var(--hair);
  border-radius: 2px;
}
.coord-tool-actions button.act.primary .kbd {
  color: color-mix(in srgb, var(--ok) 70%, var(--ink-3));
  border-color: color-mix(in srgb, var(--ok) 40%, var(--hair));
}

/* Resolved status pill — replaces the action row after approve/deny. */
.coord-tool-status {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  background: var(--panel-2);
  border-top: 1px solid var(--hair);
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-3);
}
.coord-tool-status--approved {
  color: color-mix(in srgb, var(--ok) 70%, var(--ink-2));
}
.coord-tool-status--denied,
.coord-tool-status--error {
  color: var(--err);
}
.coord-tool-status-feedback {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-3);
}

/* Mobile (<700px) — keep action targets ≥44px for WCAG 2.5.5. */
@media (max-width: 700px) {
  .coord-tool-actions {
    flex-wrap: wrap;
  }
  .coord-tool-actions button.act {
    flex: 1 1 30%;
    min-height: 44px;
    font-size: 13px;
  }
}
