/* ===== Deadline countdown rail (f426c411, render A 'Pace Rail') =====
   The scoreboard Month Pace grammar shrunk into the head-right slot: mono
   label over a 5px glow track. Heat comes from the SHARED .heat-* scale
   (--heat/--heat-glow, defined with the scoreboard) — consumed, not forked.
   Overdue is its own state: hatched track + pulsing fill, pinned 100%. */
/* flex-basis 150px with shrink + an explicit min-width: the default
   min-width:auto let a long nowrap label force the whole rail to its content
   width — the track ballooned and the label overprinted .tasks-age (Jase
   msgId 93a5afda). Now the rail holds 150px, may flex DOWN to 88px when a
   narrow head row crowds, and never grows to the label. */
.tasks-cd { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: 0 1 150px; min-width: 88px; }
/* belt-and-braces containment: whatever the label says, it clips inside the
   rail with an ellipsis — the compact narrow-width form below should make
   this moot; the guard is for the next long label nobody predicted. */
.tasks-cd-label { font-family: var(--fleet-mono); font-size: 0.58rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-muted); white-space: nowrap;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.tasks-cd-label b { color: var(--heat); font-weight: 600; }
.tasks-cd-track { position: relative; width: 100%; height: 5px; border-radius: 3px;
  background: rgba(0,0,0,.4); overflow: hidden; }
.tasks-cd-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px;
  background: linear-gradient(90deg, var(--heat-glow), var(--heat)); box-shadow: 0 0 12px var(--heat-glow); }
.tasks-cd-overdue .tasks-cd-track { background: repeating-linear-gradient(115deg, rgba(255,107,107,.16) 0 4px, rgba(0,0,0,.4) 4px 8px); }
.tasks-cd-overdue .tasks-cd-fill { animation: fleet-pulse 1.3s ease-in-out infinite; }

/* Human time-budget bar (task ad34262c stage 2). Distinct from .tasks-cd —
   the countdown rail lives in the head-right slot and measures wall-clock
   to due; this bar spans the full card width UNDER the head and measures
   elapsed working time vs an author-set budget. Bands: green under 0.8,
   amber 0.8–1.0, red at/over 1.0. Fill caps at 100% visually; label carries
   overrun magnitude via 'OVERDUE Xh Ym'. Gates in JS (timerBarHtml). */
.tasks-timer-bar { display: flex; align-items: center; gap: 12px;
  padding: 6px 12px; border-top: 1px solid var(--fleet-hair); }
.tasks-timer-bar-track { flex: 1; height: 4px; border-radius: 2px;
  background: rgba(255,255,255,0.08); overflow: hidden; }
.tasks-timer-bar-fill { height: 100%; border-radius: 2px; transition: width 0.3s ease; }
.tasks-timer-bar-green .tasks-timer-bar-fill { background: var(--fleet-working); }
.tasks-timer-bar-amber .tasks-timer-bar-fill { background: var(--fleet-your-move); }
.tasks-timer-bar-red   .tasks-timer-bar-fill { background: var(--fleet-dead); }
.tasks-timer-bar-label { font-family: var(--fleet-mono); font-size: 0.68rem;
  color: var(--text-muted); white-space: nowrap; }

.tasks-card-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 8px; min-height: 16px; }
/* chips mirror .fleet-status exactly — same voice, task-status hues */
.tasks-chip {
  font-family: var(--fleet-text); font-weight: 600; font-size: 0.62rem;
  letter-spacing: 0.06em; text-transform: uppercase; padding: 1px 7px; border-radius: 5px;
  color: #120c0c; white-space: nowrap;
}
.tasks-chip-in_progress { background: var(--fleet-working); }
/* dispatched = handed off, not yet picked up: green hollow, not green solid */
.tasks-chip-dispatched { background: transparent; color: var(--fleet-working);
  border: 1px solid var(--fleet-working); padding: 0 6px; }
