🧪 Test / 🧪 Lock + lint (push) Canceled after 0s
Requirement 001 decisions 52 to 58 (operator 2026-11-09): - Radio spot: the Agents toolbar radio button expands inline with the one composer (every channel, post and call recipients, Record, Send), a gear with the radio settings (tones, squelch, read aloud, moved out of the general settings) and Cancel mayday, which leaves the toolbar; the Radio tab keeps speakers, stations and the log plus a jump to the spot. - Day/Night menu: the badge and Drain, Suspend and Resume only; each explanation is the button's tooltip. - Tasks toolbar: views, filter, estimation, sort and business value in one wrapping row with a Request choices dropdown; the status chips stay the second row. - Burndown and burnup: a trend selector (off, linear regression, velocity over N days) stored in the hub settings, the trend lines and the forecast date on the chart, and a tooltip per point with the work packages that started, ended or joined there. - ETA: every list row shows its ETA (end when done, else start or now plus the forecast length behind its predecessors), sharing one predecessor walk with the Gantt. - Tasks 3D: a sixth view on the 3D engine with the dependency edges in the Gantt colours, layouts Force and Time. - Steady 3D camera: the view fits once per graph build, refreshes keep the operator's camera. - e2e: Firefox runs with its profile as cwd, so its crashreporter no longer drops core dumps into the repository. - A forecast beyond the last second a Date can hold is no forecast, so a nearly flat regression no longer aborts the Tasks render. Evidence: make test Ran 717 OK, ruff clean, markdownlint 0 errors; e2e 30 of 30 OK in Chromium and Firefox at 1920, 1366 and 390 px; MEDUSA 0 findings after one skeptic-accepted lexical EXA006. 🎯 Fix: 93 % 💥 Break: 4 % 💸 Cost: 100 % ⏱️ Time: – 🛡️ Security: 100 % 🏆 Score: 89 🚦 Gate: ✅ 90/5, cost and time <= 100, security 100 % Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
90 lines
7.1 KiB
CSS
90 lines
7.1 KiB
CSS
.graph.tasks { grid-template-columns: minmax(0, 1fr); }
|
|
.tasks-body { min-width: 0; }
|
|
.task-toolbar { gap: 8px 10px; }
|
|
.task-toolbar [hidden] { display: none; }
|
|
.task-toolbar input[type="search"] { flex: 1 1 120px; min-width: min(120px, 100%); }
|
|
.task-toolbar .segmented button.icon-only { min-width: 30px; padding: 4px 8px; }
|
|
.task-toolbar input[type="number"] { width: 4.5rem; }
|
|
.task-toolbar > .choice-request { margin-left: auto; }
|
|
.tasks > .chips { margin-bottom: 0; }
|
|
body.fit .graph.tasks > .tasks-body, body.fit .graph.tasks > .inbox { flex: 1; min-height: 0; overflow: auto; }
|
|
.choice-agents { display: grid; gap: 6px; max-height: 30vh; overflow: auto; }
|
|
.choice-buttons { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
.chip .count { margin-left: 2px; }
|
|
.task-list, .task-cards { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
|
|
.task-row { display: grid; gap: 6px; min-width: 0; padding: var(--sp-3); border: 1px solid var(--line); border-radius: 12px; background: var(--glass-card); }
|
|
.task-row .head-row { margin-bottom: 0; }
|
|
.task-row > .linkish { justify-self: start; font-size: var(--fs-lg); text-align: left; }
|
|
.task-row.open-work, .task-card.open-work, .wt.open-work, .matrix tr.open-work > th { box-shadow: inset 3px 0 0 var(--warn); }
|
|
.task-row.ended, .task-card.ended { opacity: .72; }
|
|
.task-id { font-size: var(--fs-sm); color: var(--muted); overflow-wrap: anywhere; }
|
|
.task-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; min-width: 0; color: var(--muted); font-size: var(--fs-sm); }
|
|
.task-meta code { overflow-wrap: anywhere; }
|
|
.task-board { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); gap: 12px; align-items: start; }
|
|
.task-column { display: grid; gap: 8px; min-width: 0; padding: var(--sp-3); }
|
|
.task-card { display: grid; gap: 4px; min-width: 0; padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--sunken); font-size: var(--fs-sm); }
|
|
.task-card .linkish { overflow-wrap: anywhere; }
|
|
.flow { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; min-width: 0; font-size: var(--fs-sm); }
|
|
.flow-label { display: inline-flex; align-items: center; gap: 4px; color: var(--muted); font-weight: 650; }
|
|
.flow-side { display: inline-flex; flex-wrap: wrap; gap: 4px; min-width: 0; }
|
|
.flow-ref { padding: 0 6px; border: 1px solid var(--line); border-radius: 6px; background: var(--sunken); line-height: 20px; overflow-wrap: anywhere; }
|
|
.flow-ref.here { border-color: transparent; background: var(--accent-soft); color: var(--accent); font-weight: 650; }
|
|
.flow-arrow { display: inline-flex; color: var(--muted); }
|
|
.flow.invalid { gap: 6px; color: var(--bad); }
|
|
.states.work .state { gap: 5px; }
|
|
.matrix-box { display: grid; gap: 8px; min-width: 0; }
|
|
.matrix-scroll { max-width: 100%; max-height: 70vh; overflow: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--glass-card); }
|
|
table.matrix { border-collapse: separate; border-spacing: 0; font-size: var(--fs-sm); }
|
|
table.matrix th, table.matrix td { padding: 6px 8px; border-bottom: 1px solid var(--line); text-align: center; vertical-align: middle; white-space: nowrap; }
|
|
table.matrix thead th { position: sticky; top: 0; z-index: 1; background: var(--panel); vertical-align: bottom; }
|
|
table.matrix th[scope="row"], table.matrix thead th:first-child { position: sticky; left: 0; background: var(--panel); text-align: left; }
|
|
table.matrix thead th:first-child { z-index: 2; }
|
|
table.matrix th[scope="row"] { z-index: 1; min-width: min(240px, 52vw); max-width: 320px; white-space: normal; }
|
|
.matrix-task { display: grid; gap: 2px; }
|
|
.matrix .party { display: inline-block; max-height: 150px; overflow: hidden; text-overflow: ellipsis; writing-mode: vertical-rl; transform: rotate(180deg); }
|
|
.matrix td .letter + .letter { margin-left: 2px; }
|
|
.task-edit { display: grid; gap: 8px; }
|
|
.task-edit h3 { margin: 6px 0 0; color: var(--muted); font-size: var(--fs-xs); font-weight: 650; letter-spacing: .04em; text-transform: uppercase; }
|
|
.task-form { display: flex; flex-wrap: wrap; align-items: end; gap: 10px; }
|
|
.task-form label { display: grid; gap: 4px; color: var(--muted); font-size: var(--fs-sm); }
|
|
.task-form input[type="number"] { width: 120px; }
|
|
.plan-group { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; color: var(--muted); font-size: var(--fs-sm); }
|
|
.task-toolbar select.field { width: auto; min-width: 0; max-width: min(11rem, 100%); }
|
|
.task-pick { margin: 0; accent-color: var(--accent); }
|
|
.task-eta { display: inline-flex; align-items: center; gap: 4px; color: var(--muted); font-size: var(--fs-sm); white-space: nowrap; }
|
|
.gantt-box, .burn-box { display: grid; gap: 8px; min-width: 0; }
|
|
.gantt-scroll { max-width: 100%; overflow: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--glass-card); }
|
|
.gantt-scroll svg.gantt { display: block; max-width: none; }
|
|
svg .gantt-bar, svg .gantt-dot { fill: color-mix(in srgb, var(--c, var(--accent)) 70%, var(--panel)); stroke: var(--c, var(--accent)); stroke-width: 1; }
|
|
svg .gantt-bar.forecast, svg .gantt-dot.forecast { fill: url(#gantt-hatch); stroke-dasharray: 3 2; }
|
|
svg .tone-ok { --c: var(--ok); }
|
|
svg .tone-bad { --c: var(--bad); }
|
|
svg .tone-info { --c: var(--info); }
|
|
svg .tone-warn { --c: var(--warn); }
|
|
svg .tone-neutral { --c: var(--muted); }
|
|
svg .hatch-ground { fill: var(--accent-soft); }
|
|
svg .hatch-line { stroke: var(--accent); stroke-width: 3; }
|
|
svg .gantt-edge { fill: none; stroke: var(--c); stroke-width: 1.6; opacity: .8; }
|
|
svg .gantt-edge.k-after, .gantt-key.k-after { --c: var(--violet); }
|
|
svg .gantt-edge.k-base, .gantt-key.k-base { --c: var(--info); }
|
|
svg .gantt-edge.k-queue, .gantt-key.k-queue { --c: var(--warn); }
|
|
svg .gantt-tip { fill: var(--muted); }
|
|
.gantt-key, .burn-key { display: inline-flex; align-items: center; gap: 6px; }
|
|
.gantt-key::before, .burn-key::before { content: ""; width: 18px; height: 4px; border-radius: 2px; background: var(--c, var(--accent)); }
|
|
.gantt-key.forecast::before { height: 10px; background: repeating-linear-gradient(45deg, var(--accent) 0 3px, var(--accent-soft) 3px 6px); }
|
|
svg.burn { width: 100%; height: auto; max-height: 60vh; }
|
|
svg .burn-line { fill: none; stroke: var(--c); stroke-width: 2.4; }
|
|
svg.burn .k-scope, .burn-key.k-scope { --c: var(--info); }
|
|
svg.burn .k-done, .burn-key.k-done { --c: var(--ok); }
|
|
svg.burn .k-remaining, .burn-key.k-remaining { --c: var(--accent); }
|
|
svg.burn .k-unestimated, .burn-key.k-unestimated { --c: var(--warn); }
|
|
svg .burn-line.k-unestimated { stroke-dasharray: 6 4; }
|
|
svg .burn-trend { fill: none; stroke: var(--c); stroke-width: 1.6; stroke-dasharray: 2 5; stroke-linecap: round; }
|
|
svg .burn-point { fill: var(--c); stroke: transparent; stroke-width: 10; cursor: help; }
|
|
svg .burn-point:hover { r: 6px; }
|
|
svg .forecast-line { stroke: var(--ok); stroke-width: 1.4; stroke-dasharray: 4 3; }
|
|
svg .forecast-label { fill: var(--ok); font-size: var(--fs-2xs); font-weight: 650; }
|
|
.burn-forecast { display: inline-flex; align-items: center; gap: 6px; }
|
|
svg .node.a-worktree.open circle { stroke: var(--warn); stroke-width: 2.6; stroke-dasharray: 3 2; }
|
|
svg .edge.flow { stroke-dasharray: 2 5; }
|