Keep the task Activity view selector visible without blanking the mobile tab strip. - Portal the Activity view menu to the document body and clamp its fixed position to the visual viewport. - Close and refocus the menu safely across task changes, scrolling, resizing, keyboard selection, and outside clicks. - Add regression coverage for mobile clipping, tab-strip preservation, and the changeset release note. Files changed: .changeset/fn-7375-activity-dropdown-overlay.md | 7 + .../dashboard/app/components/TaskDetailModal.css | 15 +- .../dashboard/app/components/TaskDetailModal.tsx | 186 ++++++++++++++++++--- .../__tests__/TaskDetailModal.css.test.ts | 7 +- ...etailModal.responsive-and-dependencies.test.tsx | 12 +- .../TaskDetailModal.task-activity-chat.test.tsx | 61 +++++++ 6 files changed, 254 insertions(+), 34 deletions(-) Fusion-Task-Id: FN-7375 Fusion-Task-Lineage: 5999507a-edd3-4485-935a-885f7c143ed4 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2919 lines
68 KiB
CSS
2919 lines
68 KiB
CSS
/* === Detail Modal === */
|
|
.task-detail-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
min-width: 0;
|
|
min-height: 0;
|
|
}
|
|
|
|
.modal.task-detail-modal {
|
|
width: min(95vw, 800px);
|
|
max-width: 95vw;
|
|
min-width: 480px;
|
|
height: 85vh;
|
|
min-height: 480px;
|
|
max-height: calc(100dvh - var(--overlay-padding-top, 10vh) - 16px);
|
|
overflow: hidden;
|
|
resize: both;
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetail 2026-06-22-20:00:
|
|
The gray top header band (task id + column badge) was over-padded. Trim its vertical padding for a more compact band, scoped to the task-detail header so the shared global .modal-header (used by other modals) is unaffected. Keep horizontal padding from --modal-padding; only the block padding shrinks.
|
|
*/
|
|
.task-detail-content > .modal-header {
|
|
padding-block: var(--space-sm);
|
|
}
|
|
|
|
.detail-title-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.detail-id {
|
|
font-family: var(--font-mono);
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.detail-column-badge {
|
|
font-size: 0.6875rem;
|
|
padding: calc(var(--space-xs) / 2) var(--space-sm);
|
|
border-radius: var(--radius-pill);
|
|
font-weight: 600;
|
|
letter-spacing: 0.03125rem;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
/*
|
|
FNXC:WorkflowBadges 2026-06-30-00:00:
|
|
Task detail workflow badges share the board badge's slight token-based icon-to-label gap so the canonical metadata badge stays readable while preserving inline truncation and timestamp ownership.
|
|
*/
|
|
.detail-workflow-badge {
|
|
column-gap: calc(var(--space-xs) / 2);
|
|
font-size: 0.6875rem;
|
|
padding: calc(var(--space-xs) / 2) var(--space-sm);
|
|
border-radius: var(--radius-pill);
|
|
font-weight: 600;
|
|
letter-spacing: 0.03125rem;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
flex: 0 1 auto;
|
|
min-width: 0;
|
|
max-width: 100%;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
color: var(--text-muted);
|
|
background: var(--surface-raised);
|
|
border: 1px solid var(--border);
|
|
}
|
|
.badge-triage {
|
|
background: var(--status-triage-bg);
|
|
color: var(--triage);
|
|
}
|
|
.badge-todo {
|
|
background: var(--status-todo-bg);
|
|
color: var(--todo);
|
|
}
|
|
.badge-in-progress {
|
|
background: var(--status-in-progress-bg);
|
|
color: var(--in-progress);
|
|
}
|
|
.badge-in-review {
|
|
background: var(--status-in-review-bg);
|
|
color: var(--in-review);
|
|
}
|
|
.badge-done {
|
|
background: var(--status-done-bg);
|
|
color: var(--done);
|
|
}
|
|
|
|
.detail-body {
|
|
padding: calc(var(--space-lg) + var(--space-xs));
|
|
min-width: 0;
|
|
overflow-x: hidden;
|
|
overflow-y: auto;
|
|
scrollbar-color: var(--border) transparent;
|
|
scrollbar-width: thin;
|
|
flex: 1;
|
|
}
|
|
|
|
.detail-body::-webkit-scrollbar {
|
|
width: 6px;
|
|
}
|
|
|
|
.detail-body::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
|
|
.detail-body::-webkit-scrollbar-thumb {
|
|
background: var(--border);
|
|
border-radius: var(--radius-sm);
|
|
}
|
|
|
|
.detail-body::-webkit-scrollbar-thumb:hover {
|
|
background: var(--text-muted);
|
|
}
|
|
|
|
/* When Activity → Raw Logs is active, switch to flex layout so the log section
|
|
can stretch to fill the remaining space above the action bar.
|
|
The detail-body itself should NOT scroll; the agent-log-viewer scrolls instead. */
|
|
.detail-body--agent-log {
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow-y: hidden;
|
|
}
|
|
|
|
/* Activity → Live and expanded Activity mirror the Raw Logs fill-height layout: the modal body does not scroll;
|
|
each segment owns internal scrolling while composers and controls stay visible. */
|
|
.detail-body--chat,
|
|
.detail-body--planner-chat {
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
overflow-y: hidden;
|
|
/* FNXC:TaskDetailChat 2026-06-13-19:55: Chat box should sit in the chat view without excess vertical spacing around the composer (FN-6418), so only the chat body tightens vertical padding while shared detail tab padding remains unchanged. */
|
|
padding-block: var(--space-md);
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetailPlannerChat 2026-06-30-23:58:
|
|
Planner Chat expand/collapse may reallocate height or hide mobile chrome, but it must not change the chat surface spacing. Keep body padding on the collapsed base selector and let expanded selectors own only flex/height behavior.
|
|
*/
|
|
.detail-body--planner-chat {
|
|
padding: var(--space-md);
|
|
}
|
|
|
|
.detail-title {
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
margin-bottom: var(--space-md);
|
|
overflow-wrap: anywhere;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.detail-title--collapsed {
|
|
display: -webkit-box;
|
|
-webkit-box-orient: vertical;
|
|
-webkit-line-clamp: 2;
|
|
line-clamp: 2;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetail 2026-06-22-20:00:
|
|
Summarize-as-title is an in-field affordance, not a separate full-width row: it sits inline with the title, pinned to the far right and bottom of the title area. Use a nowrap flex row where the title flexes to fill and the button is pushed right (margin-left:auto) and bottom-aligned (align-self:flex-end). The button shrinks to its content so it never steals title space.
|
|
*/
|
|
.detail-heading-row {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
flex-wrap: nowrap;
|
|
gap: var(--space-sm);
|
|
margin-bottom: var(--space-md);
|
|
}
|
|
|
|
.detail-heading-row .detail-title {
|
|
margin-bottom: 0;
|
|
flex: 1 1 auto;
|
|
min-width: 0;
|
|
}
|
|
|
|
.detail-summarize-title-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
background: none;
|
|
border: none;
|
|
color: var(--text-dim);
|
|
font-size: 0.8125rem;
|
|
padding: 0;
|
|
cursor: pointer;
|
|
text-align: right;
|
|
margin-left: auto;
|
|
align-self: flex-end;
|
|
flex: 0 0 auto;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.detail-summarize-title-btn:hover:not(:disabled) {
|
|
color: var(--text);
|
|
}
|
|
|
|
.detail-summarize-title-btn:focus-visible {
|
|
outline: none;
|
|
box-shadow: var(--focus-ring-strong);
|
|
}
|
|
|
|
.detail-summarize-title-btn:disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.detail-description-toggle {
|
|
display: block;
|
|
background: none;
|
|
border: none;
|
|
color: var(--text-dim);
|
|
font-size: 13px;
|
|
padding: 2px 0;
|
|
margin-bottom: var(--space-md);
|
|
cursor: pointer;
|
|
text-align: left;
|
|
}
|
|
|
|
.detail-description-toggle:hover {
|
|
color: var(--text);
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetailMeta 2026-06-13-17:32:
|
|
The task-detail modal metadata must keep priority, execution mode, provenance, PR context, and timestamps in one horizontal row that wraps as needed instead of stacking each child as a separate line.
|
|
*/
|
|
.detail-meta {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-sm) var(--space-md);
|
|
font-size: 12px;
|
|
color: var(--text-muted);
|
|
margin-bottom: var(--space-lg);
|
|
}
|
|
|
|
.detail-provenance {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
margin-top: 0;
|
|
margin-bottom: 0;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.detail-provenance svg {
|
|
width: 1em;
|
|
height: 1em;
|
|
}
|
|
|
|
.detail-provenance-link {
|
|
padding: 0;
|
|
border: 0;
|
|
background: transparent;
|
|
color: var(--todo);
|
|
cursor: pointer;
|
|
text-decoration: none;
|
|
font: inherit;
|
|
}
|
|
|
|
.detail-provenance-link:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.detail-provenance-link:focus-visible {
|
|
outline: none;
|
|
box-shadow: var(--focus-ring-strong);
|
|
border-radius: var(--radius-sm);
|
|
}
|
|
|
|
.detail-provenance-context {
|
|
display: inline-block;
|
|
max-width: 32ch;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
vertical-align: bottom;
|
|
}
|
|
|
|
.detail-timestamps {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
flex-wrap: nowrap;
|
|
gap: var(--space-xs);
|
|
color: var(--text-dim);
|
|
margin-top: 0;
|
|
}
|
|
|
|
.detail-timestamp-item {
|
|
display: inline-flex;
|
|
align-items: baseline;
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.detail-timestamp-label {
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.detail-timestamp-separator {
|
|
color: var(--text-dim);
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
/*
|
|
FNXC:TaskDetail 2026-06-22-20:00:
|
|
Keep summarize-as-title pinned bottom-right inline with the title on mobile too (no wrap to a separate row), matching the desktop in-field affordance.
|
|
*/
|
|
.detail-heading-row {
|
|
align-items: flex-end;
|
|
}
|
|
|
|
.detail-summarize-title-btn {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.detail-meta {
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.detail-provenance {
|
|
align-items: center;
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetailWorkflow 2026-06-30-07:37:
|
|
Task details show workflow identity in the Updated timestamp section across desktop and mobile. Keep the canonical badge inline with Created/Updated metadata so header rows, embedded detail hosts, and mobile back-header details do not render duplicate workflow badges or empty mobile-only shells.
|
|
*/
|
|
.detail-timestamps {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: nowrap;
|
|
}
|
|
|
|
.detail-provenance-context {
|
|
max-width: 20ch;
|
|
}
|
|
|
|
.detail-timestamp-item {
|
|
align-items: baseline;
|
|
flex-wrap: nowrap;
|
|
}
|
|
}
|
|
|
|
.detail-meta-inline-controls {
|
|
/*
|
|
FNXC:TaskDetail 2026-06-22-20:00:
|
|
Priority chip and speed (execution-mode) toggle share one min-height token so they render at identical, equal height. Reduced from the old calc(space-2xl + space-xs) (~too tall) to a compact 30px that stays legible and tappable. Both controls also get trimmed vertical padding to match.
|
|
*/
|
|
--detail-priority-control-min-height: 30px;
|
|
|
|
display: flex;
|
|
align-items: stretch;
|
|
flex-wrap: nowrap;
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.detail-priority-chip {
|
|
gap: var(--space-xs);
|
|
min-height: var(--detail-priority-control-min-height);
|
|
padding-block: var(--space-xs);
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.detail-priority-chip--saving {
|
|
opacity: 0.75;
|
|
}
|
|
|
|
.detail-priority-select {
|
|
border: 0;
|
|
background: transparent;
|
|
color: inherit;
|
|
font: inherit;
|
|
text-transform: uppercase;
|
|
letter-spacing: inherit;
|
|
cursor: pointer;
|
|
padding: 0;
|
|
min-height: inherit;
|
|
}
|
|
|
|
.detail-priority-select:focus-visible {
|
|
outline: none;
|
|
box-shadow: var(--focus-ring-strong);
|
|
border-radius: var(--radius-sm);
|
|
}
|
|
|
|
.detail-priority-select:disabled {
|
|
cursor: wait;
|
|
}
|
|
|
|
.detail-priority-select option {
|
|
color: var(--text);
|
|
background: var(--surface);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.detail-execution-mode-toggle {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
min-height: var(--detail-priority-control-min-height);
|
|
padding-block: var(--space-xs);
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.detail-execution-mode-toggle svg {
|
|
width: 1em;
|
|
height: 1em;
|
|
}
|
|
|
|
.detail-execution-mode-toggle--fast {
|
|
color: var(--color-warning);
|
|
}
|
|
|
|
.detail-execution-mode-toggle--fast svg {
|
|
color: var(--color-warning);
|
|
background: color-mix(in srgb, var(--color-warning) 20%, transparent);
|
|
border-radius: var(--radius-pill);
|
|
padding: var(--space-xs);
|
|
box-shadow: var(--glow-warning);
|
|
}
|
|
|
|
.detail-execution-mode-toggle--saving {
|
|
opacity: 0.75;
|
|
}
|
|
|
|
.detail-execution-mode-toggle:disabled {
|
|
cursor: wait;
|
|
}
|
|
|
|
|
|
/* Error alert in task detail modal */
|
|
.detail-error-alert {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: var(--space-md);
|
|
margin: var(--space-md) 0 var(--space-lg);
|
|
padding: var(--space-md) calc(var(--space-md) + var(--space-xs) / 2);
|
|
background: color-mix(in srgb, var(--color-error-dark) 10%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--color-error-dark) 30%, transparent);
|
|
border-radius: var(--radius-md);
|
|
}
|
|
|
|
.detail-error-icon {
|
|
flex-shrink: 0;
|
|
font-size: 18px;
|
|
line-height: 1;
|
|
}
|
|
|
|
.detail-error-content {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.detail-error-title {
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
color: var(--color-error-dark);
|
|
margin-bottom: var(--space-xs);
|
|
}
|
|
|
|
.detail-error-message {
|
|
font-size: 12px;
|
|
color: var(--text-muted);
|
|
line-height: 1.5;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.task-pause-reason {
|
|
margin: var(--space-md) 0 var(--space-lg);
|
|
padding: var(--space-md);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
background: color-mix(in srgb, var(--color-warning) 12%, transparent);
|
|
}
|
|
|
|
.task-pause-reason-label {
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
}
|
|
|
|
.task-pause-stderr {
|
|
margin: var(--space-sm) 0 0;
|
|
padding: var(--space-sm);
|
|
border-radius: var(--radius-sm);
|
|
border: 1px solid var(--border);
|
|
background: var(--bg);
|
|
color: var(--text-muted);
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
max-height: 220px;
|
|
overflow: auto;
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.detail-section {
|
|
margin-top: var(--space-lg);
|
|
}
|
|
|
|
.detail-pr-tab {
|
|
display: grid;
|
|
gap: var(--space-lg);
|
|
}
|
|
|
|
.detail-pr-tab .detail-section,
|
|
.detail-pr-section {
|
|
margin-top: 0;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.detail-pr-tab {
|
|
gap: var(--space-md);
|
|
}
|
|
}
|
|
|
|
.detail-provider-icons {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.detail-meta-label-icon {
|
|
vertical-align: middle;
|
|
margin-right: var(--space-xs);
|
|
}
|
|
|
|
.detail-source-section {
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
background: var(--card);
|
|
padding: var(--space-sm) var(--space-md);
|
|
}
|
|
|
|
.detail-source-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: var(--space-md);
|
|
margin: 0;
|
|
}
|
|
|
|
.detail-source-grid dt {
|
|
font-size: 11px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.4px;
|
|
color: var(--text-muted);
|
|
margin-bottom: var(--space-xs);
|
|
}
|
|
|
|
.detail-source-grid dd {
|
|
margin: 0;
|
|
color: var(--text);
|
|
font-family: var(--font-mono);
|
|
word-break: break-word;
|
|
}
|
|
|
|
.detail-source-link {
|
|
color: var(--todo);
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.detail-source-link--summary {
|
|
text-decoration: none;
|
|
}
|
|
|
|
.detail-source-link:hover {
|
|
color: var(--text);
|
|
}
|
|
|
|
.detail-source-empty {
|
|
color: var(--text-dim);
|
|
}
|
|
|
|
.detail-source-edit-group {
|
|
margin-top: var(--space-sm);
|
|
}
|
|
|
|
.detail-source-edit-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.detail-source-edit-group small {
|
|
display: block;
|
|
margin-top: var(--space-xs);
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.detail-source-header {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.detail-source-section .detail-source-header {
|
|
flex-wrap: nowrap;
|
|
align-items: center;
|
|
min-width: 0;
|
|
}
|
|
|
|
.detail-source-summary {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.detail-source-section .detail-source-summary {
|
|
flex: 1 1 auto;
|
|
min-width: 0;
|
|
}
|
|
|
|
.detail-source-label {
|
|
color: var(--text-muted);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.detail-source-provider-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
padding: 0 var(--space-xs);
|
|
border-radius: var(--radius-pill);
|
|
background: color-mix(in srgb, var(--text-muted) 18%, transparent);
|
|
color: var(--text-muted);
|
|
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.detail-source-provider-badge svg {
|
|
width: 1em;
|
|
height: 1em;
|
|
}
|
|
|
|
.detail-source-number {
|
|
color: var(--text);
|
|
font-family: var(--font-mono);
|
|
}
|
|
|
|
.detail-github-tracking-enable {
|
|
margin-left: auto;
|
|
align-self: center;
|
|
flex: 0 0 auto;
|
|
min-width: 0;
|
|
min-height: 0;
|
|
padding-block: calc(var(--space-xs) / 2);
|
|
padding-inline: var(--space-sm);
|
|
line-height: 1.2;
|
|
}
|
|
|
|
.detail-source-toggle {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
min-width: calc(var(--space-lg) + var(--space-xl) - var(--space-xs));
|
|
min-height: calc(var(--space-lg) + var(--space-xl) - var(--space-xs));
|
|
padding: var(--space-xs);
|
|
border: 0;
|
|
border-radius: var(--radius-sm);
|
|
background: transparent;
|
|
color: var(--text-muted);
|
|
cursor: pointer;
|
|
transition: background var(--transition-fast), color var(--transition-fast);
|
|
}
|
|
|
|
.detail-source-section .detail-source-toggle {
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.detail-source-header .detail-source-toggle {
|
|
margin-left: var(--space-sm);
|
|
}
|
|
|
|
.detail-source-toggle:hover {
|
|
color: var(--text);
|
|
background: var(--card-hover);
|
|
}
|
|
|
|
.detail-source-toggle:focus-visible {
|
|
outline: none;
|
|
box-shadow: var(--focus-ring-strong);
|
|
}
|
|
|
|
.detail-source-chevron--expanded {
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
.detail-source-section .detail-source-grid {
|
|
margin-top: var(--space-sm);
|
|
padding-top: var(--space-sm);
|
|
border-top: 1px solid var(--border);
|
|
}
|
|
|
|
.detail-github-tracking-section {
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
background: var(--card);
|
|
padding: var(--space-xs) var(--space-md);
|
|
}
|
|
|
|
.detail-github-tracking-section .detail-source-header {
|
|
flex-wrap: nowrap;
|
|
align-items: center;
|
|
min-width: 0;
|
|
}
|
|
|
|
.detail-github-tracking-section .detail-source-summary {
|
|
flex: 1 1 auto;
|
|
flex-wrap: nowrap;
|
|
min-width: 0;
|
|
}
|
|
|
|
.detail-github-tracking-section .detail-source-empty {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.detail-github-tracking-section .detail-source-toggle {
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.detail-github-tracking-section .detail-github-tracking-enable {
|
|
align-self: center;
|
|
}
|
|
|
|
.detail-github-tracking-spinner {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-left: auto;
|
|
align-self: center;
|
|
flex: 0 0 auto;
|
|
min-width: var(--space-lg);
|
|
min-height: var(--space-lg);
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.detail-github-tracking-content {
|
|
margin-top: var(--space-xs);
|
|
padding-top: var(--space-xs);
|
|
border-top: 1px solid var(--border);
|
|
}
|
|
|
|
.detail-github-tracking-grid {
|
|
margin-top: 0;
|
|
padding-top: 0;
|
|
}
|
|
|
|
.detail-github-issue-state {
|
|
font-weight: 600;
|
|
text-transform: lowercase;
|
|
}
|
|
|
|
.detail-github-issue-state--open {
|
|
color: var(--color-success);
|
|
}
|
|
|
|
.detail-github-issue-state--closed {
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.detail-github-tracking-controls {
|
|
margin-top: var(--space-sm);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.detail-github-tracking-helper {
|
|
display: block;
|
|
color: var(--text-muted);
|
|
line-height: 1.4;
|
|
white-space: normal;
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.detail-github-tracking-repo-row {
|
|
display: flex;
|
|
gap: var(--space-sm);
|
|
align-items: center;
|
|
}
|
|
|
|
.detail-github-tracking-repo-row .input {
|
|
flex: 1;
|
|
}
|
|
|
|
.detail-github-tracking-error {
|
|
color: var(--color-error);
|
|
}
|
|
|
|
/* Activity → Raw Logs: stretch to fill the remaining modal body height
|
|
so the log viewer uses all available space above the action bar. */
|
|
.detail-section--agent-log {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
min-height: 0;
|
|
margin-top: var(--space-lg);
|
|
}
|
|
|
|
.detail-section--chat {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
min-height: 0;
|
|
/* FNXC:TaskDetailChat 2026-06-13-19:55: Chat box should sit in the chat view without excess vertical spacing around the composer (FN-6418), so the chat section opts out of the shared top margin used by other detail tabs. */
|
|
margin-top: 0;
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetailChat 2026-06-16-22:13:
|
|
Expanded chat should take over the modal except for the task title row, so users keep task ID and column context while tabs and modal actions stay hidden.
|
|
|
|
FNXC:TaskDetailChat 2026-06-22-13:27:
|
|
Expanded chat must also cover the task metadata row — priority, execution mode, provenance/Created by, and Created/Updated timestamps — so the chat grows all the way up to the title row instead of stopping below secondary metadata controls.
|
|
|
|
FNXC:TaskDetailActivity 2026-06-30-23:55:
|
|
The same expanded-mode chrome collapse now applies to all Activity segments: Live, Feed, and Raw Logs. Keep the legacy `--chat-expanded` class for test and styling compatibility while treating it as Activity-expanded behavior.
|
|
*/
|
|
.task-detail-content--chat-expanded .detail-meta {
|
|
display: none;
|
|
}
|
|
|
|
.task-detail-content--chat-expanded .detail-tabs {
|
|
/* FNXC:TaskDetailActivity 2026-06-30-23:59: Expanded Activity still needs the top-level Activity tab dropdown because the in-panel view selector was removed. Keep the tab strip visible so Live, Feed, and Raw remain switchable while the footer and metadata chrome stay collapsed. */
|
|
display: flex;
|
|
}
|
|
|
|
.task-detail-content--chat-expanded .modal-actions {
|
|
display: none;
|
|
}
|
|
|
|
.task-detail-content--chat-expanded .modal-header {
|
|
flex: 0 0 auto;
|
|
justify-content: space-between;
|
|
padding-block: var(--space-sm);
|
|
}
|
|
|
|
.task-detail-content--chat-expanded .detail-body--chat {
|
|
flex: 1;
|
|
min-height: 0;
|
|
padding: var(--space-md);
|
|
}
|
|
|
|
.task-detail-content--chat-expanded .detail-section--chat {
|
|
flex: 1;
|
|
min-height: 0;
|
|
margin-top: 0;
|
|
}
|
|
|
|
.task-detail-content--chat-expanded .detail-activity {
|
|
display: flex;
|
|
flex: 1;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
}
|
|
|
|
.task-detail-content--chat-expanded .detail-activity-list {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetailPlannerChat 2026-06-30-23:58:
|
|
Planner Chat defaults to a focused state, but operator steering says large screens should keep the full task-detail context visible. Desktop therefore uses the same internal-scroll chat body without hiding rows; narrow/mobile layouts collapse nonessential title/provenance/actions so the composer remains reachable while header identity and close/back controls stay available.
|
|
|
|
FNXC:TaskDetailPlannerChat 2026-06-30-20:06:
|
|
Expanded Planner Chat must still expose task Priority, Execution Mode, and the tab bar on mobile. Hide only lower-priority metadata in the metadata row so inline handlers and tab navigation remain reachable without overlapping the transcript/composer.
|
|
|
|
FNXC:TaskDetailPlannerChat 2026-07-02-00:04:
|
|
Expanded Planner Chat must keep the task title and workflow badge visible on mobile. The title preserves task identity, and the workflow badge is owned by the timestamps row, so this mode hides lower-priority metadata but not `.detail-heading-row` or `.detail-timestamps`; timestamp labels inside that row can hide so the workflow badge remains compact.
|
|
|
|
FNXC:TaskDetailPlannerChat 2026-07-02-00:17:
|
|
Planner Chat should not open expanded by default. When the user expands it, the view should behave like Activity expansion: the chat panel takes nearly the whole modal, with only task title and workflow identity left above it for context.
|
|
*/
|
|
.detail-section--planner-chat {
|
|
display: flex;
|
|
flex: 1;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
margin-top: 0;
|
|
}
|
|
|
|
.task-detail-content--planner-chat-expanded .detail-body--planner-chat {
|
|
flex: 1;
|
|
min-height: 0;
|
|
padding: var(--space-md);
|
|
}
|
|
|
|
.task-detail-content--planner-chat-expanded .detail-section--planner-chat {
|
|
flex: 1;
|
|
min-height: 0;
|
|
}
|
|
|
|
.task-detail-content--planner-chat-expanded .detail-description-toggle,
|
|
.task-detail-content--planner-chat-expanded .detail-near-duplicate-banner,
|
|
.task-detail-content--planner-chat-expanded .task-fields-section,
|
|
.task-detail-content--planner-chat-expanded .branch-group-card,
|
|
.task-detail-content--planner-chat-expanded .workspace-worktrees-summary,
|
|
.task-detail-content--planner-chat-expanded .modal-actions,
|
|
.task-detail-content--planner-chat-expanded .detail-tabs,
|
|
.task-detail-content--planner-chat-expanded .detail-meta-inline-controls,
|
|
.task-detail-content--planner-chat-expanded .detail-provenance {
|
|
display: none;
|
|
}
|
|
|
|
.task-detail-content--planner-chat-expanded .modal-header {
|
|
flex: 0 0 auto;
|
|
justify-content: space-between;
|
|
padding-block: var(--space-sm);
|
|
}
|
|
|
|
.task-detail-content--planner-chat-expanded .detail-meta {
|
|
flex: 0 0 auto;
|
|
margin-bottom: var(--space-sm);
|
|
}
|
|
|
|
.task-detail-content--planner-chat-expanded .detail-timestamps .detail-timestamp-item,
|
|
.task-detail-content--planner-chat-expanded .detail-timestamps .detail-timestamp-separator {
|
|
display: none;
|
|
}
|
|
|
|
|
|
.detail-spec-edit-trigger {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
margin-bottom: var(--space-md);
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.detail-spec-edit-trigger {
|
|
align-items: stretch;
|
|
}
|
|
|
|
.detail-spec-edit-trigger .btn {
|
|
flex: 1 1 auto;
|
|
}
|
|
}
|
|
|
|
.detail-attachments-grid {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-md);
|
|
margin-bottom: var(--space-sm);
|
|
}
|
|
|
|
.detail-attachment-card {
|
|
position: relative;
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-sm);
|
|
padding: var(--space-xs);
|
|
background: var(--card);
|
|
}
|
|
|
|
.detail-attachment-link {
|
|
display: block;
|
|
}
|
|
|
|
.detail-attachment-image {
|
|
display: block;
|
|
max-width: 150px;
|
|
max-height: 100px;
|
|
border-radius: var(--radius-sm);
|
|
}
|
|
|
|
.detail-attachment-meta {
|
|
margin-top: var(--space-xs);
|
|
font-size: 11px;
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.detail-attachment-delete {
|
|
position: absolute;
|
|
top: 2px;
|
|
right: 2px;
|
|
width: 20px;
|
|
height: 20px;
|
|
padding: 0;
|
|
border: none;
|
|
border-radius: 50%;
|
|
background: color-mix(in srgb, var(--bg) 65%, var(--text));
|
|
color: var(--text);
|
|
cursor: pointer;
|
|
font-size: 12px;
|
|
line-height: 20px;
|
|
text-align: center;
|
|
}
|
|
|
|
.detail-empty-inline {
|
|
margin-bottom: var(--space-sm);
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.detail-hidden-file-input {
|
|
display: none;
|
|
}
|
|
|
|
.dep-remove-btn {
|
|
margin-left: 6px;
|
|
background: none;
|
|
border: none;
|
|
color: var(--text-muted);
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
padding: 0 4px;
|
|
}
|
|
|
|
.dep-trigger-wrap {
|
|
position: relative;
|
|
}
|
|
|
|
.detail-blocking-item--stale {
|
|
color: var(--color-warning);
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.modal-actions-spacer {
|
|
flex: 1;
|
|
}
|
|
|
|
/* Detail modal split-menu dropdowns */
|
|
.detail-actions-dropdown,
|
|
.detail-move-dropdown {
|
|
position: relative;
|
|
}
|
|
|
|
.detail-move-actions-in-review {
|
|
display: flex;
|
|
gap: var(--space-md);
|
|
align-items: center;
|
|
}
|
|
|
|
.detail-move-btn {
|
|
position: relative;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.detail-move-btn__label {
|
|
flex: 1;
|
|
}
|
|
|
|
.detail-move-btn__arrow {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: var(--space-xs);
|
|
margin-right: calc(-1 * var(--space-xs));
|
|
margin-block: calc(-1 * var(--space-xs));
|
|
border-radius: 0 var(--radius-md) var(--radius-md) 0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
@media (hover: hover) {
|
|
.detail-move-btn:hover .detail-move-btn__arrow {
|
|
background: color-mix(in srgb, var(--text) 12%, transparent);
|
|
}
|
|
}
|
|
|
|
.detail-actions-menu,
|
|
.detail-move-menu {
|
|
position: absolute;
|
|
bottom: calc(100% + var(--space-xs));
|
|
z-index: 50;
|
|
min-width: calc(var(--space-2xl) + var(--space-2xl) + var(--space-md));
|
|
background: var(--surface);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
box-shadow: var(--shadow-md);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.detail-actions-menu {
|
|
left: 0;
|
|
}
|
|
|
|
.detail-move-menu {
|
|
right: 0;
|
|
}
|
|
|
|
.detail-actions-menu-item,
|
|
.detail-move-menu-item {
|
|
display: block;
|
|
width: 100%;
|
|
padding: var(--space-sm) var(--space-md);
|
|
font-size: 13px;
|
|
font-weight: 400;
|
|
color: var(--text);
|
|
background: transparent;
|
|
border: none;
|
|
cursor: pointer;
|
|
text-align: left;
|
|
transition: background var(--transition-fast);
|
|
}
|
|
|
|
.detail-actions-menu-item:hover,
|
|
.detail-move-menu-item:hover {
|
|
background: var(--surface-hover, color-mix(in srgb, var(--text) 6%, transparent));
|
|
}
|
|
|
|
.detail-actions-menu-item:focus,
|
|
.detail-move-menu-item:focus {
|
|
outline: none;
|
|
background: var(--surface-hover, color-mix(in srgb, var(--text) 6%, transparent));
|
|
}
|
|
|
|
.detail-actions-menu-note {
|
|
color: var(--text-muted);
|
|
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetailModalResponsive 2026-06-16-19:13:
|
|
FN-6500 fixes a tablet regression from FN-5599: the task-detail overlay offset and modal max-height subtraction must use the same `--overlay-padding-top` value so the `.modal-actions` footer remains on-screen, while the modal uses more of the tablet viewport to avoid a cramped layout.
|
|
*/
|
|
@media (min-width: 769px) and (max-width: 1024px) {
|
|
.modal-overlay:has(.task-detail-modal) {
|
|
--overlay-padding-top: 6vh;
|
|
}
|
|
|
|
.modal.task-detail-modal {
|
|
width: 98vw;
|
|
max-width: 98vw;
|
|
height: 92vh;
|
|
max-height: calc(100dvh - var(--overlay-padding-top, 6vh) - var(--space-md));
|
|
}
|
|
|
|
.detail-tabs {
|
|
width: 100%;
|
|
max-inline-size: 100%;
|
|
min-width: 0;
|
|
overflow-x: auto;
|
|
overflow-y: hidden;
|
|
overscroll-behavior-inline: contain;
|
|
touch-action: pan-x pan-y;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
.detail-tab {
|
|
touch-action: pan-x pan-y;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.detail-move-btn__arrow {
|
|
padding: var(--space-xs);
|
|
}
|
|
|
|
/* Full-screen sheet on mobile. Desktop `min-width: 480px` would otherwise
|
|
push the modal off narrow viewports; overlay padding-top leaves awkward
|
|
gaps. Resize is disabled (touchscreens can't drag the grip). */
|
|
.modal-overlay:has(.task-detail-modal) {
|
|
padding-top: 0;
|
|
align-items: stretch;
|
|
justify-content: stretch;
|
|
}
|
|
|
|
.modal.task-detail-modal {
|
|
width: 100vw;
|
|
min-width: 0;
|
|
max-width: 100vw;
|
|
height: 100dvh;
|
|
min-height: 0;
|
|
max-height: 100dvh;
|
|
margin: 0;
|
|
border: none;
|
|
border-radius: 0;
|
|
resize: none;
|
|
}
|
|
|
|
.detail-body--chat {
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
overflow-y: hidden;
|
|
padding-block: var(--space-sm);
|
|
}
|
|
|
|
.detail-section--chat {
|
|
flex: 1;
|
|
min-height: 0;
|
|
margin-top: 0;
|
|
}
|
|
|
|
.task-detail-content--chat-expanded .detail-body--chat {
|
|
padding: var(--space-sm);
|
|
}
|
|
|
|
.task-detail-content--chat-expanded .detail-tabs {
|
|
display: flex;
|
|
}
|
|
|
|
.task-detail-content--chat-expanded .modal-actions {
|
|
display: none;
|
|
}
|
|
|
|
.detail-body--planner-chat {
|
|
padding: var(--space-sm);
|
|
}
|
|
}
|
|
|
|
.detail-actions-menu-item-danger {
|
|
color: var(--color-error);
|
|
}
|
|
|
|
.detail-actions-menu-item-danger:hover {
|
|
background: color-mix(in srgb, var(--color-error) 8%, transparent);
|
|
}
|
|
|
|
.detail-refine-overlay {
|
|
position: fixed;
|
|
inset: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: color-mix(in srgb, var(--bg) 70%, transparent);
|
|
z-index: 100;
|
|
}
|
|
|
|
.detail-refine-modal {
|
|
max-width: min(90vw, calc(var(--space-2xl) * 16));
|
|
width: 90%;
|
|
margin: 0;
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetail 2026-06-22-18:40:
|
|
Embedded in the full-width board-card panel the detail content must be width-bounded so it cannot overflow and get clipped on the right. Constrain the embedded root and its header/body to the host width (width:100%; min-width:0; max-width:100%); min-width:0 lets inner flex rows (header title row, tabs, action bars) shrink and wrap instead of forcing horizontal overflow. Vertical scroll stays on .detail-body.
|
|
*/
|
|
.task-detail-content--embedded {
|
|
height: 100%;
|
|
width: 100%;
|
|
min-width: 0;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.task-detail-content--embedded .modal-header,
|
|
.task-detail-content--embedded .detail-body,
|
|
.task-detail-content--embedded .detail-tabs,
|
|
.task-detail-content--embedded .modal-actions {
|
|
width: 100%;
|
|
min-width: 0;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.task-detail-content--embedded .detail-tabs {
|
|
overflow-x: auto;
|
|
overflow-y: hidden;
|
|
overscroll-behavior-inline: contain;
|
|
touch-action: pan-x pan-y;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
.task-detail-content--embedded .detail-tab {
|
|
touch-action: pan-x pan-y;
|
|
}
|
|
|
|
/* The gray header row must wrap (task id left, Back-to-board right) instead of overflowing on narrow panels. */
|
|
.task-detail-content--embedded .modal-header {
|
|
flex-wrap: wrap;
|
|
row-gap: var(--space-xs);
|
|
}
|
|
|
|
.task-detail-content--embedded .detail-title-row {
|
|
min-width: 0;
|
|
}
|
|
|
|
.task-detail-content--embedded .modal-header-actions {
|
|
min-width: 0;
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetail 2026-06-22-18:40:
|
|
"Back to board" affordance inside the gray header. margin-left:auto pushes it to the far right (across from the task id on the left); it shares the header-actions row but stays pinned right and wraps when space is tight. Theme tokens only.
|
|
*/
|
|
.task-detail-header-back-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
margin-left: auto;
|
|
padding: var(--space-xs) var(--space-sm);
|
|
font-size: 13px;
|
|
color: var(--text-muted);
|
|
background: var(--card);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-sm);
|
|
cursor: pointer;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.task-detail-header-back-btn:hover {
|
|
color: var(--text);
|
|
background: var(--card-hover);
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetail 2026-06-22-20:15:
|
|
The footer Actions/Move dropdown buttons sit at the BOTTOM of the embedded panel, so the menus must open UPWARD (above the button). The earlier embedded rule opened them downward (top:100%), which dropped the menu off the panel bottom where the body's overflow clipped it — the popups appeared to vanish. Anchor to bottom:100% so they always open above the trigger and stay on-screen.
|
|
*/
|
|
.task-detail-content--embedded .detail-actions-menu,
|
|
.task-detail-content--embedded .detail-move-menu {
|
|
bottom: calc(100% + var(--space-xs));
|
|
top: auto;
|
|
}
|
|
|
|
.detail-refine-title {
|
|
margin: 0;
|
|
}
|
|
|
|
.detail-refine-help {
|
|
margin-bottom: var(--space-md);
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.detail-refine-textarea {
|
|
width: 100%;
|
|
min-height: 120px;
|
|
padding: var(--space-md);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-sm);
|
|
background: var(--surface);
|
|
color: var(--text);
|
|
font-size: 14px;
|
|
resize: vertical;
|
|
}
|
|
|
|
.detail-refine-input-group {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-top: var(--space-sm);
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.detail-refine-char-count {
|
|
font-size: 12px;
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.task-changes-state {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: var(--space-sm);
|
|
padding: var(--space-xl);
|
|
min-height: 180px;
|
|
border: 1px dashed var(--border);
|
|
border-radius: var(--radius-md);
|
|
background: var(--card);
|
|
text-align: center;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.task-changes-state--loading,
|
|
.task-changes-state--error {
|
|
flex-direction: row;
|
|
min-height: auto;
|
|
padding: var(--space-md);
|
|
justify-content: flex-start;
|
|
border-style: solid;
|
|
}
|
|
|
|
.task-changes-state--error {
|
|
color: var(--color-error);
|
|
background: color-mix(in srgb, var(--color-error) 8%, transparent);
|
|
border-color: color-mix(in srgb, var(--color-error) 25%, transparent);
|
|
}
|
|
|
|
.task-changes-state-hint {
|
|
font-size: 12px;
|
|
color: var(--text-dim);
|
|
max-width: 440px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.task-changes-tab {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-md);
|
|
}
|
|
|
|
.changes-header {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: var(--space-md);
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.changes-header h4 {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
margin: 0;
|
|
}
|
|
|
|
.changes-header-actions {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.changes-header-actions-wrapper {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-end;
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.changes-header-actions-secondary {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
/* Keep the compact Refresh and expand buttons visually aligned in the Changes
|
|
header even though one is text and the other is icon-only. */
|
|
.task-changes-tab .changes-header-actions-secondary > .btn {
|
|
height: calc(var(--space-lg) + var(--space-sm) + (var(--space-xs) / 2));
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.task-changes-tab .changes-header-actions-secondary > .btn-icon {
|
|
width: calc(var(--space-lg) + var(--space-sm) + (var(--space-xs) / 2));
|
|
min-width: calc(var(--space-lg) + var(--space-sm) + (var(--space-xs) / 2));
|
|
min-height: calc(var(--space-lg) + var(--space-sm) + (var(--space-xs) / 2));
|
|
padding: 0;
|
|
gap: 0;
|
|
justify-content: center;
|
|
}
|
|
|
|
.changes-nav {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.changes-nav-indicator {
|
|
font-size: 12px;
|
|
color: var(--text-muted);
|
|
font-family: var(--font-mono);
|
|
min-width: 32px;
|
|
text-align: center;
|
|
}
|
|
|
|
.changes-file-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.changes-file-item {
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
background: var(--card);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.changes-file-item.expanded {
|
|
border-color: var(--text-dim);
|
|
background: var(--surface);
|
|
}
|
|
|
|
.changes-file-header {
|
|
width: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
padding: var(--space-sm) var(--space-md);
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--text);
|
|
text-align: left;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.changes-file-header:hover {
|
|
background: var(--card-hover);
|
|
}
|
|
|
|
.changes-file-header:focus-visible {
|
|
outline: none;
|
|
box-shadow: var(--focus-ring-strong);
|
|
}
|
|
|
|
.changes-file-header:active {
|
|
background: var(--border);
|
|
}
|
|
|
|
.changes-file-toggle {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: var(--text-muted);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.changes-file-status {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 20px;
|
|
font-family: var(--font-mono);
|
|
font-size: 12px;
|
|
font-weight: 700;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* Semantic status colors for changed-file entries — theme-aware via CSS variables */
|
|
.changes-file-status--added {
|
|
color: var(--color-success);
|
|
}
|
|
|
|
.changes-file-status--modified {
|
|
color: var(--color-info);
|
|
}
|
|
|
|
.changes-file-status--deleted {
|
|
color: var(--color-error-dark);
|
|
}
|
|
|
|
.changes-file-status--unknown {
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
/* Stat summary in changes header */
|
|
.changes-stat-summary {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 2px;
|
|
margin-left: var(--space-sm);
|
|
font-size: 12px;
|
|
font-family: var(--font-mono);
|
|
}
|
|
|
|
.changes-stat-summary .diff-add {
|
|
color: var(--color-success);
|
|
}
|
|
|
|
.changes-stat-summary .diff-del {
|
|
color: var(--color-error-dark);
|
|
}
|
|
|
|
/* Task-specific changes header: stacked title + stats layout */
|
|
.task-changes-tab .task-changes-header-title {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
}
|
|
|
|
.task-changes-tab .task-changes-header-title h4 {
|
|
margin: 0;
|
|
}
|
|
|
|
.task-changes-tab .task-changes-stats {
|
|
margin-left: calc(var(--space-lg) + var(--space-sm)); /* align with text after icon + gap */
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.task-changes-tab .changes-header {
|
|
align-items: stretch;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.task-changes-tab .changes-header-actions-wrapper {
|
|
width: 100%;
|
|
flex-direction: row;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
justify-content: flex-start;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.task-changes-tab .changes-header-actions,
|
|
.task-changes-tab .changes-header-actions-secondary {
|
|
flex-wrap: wrap;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.task-changes-tab .changes-header-actions {
|
|
flex: 1 1 auto;
|
|
min-width: 0;
|
|
}
|
|
|
|
.task-changes-tab .changes-header-actions-secondary {
|
|
margin-left: auto;
|
|
}
|
|
|
|
.task-changes-tab .task-changes-header-title {
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.task-changes-tab .task-changes-stats {
|
|
margin-left: calc(var(--space-lg) + var(--space-xs));
|
|
}
|
|
}
|
|
|
|
/* Truncate parent dirs from the LEFT so the filename stays visible. JSX
|
|
* wraps the path in `<bdo dir="ltr">` to preserve readable left-to-right
|
|
* display while `direction: rtl` flips the ellipsis to the start. */
|
|
.changes-file-path {
|
|
flex: 1;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
direction: rtl;
|
|
font-family: var(--font-mono);
|
|
font-size: 12px;
|
|
}
|
|
|
|
.changes-file-stat {
|
|
flex-shrink: 0;
|
|
font-family: var(--font-mono);
|
|
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.changes-file-content {
|
|
border-top: 1px solid var(--border);
|
|
}
|
|
|
|
.changes-diff-patch {
|
|
margin: 0;
|
|
padding: var(--space-sm) 0;
|
|
background: color-mix(in srgb, var(--bg) 86%, var(--text));
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
line-height: 1.5;
|
|
overflow-x: auto;
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.changes-diff-patch.changes-diff-patch--wrap {
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.changes-diff-patch.changes-diff-patch--nowrap {
|
|
white-space: pre;
|
|
word-break: normal;
|
|
}
|
|
|
|
/* Summary section - styled for done tasks with success accent */
|
|
.detail-summary {
|
|
background: color-mix(in srgb, var(--color-success) 8%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--color-success) 25%, transparent);
|
|
border-radius: var(--radius-md);
|
|
padding: var(--space-lg);
|
|
}
|
|
|
|
.detail-summary h4 {
|
|
color: var(--color-success);
|
|
margin-bottom: var(--space-md);
|
|
}
|
|
|
|
.detail-summary .markdown-body {
|
|
font-size: 14px;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.detail-summary .markdown-body p:first-child {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.detail-summary .markdown-body p:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetailSummaryTab 2026-06-27-00:00:
|
|
The done-task Summary tab is a scrollable overview composed from existing detail data. Reuse detail-section/markdown conventions and tokenized spacing/colors so the new landing tab preserves modal hierarchy across desktop and mobile.
|
|
*/
|
|
.detail-section--summary {
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.task-summary-tab {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-lg);
|
|
}
|
|
|
|
.task-summary-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-sm);
|
|
padding: var(--space-lg);
|
|
background: var(--card);
|
|
border: var(--btn-border-width) solid var(--border);
|
|
border-radius: var(--radius-lg);
|
|
}
|
|
|
|
.task-summary-section h4,
|
|
.task-summary-section h5 {
|
|
margin: 0;
|
|
}
|
|
|
|
.task-summary-section h5 {
|
|
color: var(--text-muted);
|
|
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.task-summary-markdown {
|
|
color: var(--text);
|
|
}
|
|
|
|
.task-summary-empty {
|
|
margin: 0;
|
|
color: var(--text-muted);
|
|
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
|
}
|
|
|
|
.task-summary-stats {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(calc(var(--space-2xl) * 3), 1fr));
|
|
gap: var(--space-sm);
|
|
margin: 0;
|
|
}
|
|
|
|
.task-summary-stats > div {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-xs);
|
|
min-width: 0;
|
|
padding: var(--space-sm);
|
|
background: var(--surface);
|
|
border: var(--btn-border-width) solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
}
|
|
|
|
.task-summary-stats dt {
|
|
color: var(--text-muted);
|
|
font-size: calc(var(--space-sm) + var(--space-xs) * 0.5);
|
|
text-transform: uppercase;
|
|
letter-spacing: calc(var(--btn-border-width) * 0.5);
|
|
}
|
|
|
|
.task-summary-stats dd {
|
|
margin: 0;
|
|
color: var(--text);
|
|
font-family: var(--font-mono);
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.task-summary-diff-add {
|
|
color: var(--color-success);
|
|
}
|
|
|
|
.task-summary-diff-del {
|
|
color: var(--color-error);
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetailSummaryTokenCost 2026-06-27-00:00:
|
|
The done-task Summary token-cost section must reuse task-summary card hierarchy while showing per-model counts and cost without hardcoded colors or spacing. Mobile converts table rows to stacked cards so the modal and right dock do not trap horizontal scrolling.
|
|
|
|
FNXC:TaskDetailSummaryTokenCost 2026-06-28-00:00:
|
|
The desktop table needs a token-scale min-width and non-anywhere model-name wrapping so narrow right-dock containers scroll horizontally instead of collapsing MODEL values to one character per line.
|
|
*/
|
|
.task-summary-token-table-wrap {
|
|
width: 100%;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.task-summary-token-table {
|
|
width: 100%;
|
|
min-width: calc(var(--space-2xl) * 16);
|
|
border-collapse: collapse;
|
|
color: var(--text);
|
|
}
|
|
|
|
.task-summary-token-table th,
|
|
.task-summary-token-table td {
|
|
padding: var(--space-sm);
|
|
border-bottom: var(--btn-border-width) solid var(--border);
|
|
text-align: left;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.task-summary-token-table th {
|
|
color: var(--text-muted);
|
|
font-size: calc(var(--space-sm) + var(--space-xs) * 0.5);
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: calc(var(--btn-border-width) * 0.5);
|
|
}
|
|
|
|
.task-summary-token-table tbody td:not(:first-child),
|
|
.task-summary-token-table tfoot td {
|
|
font-family: var(--font-mono);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.task-summary-token-table tfoot th,
|
|
.task-summary-token-table tfoot td {
|
|
border-bottom: 0;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.task-summary-model-label {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
min-width: 0;
|
|
}
|
|
|
|
.task-summary-model-label span:last-child {
|
|
overflow-wrap: normal;
|
|
word-break: normal;
|
|
}
|
|
|
|
.task-summary-cost-unavailable {
|
|
color: var(--color-warning);
|
|
}
|
|
|
|
.task-summary-file-list,
|
|
.task-summary-work-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-xs);
|
|
margin: 0;
|
|
padding: 0;
|
|
list-style: none;
|
|
}
|
|
|
|
.task-summary-file-list li,
|
|
.task-summary-work-list li {
|
|
min-width: 0;
|
|
padding: var(--space-sm);
|
|
background: var(--surface);
|
|
border: var(--btn-border-width) solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
color: var(--text);
|
|
}
|
|
|
|
.task-summary-file-list li {
|
|
font-family: var(--font-mono);
|
|
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.task-summary-subsection {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.task-summary-work-list li {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.task-summary-status {
|
|
flex-shrink: 0;
|
|
padding: var(--space-xs) var(--space-sm);
|
|
border-radius: var(--radius-full);
|
|
background: var(--surface-muted);
|
|
color: var(--text-muted);
|
|
font-size: calc(var(--space-sm) + var(--space-xs) * 0.5);
|
|
font-weight: 600;
|
|
text-transform: capitalize;
|
|
}
|
|
|
|
.task-summary-status--done,
|
|
.task-summary-status--passed {
|
|
background: color-mix(in srgb, var(--color-success) 16%, transparent);
|
|
color: var(--color-success);
|
|
}
|
|
|
|
.task-summary-status--skipped,
|
|
.task-summary-status--advisory_failure,
|
|
.task-summary-status--pending {
|
|
background: color-mix(in srgb, var(--color-warning) 16%, transparent);
|
|
color: var(--color-warning);
|
|
}
|
|
|
|
.task-summary-status--failed {
|
|
background: color-mix(in srgb, var(--color-error) 16%, transparent);
|
|
color: var(--color-error);
|
|
}
|
|
|
|
.task-summary-retries {
|
|
margin: 0;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.detail-section--summary {
|
|
padding-inline: var(--space-sm);
|
|
}
|
|
|
|
.task-summary-tab {
|
|
gap: var(--space-md);
|
|
}
|
|
|
|
.task-summary-section {
|
|
padding: var(--space-md);
|
|
}
|
|
|
|
.task-summary-stats {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.task-summary-token-table-wrap {
|
|
overflow-x: visible;
|
|
}
|
|
|
|
.task-summary-token-table,
|
|
.task-summary-token-table thead,
|
|
.task-summary-token-table tbody,
|
|
.task-summary-token-table tfoot,
|
|
.task-summary-token-table tr,
|
|
.task-summary-token-table th,
|
|
.task-summary-token-table td {
|
|
display: block;
|
|
min-width: 0;
|
|
}
|
|
|
|
.task-summary-token-table thead {
|
|
display: none;
|
|
}
|
|
|
|
.task-summary-token-table tbody tr,
|
|
.task-summary-token-table tfoot tr {
|
|
padding: var(--space-sm);
|
|
background: var(--surface);
|
|
border: var(--btn-border-width) solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
}
|
|
|
|
.task-summary-token-table tbody,
|
|
.task-summary-token-table tfoot {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.task-summary-token-table td,
|
|
.task-summary-token-table tfoot th {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: var(--space-sm);
|
|
padding: var(--space-xs) 0;
|
|
border-bottom: 0;
|
|
text-align: right;
|
|
}
|
|
|
|
.task-summary-token-table td::before {
|
|
content: attr(data-label);
|
|
color: var(--text-muted);
|
|
font-family: var(--font-sans);
|
|
font-weight: 600;
|
|
text-align: left;
|
|
}
|
|
|
|
.task-summary-token-table tfoot td::before {
|
|
content: none;
|
|
}
|
|
|
|
.task-summary-token-table tfoot th {
|
|
color: var(--text);
|
|
text-align: left;
|
|
text-transform: none;
|
|
letter-spacing: normal;
|
|
}
|
|
|
|
.task-summary-token-table tfoot th::after {
|
|
content: ":";
|
|
}
|
|
|
|
.task-summary-work-list li {
|
|
align-items: flex-start;
|
|
}
|
|
}
|
|
|
|
/* Spec tab layout - allows SpecEditor to fill available vertical space */
|
|
.detail-section--spec {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
min-height: 0;
|
|
margin-top: 0;
|
|
}
|
|
|
|
/*
|
|
FNXC:TaskDetailPlan 2026-06-30-00:00:
|
|
The Plan prompt editor is a task-detail body surface, not a narrow prose inset. Scope full-width guards to the Plan prompt section so modal and embedded cards align markdown, empty fallback, inline edit, and AI revision controls without changing unrelated detail sections.
|
|
*/
|
|
.detail-section--plan-prompt {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
min-width: 0;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.detail-section--plan-prompt .markdown-body,
|
|
.detail-section--plan-prompt .detail-prompt,
|
|
.detail-section--plan-prompt .spec-loading,
|
|
.detail-section--plan-prompt .spec-editor-edit-mode,
|
|
.detail-section--plan-prompt .spec-editor-revision,
|
|
.detail-section--plan-prompt .spec-editor-textarea,
|
|
.detail-section--plan-prompt .spec-editor-feedback {
|
|
box-sizing: border-box;
|
|
width: 100%;
|
|
min-width: 0;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.detail-section--plan-prompt .markdown-body,
|
|
.detail-section--plan-prompt .detail-prompt {
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.task-detail-content--embedded .detail-section--plan-prompt {
|
|
width: 100%;
|
|
min-width: 0;
|
|
max-width: 100%;
|
|
}
|
|
|
|
/* Back button for changed-files modal - hidden on desktop */
|
|
.changed-files-back-button {
|
|
display: none;
|
|
}
|
|
|
|
/* Changed-files loading spinner */
|
|
.changed-files-loading-spinner {
|
|
display: inline-block;
|
|
width: 16px;
|
|
height: 16px;
|
|
border: 2px solid var(--border);
|
|
border-top-color: var(--text-muted);
|
|
border-radius: 50%;
|
|
animation: changed-files-spin 0.6s linear infinite;
|
|
}
|
|
|
|
@keyframes changed-files-spin {
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
|
|
/* Changed-files empty state */
|
|
.changed-files-empty {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: var(--space-sm);
|
|
padding: var(--space-xl) var(--space-lg);
|
|
color: var(--text-muted);
|
|
font-size: 14px;
|
|
text-align: center;
|
|
}
|
|
|
|
.changed-files-empty-icon {
|
|
font-size: 24px;
|
|
opacity: 0.6;
|
|
}
|
|
|
|
/* Changed-files error state */
|
|
.changed-files-error {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.changed-files-error-icon {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* Renamed file label */
|
|
.changed-files-renamed {
|
|
color: var(--text-muted);
|
|
font-size: 12px;
|
|
}
|
|
|
|
/* Mobile responsive for changed-files modal */
|
|
@media (max-width: 768px) {
|
|
.changed-files-modal .changed-files-layout {
|
|
grid-template-columns: 1fr;
|
|
grid-template-rows: 1fr;
|
|
}
|
|
|
|
/* Mobile two-state view: show only list or diff at a time */
|
|
.changed-files-sidebar.mobile {
|
|
display: none;
|
|
}
|
|
|
|
.changed-files-sidebar.mobile.active {
|
|
display: flex;
|
|
flex: 1;
|
|
flex-direction: column;
|
|
border-right: none;
|
|
border-bottom: none;
|
|
max-height: none;
|
|
overflow-y: auto;
|
|
padding: 0;
|
|
background: var(--surface);
|
|
}
|
|
|
|
.changed-files-sidebar.mobile.active .file-browser-list {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
.changed-files-sidebar.mobile.active .gm-diff-loading,
|
|
.changed-files-sidebar.mobile.active .changed-files-loading {
|
|
margin: var(--space-lg);
|
|
}
|
|
|
|
.changed-files-sidebar.mobile.active .gm-diff-error,
|
|
.changed-files-sidebar.mobile.active .changed-files-error {
|
|
margin: var(--space-lg);
|
|
}
|
|
|
|
.changed-files-sidebar.mobile.active .file-browser-empty,
|
|
.changed-files-sidebar.mobile.active .changed-files-empty {
|
|
flex: 1;
|
|
}
|
|
|
|
/* Larger touch targets for file entries on mobile */
|
|
.changed-files-sidebar.mobile .changed-files-entry {
|
|
padding: calc(var(--space-sm) + var(--space-xs) / 2) var(--space-md);
|
|
min-height: 36px;
|
|
}
|
|
|
|
/* Clearer active state on mobile */
|
|
.changed-files-sidebar.mobile .changed-files-entry.active {
|
|
background: var(--card-hover);
|
|
border-left: calc(var(--btn-border-width) * 3) solid var(--in-progress);
|
|
}
|
|
|
|
.changed-files-content.mobile {
|
|
display: none;
|
|
}
|
|
|
|
.changed-files-content.mobile.active {
|
|
display: flex;
|
|
flex: 1;
|
|
flex-direction: column;
|
|
padding: var(--space-sm);
|
|
overflow-y: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
background: var(--bg);
|
|
}
|
|
|
|
.changed-files-modal .file-browser-file-info {
|
|
flex-wrap: wrap;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.changed-files-modal .file-browser-file-info strong {
|
|
font-size: 12px;
|
|
word-break: break-all;
|
|
}
|
|
|
|
/* Diff viewer fills available space on mobile */
|
|
.changed-files-content.mobile.active .changed-files-diff-section {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
}
|
|
|
|
.changed-files-content.mobile.active .gm-diff-viewer {
|
|
flex: 1;
|
|
min-height: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.changed-files-content.mobile.active .gm-diff-patch {
|
|
flex: 1;
|
|
max-height: none;
|
|
overflow: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
/* Back button styles for mobile */
|
|
.changed-files-back-button {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
min-height: calc(var(--space-2xl) + var(--space-xs));
|
|
padding: 0 var(--space-md);
|
|
background: transparent;
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
color: var(--text);
|
|
font-size: 13px;
|
|
cursor: pointer;
|
|
transition: background var(--transition-fast);
|
|
margin-right: var(--space-sm);
|
|
}
|
|
|
|
.changed-files-back-button:hover {
|
|
background: var(--card-hover);
|
|
}
|
|
|
|
.changed-files-back-button:focus-visible {
|
|
outline: none;
|
|
box-shadow: var(--focus-ring-strong);
|
|
}
|
|
|
|
.detail-section--spec {
|
|
flex: 1;
|
|
min-height: 0;
|
|
}
|
|
|
|
.detail-section--plan-prompt .detail-spec-edit-trigger,
|
|
.detail-section--plan-prompt .spec-editor-actions-row,
|
|
.detail-section--plan-prompt .spec-editor-revision-actions {
|
|
align-items: stretch;
|
|
}
|
|
|
|
.detail-section--plan-prompt .spec-editor-actions-row,
|
|
.detail-section--plan-prompt .spec-editor-revision-actions {
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.detail-section--plan-prompt .spec-editor-actions-row .btn,
|
|
.detail-section--plan-prompt .spec-editor-revision-actions .btn {
|
|
flex: 1 1 auto;
|
|
}
|
|
|
|
.detail-section--plan-prompt .spec-editor-char-count {
|
|
flex: 1 1 auto;
|
|
}
|
|
}
|
|
|
|
.detail-section h4 {
|
|
font-size: 12px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
color: var(--text-muted);
|
|
margin-bottom: var(--space-sm);
|
|
}
|
|
|
|
.detail-prompt {
|
|
padding: calc(var(--space-md) + var(--space-xs) / 2);
|
|
font-size: 13px;
|
|
line-height: 1.6;
|
|
font-family: var(--font-mono);
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.spec-loading {
|
|
padding: calc(var(--space-md) + var(--space-xs) / 2);
|
|
font-size: 13px;
|
|
color: var(--text-muted);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.spec-loading::before {
|
|
content: "";
|
|
display: inline-block;
|
|
width: 14px;
|
|
height: 14px;
|
|
border: 2px solid var(--border);
|
|
border-top-color: var(--text-muted);
|
|
border-radius: 50%;
|
|
animation: task-detail-spec-spinner-spin 0.8s linear infinite;
|
|
}
|
|
|
|
@keyframes task-detail-spec-spinner-spin {
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
|
|
/* === Modal Edit Mode Styles === */
|
|
|
|
.modal-header-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.task-detail-mobile-back {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
min-height: calc(var(--space-2xl) + var(--space-xs));
|
|
padding: 0 var(--space-sm);
|
|
font-size: calc(var(--space-sm) + var(--space-xs) * 0.625);
|
|
line-height: 1;
|
|
}
|
|
|
|
.task-detail-mobile-back svg {
|
|
width: 1em;
|
|
height: 1em;
|
|
}
|
|
|
|
.modal-edit-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 28px;
|
|
height: 28px;
|
|
padding: 0;
|
|
background: transparent;
|
|
border: none;
|
|
border-radius: var(--radius-sm);
|
|
color: var(--text-muted);
|
|
cursor: pointer;
|
|
transition:
|
|
background var(--transition-fast),
|
|
color var(--transition-fast);
|
|
}
|
|
|
|
.modal-edit-btn:hover {
|
|
background: var(--border);
|
|
color: var(--text);
|
|
}
|
|
|
|
.modal-edit-btn:focus-visible {
|
|
outline: none;
|
|
box-shadow: var(--focus-ring-strong);
|
|
}
|
|
|
|
.modal-edit-form {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-md);
|
|
}
|
|
|
|
.modal-edit-form .form-group textarea {
|
|
min-height: 160px;
|
|
}
|
|
|
|
.modal-edit-input {
|
|
width: 100%;
|
|
padding: var(--space-sm) var(--space-md);
|
|
background: var(--bg);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
color: var(--text);
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
font-family: inherit;
|
|
outline: none;
|
|
transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
|
|
}
|
|
|
|
.modal-edit-input:focus {
|
|
border-color: var(--todo);
|
|
box-shadow: var(--focus-ring);
|
|
}
|
|
|
|
.modal-edit-input::placeholder {
|
|
color: var(--text-dim);
|
|
font-weight: 400;
|
|
}
|
|
|
|
.modal-edit-input:disabled {
|
|
opacity: 0.6;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.modal-edit-textarea {
|
|
width: 100%;
|
|
padding: var(--space-sm) var(--space-md);
|
|
background: var(--bg);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
color: var(--text);
|
|
font-size: 14px;
|
|
font-family: inherit;
|
|
outline: none;
|
|
resize: vertical;
|
|
min-height: 80px;
|
|
line-height: 1.5;
|
|
transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
|
|
}
|
|
|
|
.modal-edit-textarea:focus {
|
|
border-color: var(--todo);
|
|
box-shadow: var(--focus-ring);
|
|
}
|
|
|
|
.modal-edit-textarea::placeholder {
|
|
color: var(--text-dim);
|
|
}
|
|
|
|
.modal-edit-textarea:disabled {
|
|
opacity: 0.6;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
/* Edit-mode hint text now lives in modal-actions footer */
|
|
.modal-edit-hint {
|
|
font-size: 12px;
|
|
color: var(--text-dim);
|
|
}
|
|
|
|
.modal-edit-hint kbd {
|
|
background: var(--card);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-sm);
|
|
padding: 2px 6px;
|
|
font-family: var(--font-mono);
|
|
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
/* Card saving state */
|
|
.card.card-saving {
|
|
opacity: 0.7;
|
|
}
|
|
|
|
/* === Detail Tabs === */
|
|
/*
|
|
FNXC:TaskDetailTabs 2026-06-21-00:00:
|
|
The mobile global `* { touch-action: pan-y; }` lock from FN-6365 prevents horizontal swipe gestures unless each known horizontal scroller opts back into pan-x.
|
|
The overflowing task-detail tab strip must keep horizontal touch panning enabled so conditional and plugin tabs remain reachable on narrow touch viewports (FN-6864), matching the FN-6450 agent-detail tab precedent.
|
|
|
|
FNXC:TaskDetailTabs 2026-06-22-18:00:
|
|
Remove the divider between the tab selector and the detail area below. Keep the active-tab underline as the only local selection affordance.
|
|
|
|
FNXC:TaskDetailTabs 2026-06-25-16:55:
|
|
Task-detail tabs must remain reachable as a one-row horizontal scroller on mobile across the Board modal and List embedded pane. The tab strip is the scroller, opts out of the global mobile pan-y lock with pan-x pan-y, and keeps tab children non-shrinking so conditional and plugin tabs overflow-scroll instead of clipping or compressing.
|
|
|
|
FNXC:TaskDetailTabs 2026-06-26-00:35:
|
|
`touch-action` is not inherited, so the tab buttons must also opt into pan-x because they are the real touch targets. A container-only opt-in leaves touches that start on a `.detail-tab` under the global mobile `* { touch-action: pan-y; }` lock and blocks horizontal swipes.
|
|
*/
|
|
.detail-tabs {
|
|
display: flex;
|
|
gap: 0;
|
|
width: 100%;
|
|
max-inline-size: 100%;
|
|
min-width: 0;
|
|
overflow-x: auto;
|
|
overflow-y: hidden;
|
|
overscroll-behavior-inline: contain;
|
|
touch-action: pan-x pan-y;
|
|
-webkit-overflow-scrolling: touch;
|
|
scrollbar-width: thin;
|
|
margin-bottom: var(--space-md);
|
|
}
|
|
|
|
.detail-tab {
|
|
flex-shrink: 0;
|
|
touch-action: pan-x pan-y;
|
|
padding: var(--space-sm) var(--space-lg);
|
|
background: none;
|
|
border: none;
|
|
border-bottom: 2px solid transparent;
|
|
color: var(--text-muted);
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
font-weight: 400;
|
|
font-family: inherit;
|
|
transition:
|
|
color var(--transition-fast),
|
|
border-color var(--transition-fast);
|
|
}
|
|
|
|
.detail-tab:hover {
|
|
color: var(--text);
|
|
}
|
|
.detail-tab:focus-visible {
|
|
box-shadow: var(--focus-ring-strong);
|
|
outline: none;
|
|
border-radius: var(--radius-sm) var(--radius-sm) 0 0;
|
|
}
|
|
|
|
.detail-tab-active {
|
|
border-bottom-color: var(--in-progress);
|
|
color: var(--text);
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* === Activity View Selector === */
|
|
/*
|
|
FNXC:TaskDetailActivity 2026-06-30-23:59:
|
|
The Activity tab itself is the Live/Feed/Raw dropdown trigger. Keep it in the `.detail-tabs` scroller with the same tab sizing and active underline, and keep the Activity panel toolbar only for the expand affordance so no duplicate in-content selector or empty mobile shell remains.
|
|
|
|
FNXC:TaskDetailActivity 2026-07-01-00:00:
|
|
The Activity view menu is portaled to the document body and fixed-positioned because `.detail-tabs` uses overflow scrolling on mobile. Keep overflow containment on the tab strip and move only the menu overlay out of that clipping chain.
|
|
*/
|
|
.detail-tab-dropdown {
|
|
position: relative;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.detail-tab--activity {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.detail-tab-chevron {
|
|
inline-size: var(--icon-size-sm);
|
|
block-size: var(--icon-size-sm);
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.activity-view-menu {
|
|
position: fixed;
|
|
z-index: 1000;
|
|
padding: var(--space-xs);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: calc(var(--space-xs) / 2);
|
|
background: var(--card);
|
|
border: var(--btn-border-width) solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
box-shadow: var(--shadow-lg);
|
|
overflow-y: auto;
|
|
overscroll-behavior: contain;
|
|
}
|
|
|
|
.activity-view-menu-item {
|
|
appearance: none;
|
|
border: 0;
|
|
border-radius: var(--radius-sm);
|
|
background: transparent;
|
|
color: var(--text);
|
|
cursor: pointer;
|
|
font: inherit;
|
|
text-align: start;
|
|
padding: var(--space-xs) var(--space-sm);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.activity-view-menu-item:hover,
|
|
.activity-view-menu-item:focus-visible,
|
|
.activity-view-menu-item[aria-current="true"] {
|
|
background: var(--surface-hover);
|
|
outline: none;
|
|
}
|
|
|
|
.activity-view-menu-item[aria-current="true"] {
|
|
color: var(--text);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.activity-toolbar {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: flex-end;
|
|
gap: var(--space-sm);
|
|
margin-bottom: var(--space-md);
|
|
}
|
|
|
|
.activity-expand-toggle {
|
|
flex: 0 0 auto;
|
|
min-inline-size: var(--space-2xl);
|
|
min-block-size: var(--space-2xl);
|
|
padding: 0;
|
|
}
|
|
|
|
.detail-log-loading {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
color: var(--text-muted);
|
|
min-height: calc(var(--space-2xl) + var(--space-md));
|
|
}
|
|
|
|
.detail-log-loading svg {
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.activity-toolbar {
|
|
align-items: stretch;
|
|
}
|
|
|
|
.activity-view-menu {
|
|
max-inline-size: calc(100vw - (var(--space-md) * 2));
|
|
}
|
|
|
|
.activity-expand-toggle {
|
|
min-inline-size: calc(var(--space-2xl) + var(--space-sm));
|
|
min-block-size: calc(var(--space-2xl) + var(--space-sm));
|
|
}
|
|
|
|
.detail-log-loading {
|
|
min-height: calc(var(--space-2xl) + var(--space-lg));
|
|
}
|
|
|
|
|
|
.detail-tab {
|
|
min-height: 36px;
|
|
touch-action: pan-x pan-y;
|
|
}
|
|
|
|
.detail-source-grid,
|
|
.detail-source-edit-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.detail-github-tracking-repo-row {
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.detail-priority-select {
|
|
min-height: var(--detail-priority-control-min-height);
|
|
}
|
|
|
|
.detail-source-header {
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.detail-source-summary {
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.detail-source-section .detail-source-summary {
|
|
flex: 1 1 auto;
|
|
min-width: 0;
|
|
}
|
|
|
|
.detail-github-tracking-section .detail-source-header {
|
|
flex-wrap: nowrap;
|
|
min-width: 0;
|
|
}
|
|
|
|
.detail-github-tracking-section .detail-source-summary {
|
|
flex: 1 1 auto;
|
|
flex-wrap: nowrap;
|
|
min-width: 0;
|
|
}
|
|
|
|
.detail-github-tracking-section .detail-github-tracking-enable {
|
|
margin-left: auto;
|
|
min-width: calc(var(--space-lg) + var(--space-xl) - var(--space-xs));
|
|
min-height: calc(var(--space-lg) + var(--space-xl) - var(--space-xs));
|
|
padding-block: var(--space-xs);
|
|
justify-content: center;
|
|
}
|
|
|
|
.detail-github-tracking-section .detail-github-tracking-spinner {
|
|
margin-left: auto;
|
|
}
|
|
|
|
.detail-github-tracking-section .detail-source-header .detail-source-toggle {
|
|
margin-left: 0;
|
|
}
|
|
|
|
.detail-body {
|
|
padding: calc(var(--space-md) + var(--space-xs) / 2);
|
|
overflow-x: hidden;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.detail-title {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.modal-actions {
|
|
flex-wrap: wrap;
|
|
gap: var(--space-sm);
|
|
padding: var(--space-md) calc(var(--space-md) + var(--space-xs) / 2) calc(var(--space-md) + env(safe-area-inset-bottom, 0px));
|
|
}
|
|
|
|
.modal-actions .btn {
|
|
min-width: 0;
|
|
}
|
|
|
|
/* Mobile dropdown menus — position above action bar, constrained to viewport */
|
|
.detail-actions-menu,
|
|
.detail-move-menu {
|
|
bottom: calc(100% + var(--space-xs));
|
|
max-width: calc(100vw - calc(var(--space-lg) + var(--space-md)));
|
|
max-height: calc(100dvh - 120px);
|
|
overflow-y: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
.modal-header {
|
|
padding: var(--space-md) calc(var(--space-md) + var(--space-xs) / 2);
|
|
}
|
|
|
|
.detail-tabs {
|
|
display: flex;
|
|
width: 100%;
|
|
max-inline-size: 100%;
|
|
min-width: 0;
|
|
overflow-x: auto;
|
|
overflow-y: hidden;
|
|
overscroll-behavior-inline: contain;
|
|
touch-action: pan-x pan-y;
|
|
-webkit-overflow-scrolling: touch;
|
|
scrollbar-width: none;
|
|
}
|
|
|
|
.detail-tabs::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.detail-tab {
|
|
touch-action: pan-x pan-y;
|
|
padding: var(--space-sm) var(--space-md);
|
|
font-size: 13px;
|
|
}
|
|
|
|
/* Task detail modal: prevent header clipping + full-screen refine flow */
|
|
.detail-title-row {
|
|
flex-wrap: wrap;
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.modal-header-actions {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.detail-refine-overlay {
|
|
align-items: stretch;
|
|
justify-content: stretch;
|
|
}
|
|
|
|
.detail-refine-modal {
|
|
width: 100%;
|
|
max-width: 100%;
|
|
max-height: 100dvh;
|
|
border-radius: 0;
|
|
border: none;
|
|
}
|
|
|
|
.detail-refine-textarea {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.modal-edit-form .form-group {
|
|
padding: 0;
|
|
}
|
|
|
|
/* Task edit modal: cap description textarea height on mobile so form stays visible */
|
|
.modal-edit-form .form-group textarea {
|
|
max-height: 200px;
|
|
overflow-y: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
/* Modal edit button: touch target on mobile */
|
|
.modal-edit-btn {
|
|
min-width: 36px;
|
|
min-height: 36px;
|
|
}
|
|
|
|
.task-detail-mobile-back {
|
|
min-height: calc(var(--space-2xl) + var(--space-xs));
|
|
min-width: calc(var(--space-2xl) + var(--space-xs));
|
|
}
|
|
|
|
}
|
|
|
|
|
|
.detail-in-review-stall {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-sm);
|
|
padding: var(--space-lg);
|
|
border-radius: var(--radius-md);
|
|
background: color-mix(in srgb, var(--color-warning) 8%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--color-warning) 30%, transparent);
|
|
}
|
|
|
|
.detail-in-review-stall-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.detail-in-review-stall-headline {
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
}
|
|
|
|
.detail-in-review-stall-reason {
|
|
font-family: var(--font-mono);
|
|
color: var(--text-muted);
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.detail-in-review-stall-description,
|
|
.detail-in-review-stall-action {
|
|
color: var(--text);
|
|
}
|
|
|
|
.detail-in-review-stall-meta {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-md);
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.detail-log-entry--stall-highlight {
|
|
outline: 2px solid color-mix(in srgb, var(--color-warning) 60%, transparent);
|
|
border-radius: var(--radius-sm);
|
|
background: color-mix(in srgb, var(--color-warning) 12%, transparent);
|
|
transition: outline-color var(--transition-slow);
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.detail-in-review-stall-meta {
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
}
|
|
}
|
|
|
|
.detail-near-duplicate-banner {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-sm);
|
|
padding: var(--space-lg);
|
|
border-radius: var(--radius-md);
|
|
background: color-mix(in srgb, var(--color-warning) 8%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--color-warning) 30%, transparent);
|
|
margin-bottom: var(--space-md);
|
|
}
|
|
|
|
.detail-near-duplicate-banner__header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.detail-near-duplicate-banner__headline {
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
}
|
|
|
|
.detail-near-duplicate-banner__copy {
|
|
margin: 0;
|
|
color: var(--text);
|
|
}
|
|
|
|
.detail-near-duplicate-banner__actions {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.detail-near-duplicate-banner__actions {
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
}
|
|
}
|
|
|
|
.detail-retries-grid dd {
|
|
font-weight: 600;
|
|
}
|
|
|
|
.detail-retries-warning {
|
|
margin: var(--space-sm) 0 0;
|
|
color: var(--color-error);
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
/*
|
|
FNXC:Workspace 2026-06-21-00:00:
|
|
Flat read-only per-sub-repo worktree list for a workspace task (U3/KTD5 dashboard floor).
|
|
Read-only list/placeholder only — not the deferred rich per-repo-status component.
|
|
*/
|
|
.workspace-worktrees-summary {
|
|
margin: var(--space-sm) 0 0;
|
|
}
|
|
.workspace-worktrees-placeholder {
|
|
font-size: 0.75rem;
|
|
font-weight: 600;
|
|
color: var(--text-muted, inherit);
|
|
margin-bottom: var(--space-xs);
|
|
}
|
|
.workspace-worktrees-list {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-xs);
|
|
}
|
|
.workspace-worktrees-item {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-xs) var(--space-sm);
|
|
font-size: 0.75rem;
|
|
font-family: var(--font-mono, monospace);
|
|
}
|
|
.workspace-worktrees-repo {
|
|
font-weight: 600;
|
|
}
|
|
.workspace-worktrees-branch {
|
|
color: var(--text-muted, inherit);
|
|
}
|