.tasks-chip-queued   { background: var(--fleet-waiting); color: #efeaea; }
.tasks-chip-returned { background: var(--fleet-your-move); }
.tasks-chip-blocked  { background: var(--fleet-dead); }
.tasks-chip-awaiting_signoff { background: transparent; color: var(--fleet-your-move); border: 1px solid var(--fleet-your-move); }
.tasks-chip-done     { background: var(--fleet-resting); color: #efeaea; }
/* the assignee-side 'Awaiting sign-off' badge in the card head (no action) */
.tasks-await-mark { font-family: var(--fleet-mono); font-size: 0.62rem; font-weight: 600; letter-spacing: 0.05em; color: var(--fleet-your-move); text-transform: uppercase; white-space: nowrap; }

.tasks-progress { font-family: var(--fleet-mono); font-size: 0.7rem; color: var(--text-secondary); }
.tasks-route { font-family: var(--fleet-mono); font-size: 0.68rem; color: var(--text-muted);
  margin-left: auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.tasks-route-arrow { opacity: 0.55; }
.tasks-kind { color: var(--fleet-your-move); font-size: 0.5rem; vertical-align: middle; margin-right: 3px; }

/* ---- expanded detail: the ordered steps, telemetry voice ---- */
.tasks-detail { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--fleet-hair); }
.tasks-detail-loading { font-family: var(--fleet-text); font-size: 0.78rem;
  color: var(--text-muted); font-style: italic; }
.tasks-step {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px;
  padding: 4px 0; font-family: var(--fleet-mono); font-size: 0.72rem;
}
.tasks-step + .tasks-step { border-top: 1px solid rgba(255,255,255,0.04); }
.tasks-step-seq { color: var(--text-muted); min-width: 14px; text-align: right; }
.tasks-step-owner { color: var(--text-secondary); }
.tasks-step-verb { color: var(--text-primary); }
.tasks-step-status { margin-left: auto; text-transform: uppercase; font-size: 0.62rem;
  letter-spacing: 0.06em; color: var(--text-muted); }
.tasks-step-done .tasks-step-status { color: var(--fleet-working); }
.tasks-step-active .tasks-step-status { color: var(--fleet-your-move); }
.tasks-step-returned .tasks-step-status { color: var(--fleet-your-move); }
.tasks-step-blocked .tasks-step-status { color: var(--fleet-dead); }
.tasks-step-params { flex-basis: 100%; padding-left: 22px; color: var(--text-muted);
  font-size: 0.66rem; overflow: hidden; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; }

/* ---- admin flip control (V1.1): MARK DONE on the admin's OWN current pending
   step. Two-tap inline confirm. Green = the affirmative done action (matches the
   done-step hue); amber = armed/attention (the chip's dark-on-color idiom); red
   = failed. No new colors — all fleet tokens + the established chip text colors
   (Pit Wall canon: red danger-only, amber attention). ---- */
.tasks-flip-btn {
  margin-left: 8px; font-family: var(--fleet-mono);
  font-size: 0.6rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 2px 8px; border-radius: 5px; cursor: pointer; white-space: nowrap;
  background: transparent; color: var(--fleet-working);
  border: 1px solid var(--fleet-working);
  transition: background .13s ease, border-color .13s ease, color .13s ease;
  -webkit-tap-highlight-color: transparent;
}
.tasks-flip-btn:hover { background: rgba(255,255,255,0.06); }
.tasks-flip-btn:focus-visible { outline: 2px solid var(--fleet-working); outline-offset: 2px; }
/* armed: solid amber, dark chip text — the "you're about to commit" state */
.tasks-flip-armed { background: var(--fleet-your-move); border-color: var(--fleet-your-move); color: #120c0c; }
.tasks-flip-armed:hover { background: var(--fleet-your-move); }
.tasks-flip-armed:focus-visible { outline-color: var(--fleet-your-move); }
.tasks-flip-busy { color: var(--text-muted); border-color: var(--fleet-hair); cursor: default; opacity: 0.7; }
.tasks-flip-failed { color: var(--fleet-dead); border-color: var(--fleet-dead); background: transparent; cursor: default; }
@media (prefers-reduced-motion: reduce) { .tasks-flip-btn { transition: none; } }

/* ---- merge-approval pill (Phase 1B): Jase's GO on an eval-verified merge_pr
   gate. Same visual language as the flip pill (green affirm, amber armed, red
   failed, muted disabled). The apply-migration pill is DARK — never rendered. */
.tasks-gate { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--fleet-hair); display: flex; }
.tasks-merge-pill {
  font-family: var(--fleet-mono); font-size: 0.62rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; padding: 4px 12px;
  border-radius: 6px; cursor: pointer; white-space: nowrap;
  background: transparent; color: var(--fleet-working); border: 1px solid var(--fleet-working);
  transition: background .13s ease, border-color .13s ease, color .13s ease;
  -webkit-tap-highlight-color: transparent;
}
.tasks-merge-pill:hover { background: rgba(255,255,255,0.06); }
.tasks-merge-pill:focus-visible { outline: 2px solid var(--fleet-working); outline-offset: 2px; }
.tasks-merge-pill[disabled] { color: var(--text-muted); border-color: var(--fleet-hair); cursor: default; opacity: 0.7; }
.tasks-merge-armed { background: var(--fleet-your-move); border-color: var(--fleet-your-move); color: #120c0c; }
.tasks-merge-armed:hover { background: var(--fleet-your-move); }
.tasks-merge-busy { color: var(--text-muted); border-color: var(--fleet-hair); cursor: default; opacity: 0.7; }
.tasks-merge-failed { color: var(--fleet-dead); border-color: var(--fleet-dead); }
.tasks-merge-merging { color: var(--fleet-your-move); border-color: rgba(240,160,32,0.5); background: transparent; }
/* Inline gate pill (2026-07-24, Jase's order): the pill renders IN the gate
   step's row, taking the status badge's right-aligned slot — the bottom
   .tasks-gate container is no longer rendered (one control, one place).
   YELLOW = actionable, waiting on Jase; disabled (grey via [disabled] above)
   = the walk-back render. Deliberately minimal — Jase restyles later. */
.tasks-step .tasks-merge-inline { margin-left: auto; padding: 2px 10px; font-size: 0.6rem; }
.tasks-merge-yellow { color: var(--fleet-your-move); border-color: var(--fleet-your-move); }
.tasks-merge-yellow:focus-visible { outline-color: var(--fleet-your-move); }
/* F7b: visible two-tap hint inside the idle live pill (verdict 8 — the tap
   mechanics were hover-only, unreachable on touch). Subordinate to the action
   word: lighter weight, no tracking, hairline separator, dimmed — an
   annotation, not part of the command. Armed/busy/failed drop the span in JS. */
.tasks-merge-taphint { margin-left: 6px; padding-left: 6px; border-left: 1px solid rgba(255,255,255,0.25); font-weight: 400; letter-spacing: 0; opacity: 0.6; }
/* F7b companion fix — MEASURED defect, not cosmetic: .tasks-merge-yellow sits
   later in this file than the state classes above (.tasks-merge-armed :5142,
   .tasks-merge-failed :5145), so at equal specificity it takes their color.
   The armed CONFIRM label computed color === background === rgb(254,202,87)
   (amber on amber, headless probe 2026-07-27) — the second tap's target was
   INVISIBLE, which is what "clicking it but i dont think anything is
   happening" looks like from the other side. The 07-24 inline change added
   .tasks-merge-yellow to every live state and created the collision. Scoped
   two-class overrides, no reordering (reorder risks the same class of bug in
   the other direction). Busy is already safe: its [disabled] attr rule
   outranks the single class. */
.tasks-merge-yellow.tasks-merge-armed { color: #120c0c; }
.tasks-merge-yellow.tasks-merge-failed { color: var(--fleet-dead); border-color: var(--fleet-dead); }
/* the grey state's one-line reason, wrapped onto its own line under the row.
   F1: this now carries ONLY the returned-verify note (free-form text a button
   label cannot hold) — the reason itself moved into the pill label. */
.tasks-step-gate-reason { flex-basis: 100%; margin-left: 22px; font-size: 0.62rem; color: var(--text-muted); }
/* F1 — the inert pills now carry their STATE as their visible label, so the
   label itself has to be readable. Promoting the reason into a 0.6rem element
   would inherit the exact defect being fixed: the reason was ALREADY on screen
   at 0.62rem muted and demonstrably did not land, so "the words are present"
   was never the bar. Bumped and allowed to wrap. The yellow ACTION pill keeps
   its established size and shape — Jase knows that control; only the inert
   branches change. Deliberately NOT yellow: paused is his move, but not a tap
   on THIS button, and yellow means tappable here.
   Also dropping uppercase + letter-spacing on the inert branches: the base pill
   is styled as a shouty ACTION (uppercase, 0.08em tracking, nowrap), which is
   right for a button you tap and wrong for a sentence you READ. Sentence case
   costs far less width for the same words, and white-space:normal lets a long
   status wrap instead of forcing the row wide. (An earlier version of this
   comment claimed tracked caps overflowed the row at 430px — that was a capture
   artifact: headless Chrome pins its layout viewport at 500px, so the 430px
   screenshot was CLIPPING content that had laid out correctly. The change stands
   on the status-vs-action reasoning and the width headroom, not on an overflow
   that never happened.) */
.tasks-step .tasks-merge-inline[disabled]:not(.tasks-merge-busy):not(.tasks-merge-merging) {
  font-size: 0.72rem; line-height: 1.3; white-space: normal; text-align: right;
  text-transform: none; letter-spacing: normal; font-weight: 500; max-width: 60%;
}
/* F1 — the card state line: one plain-English sentence, the card's own answer to
   "what is this and whose move is it". Sized to be READ, not chip-sized; the
   waiting-on-you variant takes the your-move colour so it wins the scan. */
.tasks-card-state { margin: 3px 0 0; font-size: 0.78rem; line-height: 1.35; color: var(--text-secondary); }
.tasks-card-state-you { color: var(--fleet-your-move); font-weight: 600; }
/* Active-step marker: seat-phrased live dot (the working colour), probe age
   dimmed beside it. Renders ONLY when the owning pane is verified working on
   a fresh probe — every other case is ABSENT, so this rule never needs an
   idle/stale variant (ruled bounds 2+3). */
.tasks-pane-active { display: inline-flex; align-items: center; gap: 5px; margin: 3px 0 0; font-size: 0.72rem; color: var(--fleet-working); }
.tasks-pane-active-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--fleet-working); box-shadow: 0 0 6px var(--fleet-working); animation: fleet-pulse 1.3s ease-in-out infinite; }
.tasks-pane-active-age { color: var(--text-muted); }
.tasks-step-pane-slot { flex-basis: 100%; margin-left: 22px; }
@media (prefers-reduced-motion: reduce) { .tasks-pane-active-dot { animation: none; } }
@media (prefers-reduced-motion: reduce) { .tasks-merge-pill { transition: none; } }

/* ---- task thread (spec §7): readable coordination stream inside the card.
   Born panel-side — never the room feed. Append + read only; body is prose,
   rendered as escaped text, never interpreted. ---- */
.tasks-thread { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--fleet-hair); }
.tasks-thread-label { font-family: var(--fleet-text); font-size: 0.58rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 6px; }
.tasks-thread-loading, .tasks-thread-empty { font-family: var(--fleet-text); font-size: 0.72rem;
  color: var(--text-muted); font-style: italic; }
.tasks-thread-list { display: flex; flex-direction: column; gap: 7px; }
.tasks-msg { padding: 5px 8px; border-radius: 7px; background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.05); }
.tasks-msg-human { background: rgba(120,160,255,0.06); border-color: rgba(120,160,255,0.14); }
.tasks-msg-head { display: flex; align-items: baseline; gap: 8px; }
.tasks-msg-sender { font-family: var(--fleet-mono); font-size: 0.68rem; color: var(--text-secondary); }
.tasks-msg-kind { color: var(--fleet-working); margin-right: 4px; font-size: 0.6rem; }
.tasks-msg-age { margin-left: auto; font-size: 0.6rem; color: var(--text-muted); }

/* Thread-message moderation (admin-only, 2026-07-30): faint per-row menu dots
   revealing an inline DELETE - two taps for a destructive act. */
.tasks-msg-menu { flex: 0 0 auto; background: transparent; border: none; cursor: pointer;
  font-size: 0.72rem; line-height: 1; padding: 0 3px; color: var(--text-muted); opacity: 0.5; }
.tasks-msg-menu:hover:not(:disabled) { opacity: 1; color: var(--text-primary); }
.tasks-msg-del { flex: 0 0 auto; font-family: var(--fleet-mono); font-size: 0.56rem; letter-spacing: 0.06em;
  padding: 2px 7px; border-radius: 5px; cursor: pointer; background: transparent;
  color: var(--fleet-dead, #ff6b6b); border: 1px solid rgba(255,107,107,0.5); }
.tasks-msg-del:hover:not(:disabled) { background: rgba(255,107,107,0.12); }
.tasks-msg-del:disabled { opacity: 0.6; cursor: progress; }
.tasks-msg-body { margin-top: 3px; font-family: var(--fleet-text); font-size: 0.74rem;
  color: var(--text-primary); white-space: pre-wrap; word-break: break-word; line-height: 1.4; }
/* padding-bottom: the input's focus ring (2px outline + 1px offset) reaches 3px
   past its border-box, and the compose row sits flush against .tasks-box's
   overflow:hidden bottom edge — without this room the ring clips flat there.
   position:relative anchors the @-mention dropdown. */
.tasks-thread-compose { display: flex; gap: 6px; margin-top: 8px; align-items: flex-end; padding-bottom: 3px; position: relative; }
/* @-mention autocomplete (022 fast-follow): opens UPWARD over the thread list —
   absolute positioning cannot escape .tasks-box's overflow:hidden, so the
   dropdown stays inside the box by geometry (never clipped at the card edge).
   Opaque panel background per the 020 opaque-panel posture. */
/* Viewport-fixed positioning (task 389a2db8, follow-up to #724). The dropdown
   must escape .tasks-box's overflow:hidden AND the button-wrap's right-anchored
   coordinate system — both were clipping the leftward-extending dd to a thin
   right-edge sliver on phone width. positionPickerDd() in tasks-board.js sets
   viewport-clamped left/top after every render; the CSS rule here owns visual
   style + z-index only, and provides a safe left:0/top:0 fallback for the
   first paint before JS runs. Same idiom as positionAttachMenu in
   messages.js:3193 (.tab-context-menu, position:fixed, body-appended,
   viewport-clamped). */
.tasks-mention-dd { position: fixed; left: 0; top: 0;
  min-width: 200px; max-width: min(90vw, 320px); max-height: 260px; overflow-y: auto; z-index: 9999;
  display: flex; flex-direction: column; gap: 2px; padding: 4px;
  background: linear-gradient(135deg, var(--bg-primary), var(--bg-secondary));
  border: 1px solid var(--fleet-hair); border-radius: 8px;
  box-shadow: 0 12px 28px -14px rgba(0,0,0,0.8); }
.tasks-mention-opt { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 10px; border: 0; border-radius: 6px; background: transparent; cursor: pointer;
  font-family: var(--fleet-text); font-size: 0.74rem; color: var(--text-primary); text-align: left; min-width: 0; }
.tasks-mention-opt:hover, .tasks-mention-active { background: rgba(255,255,255,0.08); }
.tasks-mention-user { font-family: var(--fleet-mono); font-size: 0.62rem; color: var(--fleet-working); flex: 0 0 auto; }
/* Name column takes remaining space and truncates rather than shoving the
   right-side label off-canvas — the participant-picker regression Jase caught
   was the right-side kind badge remaining visible while the name collapsed to
   zero width at narrow anchor widths. Truncation is the readable failure mode. */
.tasks-mention-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tasks-thread-input { flex: 1; resize: vertical; min-height: 34px; padding: 6px 8px;
  border-radius: 7px; background: rgba(0,0,0,0.28); border: 1px solid var(--fleet-hair);
  color: var(--text-primary); font-family: var(--fleet-text); font-size: 0.74rem; }
.tasks-thread-input:focus-visible { outline: 2px solid var(--fleet-working); outline-offset: 1px; }
.tasks-thread-send { font-family: var(--fleet-mono); font-size: 0.6rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; padding: 6px 10px; border-radius: 6px;
  cursor: pointer; white-space: nowrap; background: transparent; color: var(--fleet-working);
  border: 1px solid var(--fleet-working); -webkit-tap-highlight-color: transparent; }
.tasks-thread-send:hover { background: rgba(255,255,255,0.06); }
.tasks-thread-send[disabled] { color: var(--text-muted); border-color: var(--fleet-hair);
  cursor: default; opacity: 0.7; }
.tasks-thread-send-failed { color: var(--fleet-dead); border-color: var(--fleet-dead); }

/* ---- done tail: the Fleet garage <details> idiom, collapsed, no JS ---- */
.tasks-done {
  margin-top: 4px; border-radius: 9px; overflow: hidden;
  background: rgba(0,0,0,0.22); border: 1px dashed var(--fleet-hair);
}
.tasks-done-toggle {
  list-style: none; cursor: pointer; user-select: none;
  display: flex; align-items: center; gap: 7px; padding: 7px 11px;
  font-family: var(--fleet-text); font-weight: 600; font-size: 0.62rem;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted);
  transition: color .15s ease, background .15s ease;
}
.tasks-done-toggle::-webkit-details-marker { display: none; }
.tasks-done-toggle::before { content: '▸'; font-size: 0.7rem; opacity: 0.8; transition: transform .15s ease; }
.tasks-done[open] .tasks-done-toggle::before { transform: rotate(90deg); }
.tasks-done-toggle:hover { color: var(--text-secondary); background: rgba(255,255,255,0.03); }
.tasks-done-cards { padding: 0 11px 11px; }
.tasks-done .tasks-card { opacity: 0.75; }
.tasks-done .tasks-card:hover { opacity: 1; }

.tasks-empty { padding: 28px; text-align: center; color: var(--text-muted); }

