Restore Fusion dashboard loading indicators by preventing spinner keyframe collisions. - Move shared spinner utilities onto the collision-proof fusion-spinner-spin keyframe. - Rename component-local spin keyframes and scoped spinner utility overrides so lazy CSS chunks cannot override global loaders. - Extend spinner CSS contract coverage across shared utilities, CSS-only loaders, and renamed loading affordances. - Add a patch changeset for the published CLI package. Files changed: .changeset/fn-6961-spinner-animation.md | 7 + .../app/__tests__/spinner-animation.css.test.ts | 149 +++++++++++++++++---- .../dashboard/app/components/AgentMentionPopup.css | 6 - .../app/components/CustomProvidersSection.css | 2 +- .../app/components/CustomProvidersSection.tsx | 6 +- .../dashboard/app/components/FileMentionPopup.css | 8 +- .../dashboard/app/components/GitHubImportModal.css | 2 +- packages/dashboard/app/components/Header.css | 4 +- .../dashboard/app/components/IssueMentionPopup.css | 8 +- packages/dashboard/app/components/NodesView.css | 8 +- packages/dashboard/app/components/ScriptsModal.css | 8 +- packages/dashboard/app/components/TaskCard.css | 15 ++- .../dashboard/app/components/TaskDetailModal.css | 4 +- .../dashboard/app/components/TerminalModal.css | 6 - packages/dashboard/app/components/TodoView.css | 4 +- .../app/components/WorkflowResultsTab.css | 4 +- packages/dashboard/app/styles.css | 13 +- 17 files changed, 178 insertions(+), 76 deletions(-) Fusion-Task-Id: FN-6961 Fusion-Task-Lineage: 464e0a50-52c3-4b89-ac72-2f0227d97ce2
4892 lines
105 KiB
CSS
4892 lines
105 KiB
CSS
/*
|
||
FNXC:DashboardStyling 2026-06-19-00:00:
|
||
Non-Command-Center dashboard CSS must use the canonical --text token. The legacy primary-text alias was undefined, so it made primary text inherit fallback/parent colors or hardcoded hex colors that ignored the active theme (FN-6688).
|
||
*/
|
||
|
||
/* === Scripts Modal === */
|
||
.scripts-modal {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.scripts-modal-body {
|
||
padding: var(--space-lg);
|
||
max-height: 70vh;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.scripts-modal-body {
|
||
max-height: none;
|
||
flex: 1;
|
||
min-height: 0;
|
||
}
|
||
|
||
.scripts-modal-list-header {
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.scripts-modal-list-header .btn {
|
||
width: 100%;
|
||
justify-content: center;
|
||
}
|
||
|
||
.scripts-modal-form-actions {
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.scripts-modal-form-actions .btn {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.script-card-header {
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.script-card-actions {
|
||
flex-wrap: wrap;
|
||
width: 100%;
|
||
margin-left: 0;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.script-delete-confirm {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
}
|
||
}
|
||
|
||
/* ── Scheduled Tasks ──────────────────────────────────────────────── */
|
||
|
||
/*
|
||
FNXC:Automations 2026-06-22-16:05:
|
||
The Automations toolbar should match Artifacts' controls row: a plain body row with standalone controls on the dashboard background, not a tinted sub-header strip with its own divider.
|
||
*/
|
||
.scheduling-toolbar {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: var(--space-md);
|
||
flex-wrap: wrap;
|
||
padding: var(--space-lg) var(--modal-padding, var(--space-lg));
|
||
border-bottom: none;
|
||
background: transparent;
|
||
}
|
||
|
||
.scheduling-toolbar-left {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-md);
|
||
flex-wrap: wrap;
|
||
min-width: 0;
|
||
}
|
||
|
||
.scheduling-toolbar-right {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
margin-left: auto;
|
||
}
|
||
|
||
.scheduling-count {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: 0.75rem;
|
||
color: var(--text-muted);
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* === Automation (ScheduledTasksModal) === */
|
||
.modal.automation-modal {
|
||
width: min(95vw, 720px);
|
||
max-width: 95vw;
|
||
min-width: 0;
|
||
height: 80vh;
|
||
min-height: calc(var(--space-2xl) * 15);
|
||
max-height: calc(100dvh - var(--overlay-padding-top, 10vh) - var(--space-lg));
|
||
overflow: hidden;
|
||
resize: both;
|
||
}
|
||
|
||
.schedule-modal-content {
|
||
padding: var(--space-lg) var(--space-xl);
|
||
overflow-y: auto;
|
||
flex: 1;
|
||
min-height: 0;
|
||
}
|
||
|
||
/*
|
||
FNXC:Automations 2026-06-22-12:45:
|
||
The Automations sub-header scope button bar should match the Artifacts tab bar style: each scope is a standalone bordered surface button with the same todo-accent active state, not a segmented control inside a filled capsule.
|
||
*/
|
||
.scheduling-scope-selector {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
background: transparent;
|
||
border: none;
|
||
border-radius: 0;
|
||
padding: 0;
|
||
}
|
||
|
||
.scope-btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-xs) var(--space-md);
|
||
font-size: 0.75rem;
|
||
font-weight: 500;
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
background: var(--surface);
|
||
color: var(--text-muted);
|
||
cursor: pointer;
|
||
transition: background-color var(--transition-fast), color var(--transition-fast);
|
||
}
|
||
|
||
.scope-btn:hover {
|
||
background: var(--card-hover);
|
||
color: var(--text);
|
||
}
|
||
|
||
.scope-btn.active {
|
||
color: var(--todo);
|
||
border-color: var(--todo);
|
||
background: color-mix(in srgb, var(--todo) 12%, transparent);
|
||
}
|
||
|
||
.scope-btn:focus-visible {
|
||
outline: none;
|
||
box-shadow: var(--focus-ring-strong);
|
||
}
|
||
|
||
/* Schedule form scope toggle */
|
||
.schedule-scope-toggle {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: calc(var(--space-xs) / 2);
|
||
background: var(--surface);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
padding: calc(var(--space-xs) / 2);
|
||
width: fit-content;
|
||
}
|
||
|
||
.schedule-scope-btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
padding: var(--space-xs) var(--space-md);
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
border: none;
|
||
border-radius: var(--radius-sm);
|
||
background: transparent;
|
||
color: var(--text-muted);
|
||
cursor: pointer;
|
||
transition: background-color var(--transition-fast), color var(--transition-fast);
|
||
}
|
||
|
||
.schedule-scope-btn:hover:not(:disabled) {
|
||
background: var(--card-hover);
|
||
color: var(--text);
|
||
}
|
||
|
||
.schedule-scope-btn.active {
|
||
background: var(--todo);
|
||
color: var(--cta-text);
|
||
}
|
||
|
||
.schedule-scope-btn:disabled {
|
||
opacity: 0.5;
|
||
cursor: not-allowed;
|
||
}
|
||
|
||
.schedule-scope-btn:focus-visible {
|
||
outline: none;
|
||
box-shadow: var(--focus-ring);
|
||
}
|
||
|
||
/* Routine form scope toggle */
|
||
.routine-scope-toggle {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: calc(var(--space-xs) / 2);
|
||
background: var(--surface);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
padding: calc(var(--space-xs) / 2);
|
||
width: fit-content;
|
||
}
|
||
|
||
.routine-scope-btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
padding: var(--space-xs) var(--space-md);
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
border: none;
|
||
border-radius: var(--radius-sm);
|
||
background: transparent;
|
||
color: var(--text-muted);
|
||
cursor: pointer;
|
||
transition: background-color var(--transition-fast), color var(--transition-fast);
|
||
}
|
||
|
||
.routine-scope-btn:hover:not(:disabled) {
|
||
background: var(--card-hover);
|
||
color: var(--text);
|
||
}
|
||
|
||
.routine-scope-btn.active {
|
||
background: var(--todo);
|
||
color: var(--cta-text);
|
||
}
|
||
|
||
.routine-scope-btn:disabled {
|
||
opacity: 0.5;
|
||
cursor: not-allowed;
|
||
}
|
||
|
||
.routine-scope-btn:focus-visible {
|
||
outline: none;
|
||
box-shadow: var(--focus-ring);
|
||
}
|
||
|
||
.schedule-empty-state {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: var(--space-md);
|
||
padding: calc(var(--space-2xl) * 1.5) var(--space-xl);
|
||
color: var(--text-muted);
|
||
text-align: center;
|
||
}
|
||
|
||
.schedule-empty-state h4 {
|
||
margin: 0;
|
||
font-size: 16px;
|
||
color: var(--text);
|
||
}
|
||
|
||
.schedule-empty-state p {
|
||
margin: 0;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.schedule-empty-state .btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: calc(var(--space-sm) - var(--space-xs) / 2);
|
||
margin-top: var(--space-sm);
|
||
}
|
||
|
||
.schedule-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-md);
|
||
}
|
||
|
||
.schedule-card {
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
padding: calc(var(--space-md) + var(--space-xs) / 2) var(--space-lg);
|
||
background: var(--card);
|
||
transition: border-color var(--transition-fast);
|
||
}
|
||
|
||
.schedule-card:hover {
|
||
border-color: color-mix(in srgb, var(--border) 70%, var(--text) 30%);
|
||
}
|
||
|
||
.schedule-card.disabled {
|
||
opacity: 0.55;
|
||
}
|
||
|
||
.schedule-card-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: flex-start;
|
||
gap: var(--space-md);
|
||
}
|
||
|
||
.schedule-card-info {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.schedule-card-name-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.schedule-card-name {
|
||
font-weight: 600;
|
||
font-size: 14px;
|
||
color: var(--text);
|
||
}
|
||
|
||
.schedule-type-badge {
|
||
font-size: 11px;
|
||
font-weight: 500;
|
||
padding: 1px 7px;
|
||
border-radius: 999px;
|
||
border: 1px solid;
|
||
line-height: 1.5;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.schedule-scope-badge {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
font-size: 10px;
|
||
font-weight: 500;
|
||
padding: 1px 6px;
|
||
border-radius: 999px;
|
||
border: 1px solid;
|
||
line-height: 1.4;
|
||
white-space: nowrap;
|
||
text-transform: lowercase;
|
||
}
|
||
|
||
.schedule-scope-badge.global {
|
||
color: var(--text-muted);
|
||
border-color: var(--text-dim);
|
||
}
|
||
|
||
.schedule-scope-badge.project {
|
||
color: var(--todo);
|
||
border-color: var(--todo);
|
||
}
|
||
|
||
.schedule-card-description {
|
||
margin: 4px 0 0;
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.schedule-card-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.schedule-card-meta {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
gap: var(--space-md);
|
||
margin-top: var(--space-md);
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.schedule-meta-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
.schedule-meta-label {
|
||
font-weight: 500;
|
||
}
|
||
|
||
.schedule-cron {
|
||
font-size: 11px;
|
||
padding: 1px 5px;
|
||
background: var(--bg-secondary);
|
||
border-radius: var(--radius-sm);
|
||
}
|
||
|
||
.schedule-run-badge {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: 11px;
|
||
font-weight: 500;
|
||
padding: 1px 7px;
|
||
border-radius: 999px;
|
||
}
|
||
|
||
.schedule-run-badge.success {
|
||
color: var(--ws-success);
|
||
background: color-mix(in srgb, var(--ws-success) 10%, transparent);
|
||
}
|
||
|
||
.schedule-run-badge.failure {
|
||
color: var(--ws-error);
|
||
background: color-mix(in srgb, var(--ws-error) 10%, transparent);
|
||
}
|
||
|
||
.schedule-run-duration {
|
||
opacity: 0.7;
|
||
}
|
||
|
||
/* Run History */
|
||
.schedule-card-history {
|
||
margin-top: var(--space-md);
|
||
border-top: 1px solid var(--border);
|
||
padding-top: 8px;
|
||
}
|
||
|
||
.schedule-history-toggle {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: calc(var(--space-sm) - var(--space-xs) / 2);
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
background: none;
|
||
border: none;
|
||
cursor: pointer;
|
||
padding: 2px 0;
|
||
width: 100%;
|
||
text-align: left;
|
||
}
|
||
|
||
.schedule-history-toggle:hover {
|
||
color: var(--text);
|
||
}
|
||
|
||
.schedule-history-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
margin-top: var(--space-sm);
|
||
}
|
||
|
||
.schedule-history-item {
|
||
border-radius: var(--radius-sm);
|
||
}
|
||
|
||
.schedule-history-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
width: 100%;
|
||
padding: 4px 6px;
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
background: none;
|
||
border: none;
|
||
cursor: pointer;
|
||
border-radius: var(--radius-sm);
|
||
}
|
||
|
||
.schedule-history-header:hover {
|
||
background: var(--bg-secondary);
|
||
}
|
||
|
||
.schedule-history-status.success {
|
||
color: var(--ws-success);
|
||
}
|
||
|
||
.schedule-history-status.failure {
|
||
color: var(--ws-error);
|
||
}
|
||
|
||
.schedule-history-time {
|
||
flex: 1;
|
||
}
|
||
|
||
.schedule-history-duration {
|
||
opacity: 0.6;
|
||
}
|
||
|
||
.schedule-history-detail {
|
||
padding: 4px 6px 8px 26px;
|
||
}
|
||
|
||
.schedule-history-output {
|
||
font-size: 11px;
|
||
line-height: 1.4;
|
||
margin: 0;
|
||
padding: var(--space-sm);
|
||
background: var(--bg-secondary);
|
||
border-radius: var(--radius-sm);
|
||
overflow-x: auto;
|
||
max-height: 200px;
|
||
overflow-y: auto;
|
||
white-space: pre-wrap;
|
||
word-break: break-all;
|
||
}
|
||
|
||
.schedule-history-error {
|
||
font-size: 11px;
|
||
color: var(--ws-error);
|
||
margin-top: var(--space-xs);
|
||
}
|
||
|
||
.schedule-history-more {
|
||
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
||
color: var(--text-muted);
|
||
padding: 4px 6px;
|
||
text-align: center;
|
||
}
|
||
|
||
/* Schedule card: step count badge */
|
||
.schedule-steps-badge {
|
||
font-size: 11px;
|
||
font-weight: 500;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.schedule-meta-command-preview {
|
||
max-width: 200px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.schedule-command-preview {
|
||
font-size: 11px;
|
||
color: var(--text-muted);
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
max-width: 200px;
|
||
}
|
||
|
||
/* Step result indicators (dots in run history header) */
|
||
.step-results-indicator {
|
||
display: inline-flex;
|
||
gap: 3px;
|
||
align-items: center;
|
||
margin: 0 4px;
|
||
}
|
||
|
||
.step-result-dot {
|
||
width: 6px;
|
||
height: 6px;
|
||
border-radius: 50%;
|
||
display: inline-block;
|
||
}
|
||
|
||
.step-result-dot.success {
|
||
background: var(--ws-success);
|
||
}
|
||
|
||
.step-result-dot.failure {
|
||
background: var(--ws-error);
|
||
}
|
||
|
||
/* Per-step results in run history detail */
|
||
.schedule-step-results {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
margin-bottom: var(--space-sm);
|
||
padding: 6px;
|
||
border-radius: var(--radius-sm);
|
||
background: var(--bg-secondary);
|
||
}
|
||
|
||
.schedule-step-result {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: calc(var(--space-sm) - var(--space-xs) / 2);
|
||
font-size: 11px;
|
||
}
|
||
|
||
.schedule-step-result-status {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.schedule-step-result.success .schedule-step-result-status {
|
||
color: var(--ws-success);
|
||
}
|
||
|
||
.schedule-step-result.failure .schedule-step-result-status {
|
||
color: var(--ws-error);
|
||
}
|
||
|
||
.schedule-step-result-name {
|
||
font-weight: 500;
|
||
color: var(--text);
|
||
}
|
||
|
||
.schedule-step-result-error {
|
||
color: var(--ws-error);
|
||
font-size: 10px;
|
||
}
|
||
|
||
/* Step type badges */
|
||
.step-type-badge {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: 10px;
|
||
font-weight: 600;
|
||
padding: 2px 6px;
|
||
border-radius: var(--radius-sm);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.02em;
|
||
}
|
||
|
||
.step-type-command {
|
||
color: var(--ws-pre-merge);
|
||
background: color-mix(in srgb, var(--ws-pre-merge) 12%, transparent);
|
||
}
|
||
|
||
.step-type-ai-prompt {
|
||
color: var(--ws-teal);
|
||
background: color-mix(in srgb, var(--ws-teal) 12%, transparent);
|
||
}
|
||
|
||
/* Steps editor */
|
||
.steps-editor {
|
||
margin: 8px 0;
|
||
}
|
||
|
||
.steps-editor-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: var(--space-sm);
|
||
}
|
||
|
||
.steps-editor-title {
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.steps-empty-state {
|
||
padding: var(--space-lg);
|
||
text-align: center;
|
||
color: var(--text-muted);
|
||
font-size: 12px;
|
||
border: 1px dashed var(--border);
|
||
border-radius: var(--radius-sm);
|
||
margin-bottom: var(--space-sm);
|
||
}
|
||
|
||
.steps-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: calc(var(--space-sm) - var(--space-xs) / 2);
|
||
margin-bottom: var(--space-sm);
|
||
}
|
||
|
||
.step-card {
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-sm);
|
||
background: var(--bg);
|
||
}
|
||
|
||
.step-card-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-sm) var(--space-md);
|
||
}
|
||
|
||
.step-card-drag {
|
||
color: var(--text-muted);
|
||
cursor: grab;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.step-card-index {
|
||
font-size: 10px;
|
||
font-weight: 700;
|
||
color: var(--text-muted);
|
||
min-width: 16px;
|
||
text-align: center;
|
||
}
|
||
|
||
.step-card-name {
|
||
flex: 1;
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
color: var(--text);
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.step-card-flag {
|
||
font-size: 10px;
|
||
}
|
||
|
||
.step-card-actions {
|
||
display: flex;
|
||
gap: calc(var(--space-xs) / 2);
|
||
align-items: center;
|
||
}
|
||
|
||
/* Step editor inline form */
|
||
.step-editor {
|
||
padding: var(--space-md);
|
||
}
|
||
|
||
.step-editor .form-group {
|
||
margin-bottom: var(--space-sm);
|
||
}
|
||
|
||
.step-editor-actions {
|
||
display: flex;
|
||
gap: var(--space-sm);
|
||
justify-content: flex-end;
|
||
margin-top: var(--space-md);
|
||
}
|
||
|
||
/* Steps add buttons */
|
||
.steps-add-buttons {
|
||
display: flex;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.steps-add-buttons .btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
/* Schedule form mode toggle */
|
||
.schedule-mode-toggle {
|
||
display: flex;
|
||
gap: 0;
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-sm);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.schedule-mode-btn {
|
||
flex: 1;
|
||
padding: 6px 12px;
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
border: none;
|
||
background: var(--bg-secondary);
|
||
color: var(--text-muted);
|
||
cursor: pointer;
|
||
transition: background var(--transition-fast), color var(--transition-fast);
|
||
}
|
||
|
||
.schedule-mode-btn:hover {
|
||
background: var(--bg-tertiary, var(--bg-secondary));
|
||
}
|
||
|
||
.schedule-mode-btn.active {
|
||
background: var(--ws-pre-merge);
|
||
color: var(--cta-text);
|
||
}
|
||
|
||
.form-group-row {
|
||
display: flex;
|
||
gap: var(--space-md);
|
||
}
|
||
|
||
.form-group-row .form-group {
|
||
flex: 1;
|
||
}
|
||
|
||
/* Schedule form within modal */
|
||
.schedule-form {
|
||
padding: 0;
|
||
}
|
||
|
||
.schedule-form .modal-actions {
|
||
padding: var(--space-lg) 0 0;
|
||
border-top: 1px solid var(--border);
|
||
margin-top: var(--space-lg);
|
||
position: sticky;
|
||
bottom: 0;
|
||
z-index: 1;
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.schedule-modal-content {
|
||
max-height: none;
|
||
padding: var(--space-md) var(--space-lg);
|
||
}
|
||
|
||
.schedule-card {
|
||
margin: 0;
|
||
padding: var(--space-md);
|
||
}
|
||
|
||
.schedule-card-header {
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.schedule-card-actions {
|
||
flex-wrap: wrap;
|
||
width: 100%;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.schedule-empty-state {
|
||
padding: var(--space-xl) var(--space-lg);
|
||
}
|
||
|
||
.schedule-form {
|
||
padding-left: var(--space-lg);
|
||
padding-right: var(--space-lg);
|
||
}
|
||
|
||
.scheduling-toolbar {
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.scheduling-toolbar-left {
|
||
flex: 1 1 100%;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.scheduling-toolbar-right {
|
||
flex: 1 1 100%;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.scheduling-scope-selector {
|
||
width: 100%;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.scope-btn {
|
||
flex: 1;
|
||
justify-content: center;
|
||
}
|
||
}
|
||
|
||
/* ── Routines ──────────────────────────────────────────────────── */
|
||
|
||
.routine-empty-state {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: var(--space-md);
|
||
padding: calc(var(--space-2xl) * 1.5) var(--space-xl);
|
||
color: var(--text-muted);
|
||
text-align: center;
|
||
}
|
||
|
||
.routine-empty-state h4 {
|
||
margin: 0;
|
||
font-size: 16px;
|
||
color: var(--text);
|
||
}
|
||
|
||
.routine-empty-state p {
|
||
margin: 0;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.routine-empty-state .btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: calc(var(--space-sm) - var(--space-xs) / 2);
|
||
margin-top: var(--space-sm);
|
||
}
|
||
|
||
.routine-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-md);
|
||
}
|
||
|
||
.routine-card {
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
padding: calc(var(--space-md) + var(--space-xs) / 2) var(--space-lg);
|
||
background: var(--card);
|
||
transition: border-color var(--transition-fast);
|
||
}
|
||
|
||
.routine-card:hover {
|
||
border-color: color-mix(in srgb, var(--border) 70%, var(--text) 30%);
|
||
}
|
||
|
||
.routine-card.disabled {
|
||
opacity: 0.55;
|
||
}
|
||
|
||
.routine-card.running {
|
||
border-color: var(--color-info);
|
||
box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-info) 30%, transparent);
|
||
background: color-mix(in srgb, var(--color-info) 5%, var(--card));
|
||
}
|
||
|
||
.scripts-modal .spinner {
|
||
animation: scripts-modal-spinner-spin 1s linear infinite;
|
||
}
|
||
|
||
.routine-card-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: flex-start;
|
||
gap: var(--space-md);
|
||
}
|
||
|
||
.routine-card-info {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.routine-card-name-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.routine-card-name {
|
||
font-weight: 600;
|
||
font-size: 14px;
|
||
color: var(--text);
|
||
}
|
||
|
||
.routine-trigger-badge {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: 11px;
|
||
font-weight: 500;
|
||
padding: 1px 7px;
|
||
border-radius: 999px;
|
||
border: 1px solid;
|
||
line-height: 1.5;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.routine-scope-badge {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
font-size: 10px;
|
||
font-weight: 500;
|
||
padding: 1px 6px;
|
||
border-radius: 999px;
|
||
border: 1px solid;
|
||
line-height: 1.4;
|
||
white-space: nowrap;
|
||
text-transform: lowercase;
|
||
}
|
||
|
||
.routine-scope-badge.global {
|
||
color: var(--text-muted);
|
||
border-color: var(--text-dim);
|
||
}
|
||
|
||
.routine-scope-badge.project {
|
||
color: var(--todo);
|
||
border-color: var(--todo);
|
||
}
|
||
|
||
.routine-card-description {
|
||
margin: 4px 0 0;
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.routine-card-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.routine-card-meta {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
gap: var(--space-md);
|
||
margin-top: var(--space-md);
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.routine-meta-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
.routine-run-output {
|
||
margin-top: var(--space-sm);
|
||
border-radius: var(--radius-sm);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.routine-run-output.success {
|
||
border-left: 3px solid var(--color-success);
|
||
background: color-mix(in srgb, var(--color-success) 5%, transparent);
|
||
}
|
||
|
||
.routine-run-output.failure {
|
||
border-left: 3px solid var(--color-error);
|
||
background: color-mix(in srgb, var(--color-error) 5%, transparent);
|
||
}
|
||
|
||
.routine-run-output-text {
|
||
font-family: var(--font-mono);
|
||
font-size: 12px;
|
||
padding: var(--space-sm) var(--space-md);
|
||
margin: 0;
|
||
white-space: pre-wrap;
|
||
word-break: break-word;
|
||
max-height: 200px;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.routine-run-output-error {
|
||
font-family: var(--font-mono);
|
||
font-size: 12px;
|
||
padding: var(--space-sm) var(--space-md);
|
||
color: var(--color-error);
|
||
}
|
||
|
||
.routine-meta-label {
|
||
font-weight: 500;
|
||
}
|
||
|
||
.routine-cron {
|
||
font-size: 11px;
|
||
padding: 1px 5px;
|
||
background: var(--bg-secondary);
|
||
border-radius: var(--radius-sm);
|
||
}
|
||
|
||
.routine-policy-badge {
|
||
font-size: 11px;
|
||
padding: 1px 7px;
|
||
background: var(--bg-secondary);
|
||
border-radius: var(--radius-sm);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.routine-card-history {
|
||
margin-top: var(--space-md);
|
||
border-top: 1px solid var(--border);
|
||
padding-top: 8px;
|
||
}
|
||
|
||
.routine-history-trigger-type {
|
||
font-size: 10px;
|
||
padding: 0px 4px;
|
||
background: var(--bg-tertiary);
|
||
border-radius: var(--radius-sm);
|
||
color: var(--text-muted);
|
||
margin-left: 4px;
|
||
}
|
||
|
||
/* Routine form */
|
||
.routine-form {
|
||
padding: 0;
|
||
}
|
||
|
||
.routine-form .modal-actions {
|
||
padding: var(--space-lg) 0 0;
|
||
border-top: 1px solid var(--border);
|
||
margin-top: var(--space-lg);
|
||
position: sticky;
|
||
bottom: 0;
|
||
z-index: 1;
|
||
}
|
||
|
||
.routine-trigger-type-selector {
|
||
display: flex;
|
||
gap: var(--space-sm);
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.routine-trigger-btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: calc(var(--space-sm) - var(--space-xs) / 2);
|
||
padding: 8px 14px;
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
background: var(--bg);
|
||
color: var(--text-muted);
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
transition:
|
||
border-color var(--transition-fast),
|
||
background var(--transition-fast),
|
||
color var(--transition-fast);
|
||
}
|
||
|
||
.routine-trigger-btn:hover {
|
||
border-color: color-mix(in srgb, var(--border) 70%, var(--text) 30%);
|
||
background: var(--bg-secondary);
|
||
color: var(--text);
|
||
}
|
||
|
||
.routine-trigger-btn.active {
|
||
border-color: var(--in-progress);
|
||
background: color-mix(in srgb, var(--in-progress) 10%, transparent);
|
||
color: var(--in-progress);
|
||
}
|
||
|
||
.routine-trigger-info {
|
||
display: block;
|
||
padding: var(--space-md);
|
||
background: var(--bg-secondary);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
font-size: 13px;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
/* Routine mobile responsive */
|
||
@media (max-width: 768px) {
|
||
.routine-card {
|
||
margin: 0;
|
||
padding: var(--space-md);
|
||
}
|
||
|
||
.routine-card-header {
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.routine-card-actions {
|
||
flex-wrap: wrap;
|
||
width: 100%;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.routine-empty-state {
|
||
padding: var(--space-xl) var(--space-lg);
|
||
}
|
||
|
||
.routine-run-output-text,
|
||
.routine-run-output-error {
|
||
font-size: 11px;
|
||
}
|
||
|
||
.routine-run-output-text {
|
||
max-height: 160px;
|
||
}
|
||
|
||
.routine-form {
|
||
padding-left: var(--space-lg);
|
||
padding-right: var(--space-lg);
|
||
}
|
||
|
||
.routine-trigger-type-selector {
|
||
flex-direction: column;
|
||
}
|
||
|
||
.routine-trigger-btn {
|
||
justify-content: center;
|
||
}
|
||
}
|
||
|
||
/* ── Activity Log Modal ─────────────────────────────────────────── */
|
||
|
||
.activity-log-modal {
|
||
width: min(95vw, 640px);
|
||
max-width: 95vw;
|
||
max-height: calc(100dvh - var(--overlay-padding-top, 10vh) - 16px);
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/*
|
||
FNXC:RightDockEmbedded 2026-06-22-12:00:
|
||
The activity-log embedded (.activity-log-embedded / .activity-log-modal--embedded) rules and their @container block were moved to ActivityLogModal.css, next to the component. The base .activity-log-* modal rules remain here pending a full extraction.
|
||
*/
|
||
|
||
/*
|
||
FNXC:AutomationsEmbedded 2026-06-22-00:00:
|
||
Automations can render inline in the main content area (presentation="embedded") instead of as a fixed modal overlay.
|
||
The embedded root fills its host and sheds all modal chrome — no overlay, no card/shadow/border/radius — so the view
|
||
blends into the main panel like Command Center. The view container carries --space-lg padding and a plain .cc-header
|
||
title row (reused from Command Center). The body is a responsive two-pane layout (list + detail) via container query
|
||
when supported, falling back to a min-width media breakpoint, that collapses to a single column below ~900px.
|
||
*/
|
||
.automations-embedded.right-dock-embedded-view {
|
||
display: flex;
|
||
width: 100%;
|
||
height: 100%;
|
||
min-height: 0;
|
||
background: none;
|
||
box-shadow: none;
|
||
border: none;
|
||
border-radius: 0;
|
||
}
|
||
|
||
.automations-embedded-view {
|
||
display: flex;
|
||
flex: 1;
|
||
flex-direction: column;
|
||
gap: var(--space-lg);
|
||
min-height: 0;
|
||
inline-size: 100%;
|
||
/* Enable container-query-driven two-pane breakpoint scoped to the view's own width, not the viewport. */
|
||
container-type: inline-size;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
/*
|
||
FNXC:ViewHeader 2026-06-23-04:15:
|
||
Bring the embedded Automations header to the canonical ViewHeader treatment: edge-to-edge --surface bg without a bottom divider, --space-lg/--space-xl padding, and the shared --view-header-min-height (≈61px border-box) so it matches Agents/Mailbox/Missions exactly. The body rows below carry the horizontal --space-xl inset + a bottom inset (the view itself drops its uniform padding so the header can span edge-to-edge).
|
||
*/
|
||
.automations-embedded-header.cc-header {
|
||
box-sizing: border-box;
|
||
min-height: var(--view-header-min-height);
|
||
padding: var(--space-lg) var(--space-xl);
|
||
background: var(--surface);
|
||
border-bottom: none;
|
||
}
|
||
|
||
/* Canonical --todo leading-icon tint (override Command Center's icon-triage brown) at size 20. */
|
||
.automations-embedded-header .cc-title svg {
|
||
color: var(--todo);
|
||
}
|
||
|
||
/* Body rows keep the --space-xl horizontal inset + bottom inset that the now-edge-to-edge header no longer supplies. */
|
||
.automations-embedded-view > :not(.automations-embedded-header) {
|
||
margin-inline: var(--space-xl);
|
||
}
|
||
|
||
/*
|
||
FNXC:Automations 2026-06-23-04:45:
|
||
With the header now edge-to-edge and dividerless, the first body row still needs breathing room below the title area instead of reading flush against it. Scoped to the first body row only (the flex gap handles spacing between subsequent rows).
|
||
*/
|
||
.automations-embedded-header + :not(.automations-embedded-header) {
|
||
margin-top: var(--space-sm);
|
||
}
|
||
|
||
.automations-embedded-view > :last-child:not(.automations-embedded-header) {
|
||
margin-bottom: var(--space-lg);
|
||
}
|
||
|
||
.automations-embedded-view > .scheduling-toolbar {
|
||
padding-right: 0;
|
||
padding-left: 0;
|
||
}
|
||
|
||
/*
|
||
FNXC:Automations 2026-06-24-23:30:
|
||
The embedded single-column Automations list/detail grid must not stretch implicit rows to fill the pane; stretch pushes the selected detail card far below the list row on tall/narrow surfaces. Keep rows content-sized and top-aligned so toolbar, list, and detail stay packed while the wide breakpoint only changes the column template.
|
||
*/
|
||
.automations-two-pane {
|
||
display: grid;
|
||
grid-template-columns: 1fr;
|
||
grid-auto-rows: max-content;
|
||
align-content: start;
|
||
align-items: start;
|
||
gap: var(--space-lg);
|
||
min-height: 0;
|
||
flex: 1;
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.automations-two-pane {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
}
|
||
|
||
.automations-single-pane {
|
||
min-height: 0;
|
||
flex: 1;
|
||
}
|
||
|
||
/* Left list rail */
|
||
.automations-list-pane {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
min-width: 0;
|
||
}
|
||
|
||
.automation-list-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
width: 100%;
|
||
padding: var(--space-sm) var(--space-md);
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
color: var(--text);
|
||
font-size: 0.875rem;
|
||
text-align: left;
|
||
cursor: pointer;
|
||
transition: border-color var(--transition-fast), background var(--transition-fast);
|
||
}
|
||
|
||
.automation-list-row:hover {
|
||
border-color: var(--accent);
|
||
}
|
||
|
||
/*
|
||
FNXC:Automations 2026-06-22-12:00:
|
||
Selected automation row uses the theme accent token. --accent-subtle is not a defined token; fall back to a
|
||
theme-derived subtle accent tint (color-mix house style) so the active state follows the active theme (incl. light)
|
||
instead of resolving to a flat --card with no accent emphasis.
|
||
*/
|
||
.automation-list-row.active {
|
||
border-color: var(--accent);
|
||
background: var(--accent-subtle, color-mix(in srgb, var(--accent) 10%, transparent));
|
||
}
|
||
|
||
.automation-list-row-name {
|
||
flex: 1;
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.automation-list-row-badge {
|
||
flex-shrink: 0;
|
||
padding: 0 var(--space-sm);
|
||
border-radius: var(--radius-sm);
|
||
background: var(--bg);
|
||
border: 1px solid var(--border);
|
||
color: var(--text-muted);
|
||
font-size: 0.6875rem;
|
||
}
|
||
|
||
/* Right detail pane */
|
||
.automations-detail-pane {
|
||
min-width: 0;
|
||
min-height: 0;
|
||
}
|
||
|
||
.automations-detail-empty {
|
||
height: 100%;
|
||
}
|
||
|
||
/* Two columns once the embedded container is wide enough (~900px). */
|
||
@container (min-width: 900px) {
|
||
.automations-two-pane {
|
||
grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);
|
||
align-items: start;
|
||
}
|
||
}
|
||
|
||
/*
|
||
Fallback for browsers without container-query support: use a viewport media query. Harmless where container
|
||
queries already apply (the container-query rule above also fires and produces the same two-column layout).
|
||
*/
|
||
@media (min-width: 900px) {
|
||
.automations-two-pane {
|
||
grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);
|
||
align-items: start;
|
||
}
|
||
}
|
||
|
||
.activity-log-header {
|
||
/* Extends shared .modal-header with activity-log-specific overrides */
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.activity-log-title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-md);
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
color: var(--text);
|
||
}
|
||
|
||
.activity-log-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.activity-log-filter {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: calc(var(--space-sm) - var(--space-xs) / 2);
|
||
padding: calc(var(--space-sm) - var(--space-xs) / 2) var(--space-md);
|
||
background: var(--bg);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-sm);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.activity-log-filter-select {
|
||
background: transparent;
|
||
border: none;
|
||
color: var(--text);
|
||
font-size: 13px;
|
||
cursor: pointer;
|
||
outline: none;
|
||
}
|
||
|
||
.activity-log-refresh,
|
||
.activity-log-clear {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 32px;
|
||
height: 32px;
|
||
border: none;
|
||
background: transparent;
|
||
color: var(--text-muted);
|
||
cursor: pointer;
|
||
border-radius: var(--radius-sm);
|
||
transition: background var(--transition-fast), color var(--transition-fast);
|
||
}
|
||
|
||
.activity-log-refresh:hover,
|
||
.activity-log-clear:hover {
|
||
background: var(--card-hover);
|
||
color: var(--text);
|
||
}
|
||
|
||
.activity-log-content {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
padding: var(--space-lg) var(--space-xl);
|
||
min-height: 0;
|
||
}
|
||
|
||
.activity-log-empty {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: calc(var(--space-2xl) * 2 - var(--space-xs)) var(--space-xl);
|
||
color: var(--text-muted);
|
||
text-align: center;
|
||
}
|
||
|
||
.activity-log-empty-icon {
|
||
opacity: 0.3;
|
||
margin-bottom: var(--space-lg);
|
||
}
|
||
|
||
.activity-log-empty p {
|
||
font-size: 14px;
|
||
margin: 0;
|
||
}
|
||
|
||
.activity-log-error {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-md) var(--space-lg);
|
||
background: color-mix(in srgb, var(--ws-error) 10%, transparent);
|
||
color: var(--ws-error);
|
||
border-radius: var(--radius-md);
|
||
margin-bottom: var(--space-lg);
|
||
font-size: 13px;
|
||
}
|
||
|
||
.activity-log-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-md);
|
||
}
|
||
|
||
.activity-log-entry {
|
||
display: flex;
|
||
gap: var(--space-md);
|
||
padding: var(--space-md);
|
||
background: var(--bg-secondary);
|
||
border-radius: var(--radius-md);
|
||
border: 1px solid var(--border);
|
||
}
|
||
|
||
.activity-log-entry-icon {
|
||
flex-shrink: 0;
|
||
width: 28px;
|
||
height: 28px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: var(--bg);
|
||
border-radius: var(--radius-sm);
|
||
border: 1px solid var(--border);
|
||
}
|
||
|
||
.activity-icon {
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.activity-icon.created {
|
||
color: var(--todo);
|
||
}
|
||
|
||
.activity-icon.moved {
|
||
color: var(--in-progress);
|
||
}
|
||
|
||
.activity-icon.updated {
|
||
color: var(--color-info);
|
||
}
|
||
|
||
.activity-icon.deleted {
|
||
color: var(--ws-error);
|
||
}
|
||
|
||
.activity-icon.merged {
|
||
color: var(--done);
|
||
}
|
||
|
||
.activity-icon.failed {
|
||
color: var(--ws-error);
|
||
}
|
||
|
||
.activity-icon.settings {
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.activity-log-entry-content {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.activity-log-entry-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: var(--space-xs);
|
||
}
|
||
|
||
.activity-log-entry-type {
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
color: var(--text);
|
||
text-transform: capitalize;
|
||
}
|
||
|
||
.activity-log-entry-time {
|
||
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.activity-log-entry-details {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
margin-bottom: var(--space-xs);
|
||
}
|
||
|
||
.activity-log-task-link {
|
||
font-family: var(--font-mono);
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
color: var(--todo);
|
||
background: none;
|
||
border: none;
|
||
padding: 0;
|
||
cursor: pointer;
|
||
text-decoration: none;
|
||
}
|
||
|
||
.activity-log-task-link:hover {
|
||
text-decoration: underline;
|
||
}
|
||
|
||
.activity-log-task-title {
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
color: var(--text);
|
||
}
|
||
|
||
.activity-log-entry-text {
|
||
font-size: 13px;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.activity-log-entry-metadata {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
margin-top: 6px;
|
||
}
|
||
|
||
.activity-log-metadata-item {
|
||
font-size: 11px;
|
||
padding: 2px 8px;
|
||
background: var(--bg);
|
||
border-radius: var(--radius-sm);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.activity-log-metadata-item.success {
|
||
color: var(--color-success);
|
||
background: color-mix(in srgb, var(--color-success) 10%, transparent);
|
||
}
|
||
|
||
.activity-log-metadata-item.error {
|
||
color: var(--ws-error);
|
||
background: color-mix(in srgb, var(--ws-error) 10%, transparent);
|
||
}
|
||
|
||
.activity-log-load-more {
|
||
width: 100%;
|
||
padding: var(--space-md);
|
||
margin-top: var(--space-lg);
|
||
background: var(--bg-secondary);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
color: var(--text);
|
||
font-size: 13px;
|
||
cursor: pointer;
|
||
transition: background var(--transition-fast);
|
||
}
|
||
|
||
.activity-log-load-more:hover {
|
||
background: var(--card-hover);
|
||
}
|
||
|
||
.activity-log-loading {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: var(--space-xl);
|
||
}
|
||
|
||
.activity-log-loading .spin {
|
||
animation: scripts-modal-spinner-spin 1s linear infinite;
|
||
}
|
||
|
||
@keyframes scripts-modal-spinner-spin {
|
||
from {
|
||
transform: rotate(0deg);
|
||
}
|
||
to {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
/* Active filters bar */
|
||
.activity-log-active-filters {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-sm) var(--space-xl);
|
||
border-bottom: 1px solid var(--border);
|
||
background: var(--bg-secondary);
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.activity-log-filter-label {
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
font-weight: 500;
|
||
}
|
||
|
||
.activity-log-filter-badge {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
padding: 2px 8px;
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-pill);
|
||
color: var(--text-muted);
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.activity-log-clear-filters {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
padding: 2px 8px;
|
||
margin-left: auto;
|
||
background: none;
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-sm);
|
||
color: var(--text-muted);
|
||
font-size: 11px;
|
||
cursor: pointer;
|
||
transition:
|
||
background var(--transition-fast),
|
||
color var(--transition-fast),
|
||
border-color var(--transition-fast);
|
||
}
|
||
|
||
.activity-log-clear-filters:hover {
|
||
background: var(--card-hover);
|
||
color: var(--text);
|
||
border-color: var(--text-dim);
|
||
}
|
||
|
||
/* Project filter variant */
|
||
.activity-log-filter--project {
|
||
min-width: 140px;
|
||
}
|
||
|
||
/* Confirmation dialog */
|
||
.activity-log-confirm-overlay {
|
||
position: absolute;
|
||
inset: 0;
|
||
background: color-mix(in srgb, var(--text) 50%, transparent);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 100;
|
||
border-radius: var(--radius-lg);
|
||
}
|
||
|
||
.activity-log-confirm-dialog {
|
||
background: var(--bg);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-lg);
|
||
padding: var(--space-xl);
|
||
max-width: 360px;
|
||
text-align: center;
|
||
}
|
||
|
||
.activity-log-confirm-dialog h3 {
|
||
margin: 0 0 var(--space-sm);
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
color: var(--text);
|
||
}
|
||
|
||
.activity-log-confirm-dialog p {
|
||
margin: 0 0 var(--space-xl);
|
||
font-size: 13px;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.activity-log-confirm-actions {
|
||
display: flex;
|
||
gap: var(--space-md);
|
||
justify-content: center;
|
||
}
|
||
|
||
.activity-log-confirm-cancel,
|
||
.activity-log-confirm-clear {
|
||
padding: var(--space-md) var(--space-xl);
|
||
border-radius: var(--radius-md);
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
transition: background var(--transition-fast);
|
||
}
|
||
|
||
.activity-log-confirm-cancel {
|
||
background: var(--bg-secondary);
|
||
border: 1px solid var(--border);
|
||
color: var(--text);
|
||
}
|
||
|
||
.activity-log-confirm-cancel:hover {
|
||
background: var(--card-hover);
|
||
}
|
||
|
||
.activity-log-confirm-clear {
|
||
background: var(--ws-error);
|
||
border: 1px solid var(--ws-error);
|
||
color: var(--cta-text);
|
||
}
|
||
|
||
.activity-log-confirm-clear:hover {
|
||
background: var(--ws-error-dark);
|
||
border-color: var(--ws-error-dark);
|
||
}
|
||
|
||
/* ── Activity Log — Tablet (769px–1024px) ────────────────────────── */
|
||
|
||
@media (min-width: 769px) and (max-width: 1024px) {
|
||
/* Widen only the Activity Log modal; keep the global .modal-lg width unchanged. */
|
||
.activity-log-modal {
|
||
width: calc(100vw - var(--space-2xl));
|
||
max-width: calc(100vw - var(--space-2xl));
|
||
}
|
||
|
||
/* Header: title on left, close on right of top row, actions wrap below. */
|
||
.activity-log-header {
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.activity-log-title {
|
||
flex: 1 1 auto;
|
||
order: 0;
|
||
}
|
||
|
||
.activity-log-actions {
|
||
flex: 1 1 100%;
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
order: 2;
|
||
}
|
||
|
||
.activity-log-header .modal-close {
|
||
order: 1;
|
||
margin-left: auto;
|
||
flex: 0 0 auto;
|
||
}
|
||
|
||
.activity-log-filter,
|
||
.activity-log-filter--project {
|
||
flex: 1 1 0;
|
||
min-width: 0;
|
||
}
|
||
|
||
.activity-log-filter-select {
|
||
width: 100%;
|
||
}
|
||
|
||
.activity-log-refresh,
|
||
.activity-log-clear {
|
||
flex-shrink: 0;
|
||
}
|
||
}
|
||
|
||
/* ── Activity Log — Mobile (≤ 768px) ─────────────────────────────── */
|
||
|
||
@media (max-width: 768px) {
|
||
/* Full-screen modal on mobile, matching .modal/.modal-lg pattern */
|
||
.activity-log-modal {
|
||
max-height: 100vh;
|
||
max-height: 100dvh;
|
||
}
|
||
|
||
/* Header: title on left, close on right of top row, actions wrap below */
|
||
.activity-log-header {
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-md) var(--space-lg);
|
||
}
|
||
|
||
.activity-log-title {
|
||
flex: 1 1 auto;
|
||
order: 0;
|
||
}
|
||
|
||
.activity-log-actions {
|
||
flex: 1 1 100%;
|
||
flex-wrap: wrap;
|
||
gap: var(--space-xs);
|
||
order: 2;
|
||
}
|
||
|
||
/* Close button: pin to top-right (after title on the same row) */
|
||
.activity-log-header .modal-close {
|
||
order: 1;
|
||
margin-left: auto;
|
||
flex: 0 0 auto;
|
||
}
|
||
|
||
/* Filter containers fill available width */
|
||
.activity-log-filter,
|
||
.activity-log-filter--project {
|
||
flex: 1 1 0;
|
||
min-width: 0;
|
||
}
|
||
|
||
.activity-log-filter-select {
|
||
width: 100%;
|
||
}
|
||
|
||
/* Action buttons stay inline but shrink */
|
||
.activity-log-refresh,
|
||
.activity-log-clear {
|
||
width: 44px;
|
||
height: 44px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* Active filters bar wraps on small screens */
|
||
.activity-log-active-filters {
|
||
flex-wrap: wrap;
|
||
padding: var(--space-sm) var(--space-lg);
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
.activity-log-clear-filters {
|
||
margin-left: 0;
|
||
}
|
||
|
||
/* Content area tighter padding */
|
||
.activity-log-content {
|
||
padding: var(--space-md) var(--space-lg);
|
||
min-height: 200px;
|
||
}
|
||
|
||
/* Entries: allow content to wrap freely */
|
||
.activity-log-entry {
|
||
min-height: 36px;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-sm);
|
||
}
|
||
|
||
.activity-log-entry-icon {
|
||
width: 24px;
|
||
height: 24px;
|
||
}
|
||
|
||
.activity-log-entry-header {
|
||
flex-wrap: wrap;
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
.activity-log-entry-details {
|
||
flex-wrap: wrap;
|
||
word-break: break-word;
|
||
}
|
||
|
||
.activity-log-entry-text {
|
||
word-break: break-word;
|
||
}
|
||
|
||
/* Empty state compact */
|
||
.activity-log-empty {
|
||
padding: var(--space-xl) var(--space-lg);
|
||
}
|
||
|
||
/* Confirmation dialog fills more of the viewport */
|
||
.activity-log-confirm-dialog {
|
||
max-width: calc(100vw - 32px);
|
||
margin: 0 var(--space-lg);
|
||
}
|
||
|
||
.activity-log-confirm-actions {
|
||
flex-direction: column;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.activity-log-confirm-cancel,
|
||
.activity-log-confirm-clear {
|
||
width: 100%;
|
||
text-align: center;
|
||
}
|
||
}
|
||
|
||
/* ══════════════════════════════════════════════════════════════════
|
||
GIT MANAGER MODAL
|
||
══════════════════════════════════════════════════════════════════ */
|
||
|
||
/* Modal size override - flex layout for sidebar + content */
|
||
/*
|
||
FNXC:GitManager 2026-06-23-23:52:
|
||
Sidebar-launched floating modals should not dim, blur, or block the app behind them. Match the Files/RightDock floating-window model: the overlay is transparent and click-through, while the Git Manager panel remains interactive. Dismissal stays on Escape/close button instead of backdrop click.
|
||
|
||
FNXC:GitManager 2026-06-23-21:28:
|
||
Theme-level modal backdrop rules can load after component CSS and reapply dim/blur, especially in glass themes. Use a higher-specificity modal overlay selector and clear both standard and WebKit backdrop filters so Git Manager never darkens the app behind it.
|
||
*/
|
||
.modal-overlay.git-manager-modal-overlay.git-manager-modal-overlay {
|
||
background: transparent;
|
||
backdrop-filter: none;
|
||
-webkit-backdrop-filter: none;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.modal.gm-modal {
|
||
width: min(95vw, 1400px);
|
||
max-width: 95vw;
|
||
min-width: 0;
|
||
height: 92vh;
|
||
min-height: calc(var(--space-2xl) * 15);
|
||
max-height: calc(100dvh - var(--overlay-padding-top, 10vh) - var(--space-lg));
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
resize: both;
|
||
pointer-events: auto;
|
||
}
|
||
|
||
/*
|
||
FNXC:RightDockEmbedding 2026-06-22-00:00:
|
||
Right-dock redesign renders dock items inline (GitManager presentation="embedded") instead of as fixed popup modals.
|
||
The embedded host fills its right-dock container; the inner shell drops overlay-only chrome (fixed sizing, box-shadow, resize handle, rounded corners) so it reads as an inline panel, not a floating modal.
|
||
*/
|
||
.git-manager-embedded {
|
||
display: flex;
|
||
width: 100%;
|
||
height: 100%;
|
||
min-height: 0;
|
||
}
|
||
|
||
.gm-modal.gm-modal--embedded {
|
||
width: 100%;
|
||
height: 100%;
|
||
max-width: none;
|
||
min-width: 0;
|
||
max-height: none;
|
||
min-height: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
box-shadow: none;
|
||
border-radius: 0;
|
||
resize: none;
|
||
position: static;
|
||
/* Drive the dock-vs-expand layout off the embedded host's own width, not the viewport. */
|
||
container-type: inline-size;
|
||
container-name: gm-embedded;
|
||
}
|
||
|
||
/*
|
||
FNXC:GitManager 2026-06-22-17:30:
|
||
The embedded Git Manager adapts to its CONTAINER width, not the viewport, so the SAME embedded render works in both the narrow right dock and the wide pop-out (expand) modal:
|
||
- Wide container (expand modal, > 560px): inherits the default desktop layout — vertical section sidebar + content (two-pane, like before). Those default rules live OUTSIDE this container query and are untouched.
|
||
- Narrow container (dock, <= 560px): MIRRORS the phone-width (@media max-width:768px) gm layout exactly. Section tabs become a horizontal strip with ICON + TEXT LABEL per tab (the mobile .gm-nav-item: column, icon over label, comfortable padding), and every section (status grid, create form, branches, stashes, changes/files split, and the REMOTES view) collapses to its mobile single-column form. The remotes view is CSS-only (no JS width gating in GitManagerModal.tsx), so mirroring the @media remotes rules here gives the dock the mobile remotes selector strip + stacked detail.
|
||
The previous bespoke rules here hid the tab labels (icon-only) and used a cramped strip; the user wants labeled tabs, more spacing, and the mobile remotes layout, so we now mirror the @media gm INTERNAL rules verbatim under the .gm-modal--embedded prefix. Only the viewport-takeover (.modal.gm-modal 100vw/100dvh) rules are NOT mirrored — they are scoped to :not(.gm-modal--embedded) and must never apply to the embedded pane.
|
||
*/
|
||
@container gm-embedded (max-width: 560px) {
|
||
.gm-modal--embedded .gm-changes-split {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-changes-lists {
|
||
min-width: 0;
|
||
max-width: 100%;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-file-section {
|
||
min-width: 0;
|
||
max-width: 100%;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-file-section-header {
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.gm-modal--embedded .gm-file-section-header h5 {
|
||
min-width: 0;
|
||
flex: 1 1 auto;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-file-section-actions {
|
||
flex: 1 1 100%;
|
||
flex-wrap: wrap;
|
||
min-width: 0;
|
||
justify-content: flex-start;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-file-section-actions .btn {
|
||
flex: 1 1 auto;
|
||
min-width: 0;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-file-item {
|
||
min-width: 0;
|
||
flex-wrap: wrap;
|
||
row-gap: var(--space-xs);
|
||
}
|
||
|
||
.gm-modal--embedded .gm-file-checkbox,
|
||
.gm-modal--embedded .gm-file-icon,
|
||
.gm-modal--embedded .gm-file-badge,
|
||
.gm-modal--embedded .gm-file-item .gm-icon-btn {
|
||
flex: 0 0 auto;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-file-name {
|
||
flex: 1 1 auto;
|
||
min-width: 0;
|
||
}
|
||
|
||
/* ── Section tabs: mobile horizontal strip with icon + TEXT LABEL ── */
|
||
.gm-modal--embedded .gm-layout {
|
||
flex-direction: column;
|
||
}
|
||
|
||
/*
|
||
FNXC:GitManager 2026-06-22-19:20:
|
||
The dock tab strip is ONE ROW that scrolls left-right when needed, showing as many section icons as fit. Tabs are compact ICON-ONLY (labels are sr-only; the button title gives a tooltip) so the maximum number of sections is visible before horizontal scroll kicks in. width:auto overrides the base .gm-nav-item width:100% that otherwise made each tab fill the row (one per swipe).
|
||
|
||
FNXC:GitManager 2026-06-24-21:25:
|
||
The embedded right-dock tablist must opt out of the global mobile pan-y lock the same way as the standalone modal: horizontal touch scrolling keeps late tabs and Refresh reachable while pan-y still lets vertical page/content scroll win when the gesture is vertical.
|
||
*/
|
||
.gm-modal--embedded .gm-sidebar {
|
||
flex: 0 0 auto;
|
||
flex-direction: row;
|
||
flex-wrap: nowrap;
|
||
width: 100%;
|
||
min-width: 0;
|
||
border-right: none;
|
||
border-bottom: 1px solid var(--border);
|
||
overflow-x: auto;
|
||
overflow-y: hidden;
|
||
-webkit-overflow-scrolling: touch;
|
||
overscroll-behavior-x: contain;
|
||
scrollbar-width: thin;
|
||
touch-action: pan-x pan-y;
|
||
padding: var(--space-xs) var(--space-sm);
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
.gm-modal--embedded .gm-nav-item {
|
||
flex: 0 0 auto;
|
||
width: auto;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 0;
|
||
padding: var(--space-xs);
|
||
border-left: none;
|
||
border-bottom: 2px solid transparent;
|
||
min-width: calc(var(--space-xl) + var(--space-xs));
|
||
min-height: calc(var(--space-xl) + var(--space-sm));
|
||
}
|
||
|
||
.gm-modal--embedded .gm-repo-selector-wrap {
|
||
flex: 0 0 auto;
|
||
border-bottom: none;
|
||
padding: var(--space-xs);
|
||
min-height: calc(var(--space-xl) + var(--space-sm));
|
||
}
|
||
|
||
.gm-modal--embedded .gm-repo-selector {
|
||
flex: 0 0 auto;
|
||
width: auto;
|
||
max-width: calc(var(--space-2xl) * 4);
|
||
border-radius: var(--radius-sm);
|
||
padding: calc(var(--space-xs) / 2) var(--space-xs);
|
||
font-size: var(--font-size-xs);
|
||
}
|
||
|
||
/* Icon-only: hide the section label (kept for screen readers); the button title is the tooltip. */
|
||
.gm-modal--embedded .gm-nav-label {
|
||
position: absolute;
|
||
width: 1px;
|
||
height: 1px;
|
||
padding: 0;
|
||
margin: -1px;
|
||
overflow: hidden;
|
||
clip: rect(0, 0, 0, 0);
|
||
white-space: nowrap;
|
||
border: 0;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-nav-item.active {
|
||
border-left-color: transparent;
|
||
border-bottom-color: var(--todo);
|
||
}
|
||
|
||
/*
|
||
FNXC:GitManager 2026-06-22-19:20:
|
||
In the one-row scrolling strip the refresh is a compact icon button matching .gm-nav-item, pinned as the last item. Drop the desktop margin-top:auto so it stays inline.
|
||
*/
|
||
.gm-modal--embedded .gm-nav-refresh {
|
||
flex: 0 0 auto;
|
||
width: auto;
|
||
margin-top: 0;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: var(--space-xs);
|
||
border-left: none;
|
||
min-width: calc(var(--space-xl) + var(--space-xs));
|
||
}
|
||
|
||
.gm-modal--embedded .gm-content {
|
||
min-height: 200px;
|
||
padding: var(--space-md);
|
||
}
|
||
|
||
.gm-modal--embedded .gm-search-box input {
|
||
font-size: 16px;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-status-grid {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-create-form {
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-create-form input,
|
||
.gm-modal--embedded .gm-create-form select {
|
||
flex: 1 1 100%;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-branch-item {
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.gm-modal--embedded .gm-stash-header {
|
||
flex-direction: column;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.gm-modal--embedded .gm-stash-actions {
|
||
width: 100%;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-remote-actions {
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-pull-split {
|
||
flex: 1 1 100%;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-pull-split-toggle {
|
||
min-width: 36px;
|
||
min-height: 36px;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-pull-menu {
|
||
left: 0;
|
||
right: auto;
|
||
min-width: 100%;
|
||
}
|
||
|
||
/* ── Remotes view: mobile single-column (selector strip + stacked detail) ── */
|
||
.gm-modal--embedded .gm-remotes-layout {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-remote-selector {
|
||
width: 100%;
|
||
min-width: 0;
|
||
border-right: 1px solid var(--border);
|
||
flex-direction: row;
|
||
overflow-x: auto;
|
||
overflow-y: hidden;
|
||
padding-bottom: var(--space-sm);
|
||
}
|
||
|
||
.gm-modal--embedded .gm-remote-selector-header {
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
padding: 0 var(--space-xs) 0 0;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-remote-selector-item {
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: var(--space-xs);
|
||
min-width: 120px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-remote-selector-name {
|
||
width: 100%;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-remote-detail {
|
||
min-height: 200px;
|
||
padding-right: 0;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-remote-form {
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-remote-form .gm-input,
|
||
.gm-modal--embedded .gm-remote-form .gm-input-url {
|
||
width: 100%;
|
||
min-width: unset;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-remote-detail-url-row {
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-remote-inline-actions {
|
||
margin-left: auto;
|
||
}
|
||
|
||
.gm-modal--embedded .gm-commit-form .gm-commit-actions {
|
||
flex-direction: column;
|
||
}
|
||
}
|
||
|
||
/* Main layout: sidebar + content */
|
||
.gm-layout {
|
||
display: flex;
|
||
flex: 1;
|
||
min-height: 0;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* ── Sidebar ── */
|
||
|
||
.gm-sidebar {
|
||
display: flex;
|
||
flex-direction: column;
|
||
width: 160px;
|
||
min-width: 160px;
|
||
border-right: 1px solid var(--border);
|
||
background: color-mix(in srgb, var(--bg) 35%, transparent);
|
||
padding: var(--space-sm) 0;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
/* ── Workspace repo selector ── */
|
||
.gm-repo-selector-wrap {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
padding: var(--space-sm) var(--space-lg);
|
||
border-bottom: 1px solid var(--border);
|
||
color: var(--text-muted);
|
||
}
|
||
.gm-repo-selector {
|
||
flex: 1;
|
||
min-width: 0;
|
||
background: var(--bg-input);
|
||
color: var(--text);
|
||
border: 1px solid var(--border);
|
||
border-radius: 4px;
|
||
padding: 2px 4px;
|
||
font-size: 12px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.gm-nav-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-sm) var(--space-lg);
|
||
background: none;
|
||
border: none;
|
||
color: var(--text-muted);
|
||
font-size: 13px;
|
||
cursor: pointer;
|
||
transition: all var(--transition-fast);
|
||
text-align: left;
|
||
width: 100%;
|
||
border-left: 3px solid transparent;
|
||
}
|
||
|
||
.gm-nav-item:hover {
|
||
color: var(--text);
|
||
background: color-mix(in srgb, var(--text) 5%, transparent);
|
||
}
|
||
|
||
.gm-nav-item.active {
|
||
color: var(--text);
|
||
background: color-mix(in srgb, var(--todo) 8%, transparent);
|
||
border-left-color: var(--todo);
|
||
font-weight: 500;
|
||
}
|
||
|
||
/*
|
||
FNXC:GitManager 2026-06-22-19:00:
|
||
Refresh button pinned at the end of the section nav strip (replaces the removed duplicate internal gray .modal-header refresh). In the desktop vertical sidebar margin-top:auto pins it to the bottom; in the dock wrapping/mobile horizontal strip it sits as the last tab. Shares the .gm-nav-item visual language; theme tokens only.
|
||
*/
|
||
.gm-nav-refresh {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-sm) var(--space-lg);
|
||
margin-top: auto;
|
||
background: none;
|
||
border: none;
|
||
color: var(--text-muted);
|
||
font-size: 13px;
|
||
cursor: pointer;
|
||
transition: all var(--transition-fast);
|
||
text-align: left;
|
||
width: 100%;
|
||
border-left: 3px solid transparent;
|
||
}
|
||
|
||
.gm-nav-refresh:hover:not(:disabled) {
|
||
color: var(--text);
|
||
background: color-mix(in srgb, var(--text) 5%, transparent);
|
||
}
|
||
|
||
.gm-nav-refresh:disabled {
|
||
opacity: 0.6;
|
||
cursor: default;
|
||
}
|
||
|
||
/* ── Header Actions ── */
|
||
|
||
.gm-header-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
/* ── Content Area ── */
|
||
|
||
.gm-content {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow-y: auto;
|
||
padding: var(--space-lg);
|
||
min-height: 400px;
|
||
position: relative;
|
||
}
|
||
|
||
/* ── Loading / Error ── */
|
||
|
||
.gm-loading {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-2xl);
|
||
color: var(--text-muted);
|
||
font-size: 14px;
|
||
}
|
||
|
||
.gm-error {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-lg);
|
||
background: color-mix(in srgb, var(--color-error) 10%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--color-error) 20%, transparent);
|
||
border-radius: var(--radius-md);
|
||
color: var(--color-error);
|
||
font-size: 13px;
|
||
}
|
||
|
||
.gm-error .btn {
|
||
margin-left: auto;
|
||
}
|
||
|
||
/* ── Panel Container ── */
|
||
|
||
.gm-panel {
|
||
display: flex;
|
||
flex: 1;
|
||
flex-direction: column;
|
||
min-height: 0;
|
||
gap: var(--space-md);
|
||
}
|
||
|
||
.gm-panel-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: var(--space-md);
|
||
}
|
||
|
||
.gm-panel-header h4 {
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
margin: 0;
|
||
}
|
||
|
||
/* ── Empty State ── */
|
||
|
||
.gm-empty {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: var(--space-xl);
|
||
color: var(--text-dim);
|
||
font-size: 13px;
|
||
font-style: italic;
|
||
}
|
||
|
||
/* ── Status Panel ── */
|
||
|
||
.gm-status-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: var(--space-md);
|
||
}
|
||
|
||
.gm-status-card {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
padding: var(--space-md);
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
}
|
||
|
||
.gm-status-label {
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.5px;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.gm-status-value {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: 14px;
|
||
color: var(--text);
|
||
}
|
||
|
||
.gm-status-sub {
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.gm-status-conflict {
|
||
color: var(--color-error);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.gm-status-warning {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-md);
|
||
margin-top: var(--space-md);
|
||
background: color-mix(in srgb, var(--color-warning) 12%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--color-warning) 40%, transparent);
|
||
border-radius: var(--radius-md);
|
||
font-size: 13px;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.gm-status-warning svg {
|
||
flex-shrink: 0;
|
||
margin-top: 2px;
|
||
color: var(--color-warning);
|
||
}
|
||
|
||
.gm-status-warning code {
|
||
background: var(--card);
|
||
padding: 1px 4px;
|
||
border-radius: var(--radius-sm);
|
||
font-size: 12px;
|
||
}
|
||
|
||
.gm-status-advances {
|
||
margin-top: var(--space-md);
|
||
padding: var(--space-md);
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
font-size: 13px;
|
||
}
|
||
|
||
.gm-status-advances-header {
|
||
font-weight: 600;
|
||
font-size: 12px;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.5px;
|
||
color: var(--text-muted);
|
||
margin-bottom: var(--space-sm);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: var(--space-sm);
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.gm-status-advances-help {
|
||
margin: var(--space-sm) 0;
|
||
padding: var(--space-sm) var(--space-md);
|
||
background: color-mix(in srgb, var(--accent, #4a8af4) 6%, transparent);
|
||
border-left: 3px solid var(--accent, #4a8af4);
|
||
border-radius: var(--radius-sm);
|
||
font-size: 12px;
|
||
text-transform: none;
|
||
letter-spacing: normal;
|
||
color: var(--text);
|
||
font-weight: normal;
|
||
}
|
||
|
||
.gm-status-advances-help p {
|
||
margin: 0 0 var(--space-sm) 0;
|
||
}
|
||
|
||
.gm-status-advances-help p:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.gm-status-advances-help-list {
|
||
list-style: disc;
|
||
margin: 0 0 var(--space-sm) 0;
|
||
padding-left: var(--space-lg);
|
||
display: block;
|
||
}
|
||
|
||
.gm-status-advances-help-list li {
|
||
padding: 2px 0;
|
||
background: none;
|
||
}
|
||
|
||
.gm-status-advances ul {
|
||
list-style: none;
|
||
padding: 0;
|
||
margin: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
.gm-status-advances li {
|
||
padding: 4px 8px;
|
||
border-radius: var(--radius-sm);
|
||
font-size: 12px;
|
||
}
|
||
|
||
.gm-status-advances .gm-advance-needs-action {
|
||
background: color-mix(in srgb, var(--color-warning) 8%, transparent);
|
||
}
|
||
|
||
.gm-status-advances .gm-advance-handled {
|
||
background: color-mix(in srgb, var(--color-success) 6%, transparent);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.gm-status-badge {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
padding: 2px 8px;
|
||
border-radius: var(--radius-sm);
|
||
}
|
||
|
||
.gm-status-badge.clean {
|
||
color: var(--color-success);
|
||
background: color-mix(in srgb, var(--color-success) 10%, transparent);
|
||
}
|
||
|
||
.gm-status-badge.dirty {
|
||
color: var(--color-error);
|
||
background: color-mix(in srgb, var(--color-error) 10%, transparent);
|
||
}
|
||
|
||
.gm-hash {
|
||
font-family: var(--font-mono);
|
||
font-size: 12px;
|
||
background: color-mix(in srgb, var(--text) 5%, transparent);
|
||
padding: 2px 6px;
|
||
border-radius: var(--radius-sm);
|
||
color: var(--todo);
|
||
}
|
||
|
||
.gm-ahead {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: calc(var(--space-xs) / 2);
|
||
color: var(--color-success);
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.gm-behind {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: calc(var(--space-xs) / 2);
|
||
color: var(--color-error);
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.gm-in-sync {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
color: var(--color-success);
|
||
font-size: 13px;
|
||
}
|
||
|
||
/* ── Icon Button ── */
|
||
|
||
.gm-icon-btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 24px;
|
||
height: 24px;
|
||
background: none;
|
||
border: none;
|
||
border-radius: var(--radius-sm);
|
||
color: var(--text-muted);
|
||
cursor: pointer;
|
||
transition: all var(--transition-fast);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.gm-icon-btn:hover {
|
||
background: color-mix(in srgb, var(--text) 10%, transparent);
|
||
color: var(--text);
|
||
}
|
||
|
||
/* ── Search Box ── */
|
||
|
||
.gm-search-box {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
padding: var(--space-xs) var(--space-sm);
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-sm);
|
||
flex: 0 0 auto;
|
||
max-width: 200px;
|
||
}
|
||
|
||
.gm-search-box input {
|
||
background: none;
|
||
border: none;
|
||
color: var(--text);
|
||
font-size: 12px;
|
||
outline: none;
|
||
width: 100%;
|
||
min-width: 0;
|
||
}
|
||
|
||
.gm-search-box svg {
|
||
color: var(--text-muted);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* ── Changes Panel ── */
|
||
|
||
.gm-changes-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-md);
|
||
padding: var(--space-sm) var(--space-md);
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
}
|
||
|
||
.gm-branch-indicator {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
color: var(--text);
|
||
}
|
||
|
||
.gm-dirty-badge {
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
padding: 2px 6px;
|
||
border-radius: var(--radius-sm);
|
||
background: color-mix(in srgb, var(--color-error) 10%, transparent);
|
||
color: var(--color-error);
|
||
}
|
||
|
||
/* ── Split-pane: file lists on left, diff viewer on right ─────────────────
|
||
* Lazygit-style layout so the file lists stay visible while reading a diff.
|
||
* `.gm-content` (the panel scroll container) keeps overflow-y: auto, and the
|
||
* left column uses `position: sticky` so it pins to the top as the right
|
||
* column scrolls. Mobile (≤720px) collapses to a single column with the
|
||
* lists rendered first and the diff below — sticky disabled because there's
|
||
* no horizontal room for a second pane and a sticky list would eat the
|
||
* already-tight viewport.
|
||
*/
|
||
.gm-changes-split {
|
||
display: grid;
|
||
grid-template-columns: minmax(280px, 360px) 1fr;
|
||
gap: var(--space-md);
|
||
align-items: start;
|
||
}
|
||
|
||
.gm-changes-lists {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-md);
|
||
position: sticky;
|
||
top: 0;
|
||
align-self: start;
|
||
min-height: 0;
|
||
/* Cap the sticky column so its internal lists never push past the viewport
|
||
* — without this, two long lists at max-height 200px each + headers can
|
||
* exceed the available scroll-port height and the column visually clips. */
|
||
max-height: calc(100dvh - var(--overlay-padding-top, 10vh) - 280px);
|
||
overflow-y: auto;
|
||
/* Don't let the sticky scrollbar overlap the diff column. */
|
||
padding-right: 2px;
|
||
}
|
||
|
||
.gm-changes-diff {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-sm);
|
||
/* Allow children (long file paths, code lines) to shrink below intrinsic
|
||
* width — required for `overflow: hidden` / `word-break` to work in the
|
||
* diff viewer. Without this the right column would push the layout wider
|
||
* than the modal. */
|
||
min-width: 0;
|
||
/* Match the lists' top so empty/loading/diff states align with the list
|
||
* column visually. */
|
||
padding-top: 0;
|
||
}
|
||
|
||
/* Empty placeholder shown when no file is selected. Gives the right pane
|
||
* structure on first open instead of a blank gap. */
|
||
.gm-diff-empty {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-2xl) var(--space-lg);
|
||
border: 1px dashed var(--border);
|
||
border-radius: var(--radius-md);
|
||
color: var(--text-dim);
|
||
font-size: 13px;
|
||
min-height: 140px;
|
||
}
|
||
|
||
@media (max-width: 720px) {
|
||
.gm-changes-split {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
.gm-changes-lists {
|
||
position: static;
|
||
max-height: none;
|
||
overflow-y: visible;
|
||
padding-right: 0;
|
||
}
|
||
.gm-diff-empty {
|
||
/* Don't take a full screen of empty state on mobile — collapse to a
|
||
* compact hint when no file is selected. */
|
||
min-height: 0;
|
||
padding: var(--space-md);
|
||
}
|
||
}
|
||
|
||
/* ── File Section ── */
|
||
|
||
.gm-file-section {
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 0;
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.gm-file-section-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: var(--space-sm) var(--space-md);
|
||
background: color-mix(in srgb, var(--bg) 55%, transparent);
|
||
border-bottom: 1px solid var(--border);
|
||
}
|
||
|
||
.gm-file-section-header h5 {
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.3px;
|
||
color: var(--text-muted);
|
||
margin: 0;
|
||
}
|
||
|
||
.gm-file-section-actions {
|
||
display: flex;
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
/* ── File List ── */
|
||
|
||
.gm-file-list {
|
||
min-height: 0;
|
||
max-height: calc(var(--space-2xl) * 6 + var(--space-md));
|
||
overflow-y: auto;
|
||
overscroll-behavior: contain;
|
||
-webkit-overflow-scrolling: touch;
|
||
}
|
||
|
||
.gm-file-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-xs) var(--space-md);
|
||
border-bottom: 1px solid color-mix(in srgb, var(--text) 3%, transparent);
|
||
font-size: 13px;
|
||
transition: background var(--transition-fast);
|
||
cursor: pointer;
|
||
}
|
||
|
||
.gm-file-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.gm-file-item:hover {
|
||
background: color-mix(in srgb, var(--text) 3%, transparent);
|
||
}
|
||
|
||
.gm-file-item.staged {
|
||
background: color-mix(in srgb, var(--color-success) 3%, transparent);
|
||
}
|
||
|
||
.gm-file-item.active {
|
||
background: var(--card-hover);
|
||
}
|
||
|
||
.gm-file-item:focus-visible {
|
||
outline: none;
|
||
box-shadow: var(--focus-ring-strong);
|
||
}
|
||
|
||
.gm-file-checkbox {
|
||
display: flex;
|
||
align-items: center;
|
||
cursor: pointer;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.gm-file-checkbox input[type="checkbox"] {
|
||
width: 14px;
|
||
height: 14px;
|
||
accent-color: var(--todo);
|
||
}
|
||
|
||
/* Show as much of the path as fits, truncating the LEFT side (parent dirs)
|
||
* with an ellipsis so the filename — the most identifying part — stays
|
||
* visible. `direction: rtl` flips the truncation side; the JSX wraps the
|
||
* value in `<bdo dir="ltr">` so the displayed text still reads naturally
|
||
* left-to-right. */
|
||
.gm-file-name {
|
||
flex: 1;
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
direction: rtl;
|
||
font-family: var(--font-mono);
|
||
font-size: 12px;
|
||
color: var(--text);
|
||
}
|
||
|
||
.gm-file-icon {
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.gm-file-added { color: var(--color-success); }
|
||
.gm-file-modified { color: var(--todo); }
|
||
.gm-file-deleted { color: var(--color-error); }
|
||
.gm-file-renamed { color: var(--in-progress); }
|
||
|
||
.gm-file-badge {
|
||
font-family: var(--font-mono);
|
||
font-size: 10px;
|
||
font-weight: 700;
|
||
padding: 1px 4px;
|
||
border-radius: var(--radius-sm);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.gm-file-badge-added,
|
||
.gm-file-badge-untracked {
|
||
background: color-mix(in srgb, var(--color-success) 15%, transparent);
|
||
color: var(--color-success);
|
||
}
|
||
|
||
.gm-file-badge-modified {
|
||
background: color-mix(in srgb, var(--todo) 15%, transparent);
|
||
color: var(--todo);
|
||
}
|
||
|
||
.gm-file-badge-deleted {
|
||
background: color-mix(in srgb, var(--color-error) 15%, transparent);
|
||
color: var(--color-error);
|
||
}
|
||
|
||
.gm-file-badge-renamed,
|
||
.gm-file-badge-copied {
|
||
background: color-mix(in srgb, var(--in-progress) 15%, transparent);
|
||
color: var(--in-progress);
|
||
}
|
||
|
||
/* ── Diff Viewer ── */
|
||
|
||
.gm-diff-section {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.gm-diff-target {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.gm-diff-target code {
|
||
font-family: var(--font-mono);
|
||
font-size: 11px;
|
||
color: var(--text);
|
||
}
|
||
|
||
.changed-files-diff-section {
|
||
height: 100%;
|
||
}
|
||
|
||
.gm-diff-viewer {
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
overflow: hidden;
|
||
background: var(--card);
|
||
}
|
||
|
||
.gm-diff-stat {
|
||
padding: var(--space-sm) var(--space-md);
|
||
background: var(--surface);
|
||
font-family: var(--font-mono);
|
||
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
||
color: var(--text-muted);
|
||
border-bottom: 1px solid var(--border);
|
||
margin: 0;
|
||
white-space: pre-wrap;
|
||
word-break: break-all;
|
||
}
|
||
|
||
.gm-diff-patch {
|
||
padding: var(--space-sm) var(--space-md);
|
||
font-family: var(--font-mono);
|
||
font-size: 11px;
|
||
line-height: 1.5;
|
||
color: var(--text);
|
||
max-height: 420px;
|
||
overflow: auto;
|
||
margin: 0;
|
||
white-space: pre-wrap;
|
||
word-break: break-all;
|
||
}
|
||
|
||
.gm-diff-loading {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-lg);
|
||
color: var(--text-muted);
|
||
font-size: 13px;
|
||
background: var(--surface);
|
||
border-radius: var(--radius-md);
|
||
border: 1px solid var(--border);
|
||
}
|
||
|
||
.gm-diff-error {
|
||
padding: var(--space-md);
|
||
color: var(--color-error);
|
||
font-size: 13px;
|
||
background: var(--surface);
|
||
border-radius: var(--radius-md);
|
||
border: 1px solid var(--border);
|
||
}
|
||
|
||
.changed-files-layout {
|
||
display: grid;
|
||
grid-template-columns: minmax(240px, 320px) minmax(0, 1fr);
|
||
min-height: 60vh;
|
||
}
|
||
|
||
.changed-files-sidebar {
|
||
border-right: 1px solid var(--border);
|
||
background: var(--surface);
|
||
}
|
||
|
||
.changed-files-content {
|
||
padding: var(--space-md);
|
||
min-width: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.changed-files-entry {
|
||
/* Button reset — entries are <button> elements that must not use browser defaults */
|
||
background: none;
|
||
border: none;
|
||
font-family: inherit;
|
||
font-size: inherit;
|
||
color: var(--text);
|
||
text-align: left;
|
||
width: 100%;
|
||
/* Layout */
|
||
justify-content: flex-start;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-sm) var(--space-md);
|
||
cursor: pointer;
|
||
transition: background var(--transition-fast);
|
||
}
|
||
|
||
.changed-files-entry:hover {
|
||
background: var(--card-hover);
|
||
}
|
||
|
||
.changed-files-entry:focus-visible {
|
||
box-shadow: var(--focus-ring-strong);
|
||
outline: none;
|
||
}
|
||
|
||
.changed-files-entry.active {
|
||
background: var(--card);
|
||
border-left: 3px solid var(--todo);
|
||
}
|
||
|
||
/* Entry icon color uses muted token so it adapts to every theme */
|
||
.changed-files-entry .file-node-icon {
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
/* Entry filename uses theme text token */
|
||
.changed-files-entry .file-node-name {
|
||
color: var(--text);
|
||
}
|
||
|
||
.changed-files-badge {
|
||
margin-left: auto;
|
||
}
|
||
|
||
/* Status-aware badge colors in the changed-files modal sidebar */
|
||
.changed-files-badge--added {
|
||
color: var(--status-color-added, #3fb950);
|
||
border-color: var(--status-color-added, #3fb950);
|
||
}
|
||
|
||
.changed-files-badge--modified {
|
||
color: var(--status-color-modified, #58a6ff);
|
||
border-color: var(--status-color-modified, #58a6ff);
|
||
}
|
||
|
||
.changed-files-badge--deleted {
|
||
color: var(--status-color-deleted, #f85149);
|
||
border-color: var(--status-color-deleted, #f85149);
|
||
}
|
||
|
||
.changed-files-badge--renamed,
|
||
.changed-files-badge--unknown {
|
||
color: var(--status-color-unknown, #8b949e);
|
||
border-color: var(--status-color-unknown, #8b949e);
|
||
}
|
||
|
||
/* ── Commit Form ── */
|
||
|
||
.gm-commit-form {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-md);
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
}
|
||
|
||
.gm-commit-input {
|
||
width: 100%;
|
||
background: var(--bg);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-sm);
|
||
color: var(--text);
|
||
font-family: var(--font-mono);
|
||
font-size: 12px;
|
||
padding: var(--space-sm);
|
||
resize: vertical;
|
||
min-height: 60px;
|
||
outline: none;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.gm-commit-input:focus {
|
||
border-color: var(--todo);
|
||
box-shadow: var(--focus-ring);
|
||
}
|
||
|
||
.gm-commit-actions {
|
||
display: flex;
|
||
gap: var(--space-sm);
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
/* ── Commits Panel ── */
|
||
|
||
.gm-commits-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.gm-commit-item {
|
||
display: flex;
|
||
gap: var(--space-sm);
|
||
position: relative;
|
||
}
|
||
|
||
.gm-commit-graph {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
width: 20px;
|
||
flex-shrink: 0;
|
||
padding-top: 12px;
|
||
}
|
||
|
||
.gm-commit-dot {
|
||
width: 10px;
|
||
height: 10px;
|
||
border-radius: 50%;
|
||
background: var(--todo);
|
||
border: 2px solid var(--card);
|
||
flex-shrink: 0;
|
||
z-index: 1;
|
||
}
|
||
|
||
.gm-commit-line {
|
||
width: 2px;
|
||
flex: 1;
|
||
background: var(--border);
|
||
margin-top: -1px;
|
||
}
|
||
|
||
.gm-commit-body {
|
||
flex: 1;
|
||
min-width: 0;
|
||
padding-bottom: var(--space-sm);
|
||
}
|
||
|
||
.gm-commit-header {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: calc(var(--space-xs) / 2);
|
||
width: 100%;
|
||
background: none;
|
||
border: none;
|
||
color: var(--text);
|
||
cursor: pointer;
|
||
text-align: left;
|
||
padding: var(--space-xs) var(--space-sm);
|
||
border-radius: var(--radius-sm);
|
||
transition: background var(--transition-fast);
|
||
}
|
||
|
||
.gm-commit-header:hover {
|
||
background: color-mix(in srgb, var(--text) 3%, transparent);
|
||
}
|
||
|
||
.gm-commit-top-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.gm-commit-message {
|
||
flex: 1;
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.gm-commit-meta {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.gm-merge-badge {
|
||
font-size: 10px;
|
||
font-weight: 600;
|
||
padding: 1px 5px;
|
||
border-radius: var(--radius-sm);
|
||
background: color-mix(in srgb, var(--in-progress) 15%, transparent);
|
||
color: var(--in-progress);
|
||
text-transform: uppercase;
|
||
}
|
||
|
||
.gm-commit-actions-row {
|
||
display: flex;
|
||
gap: var(--space-xs);
|
||
padding-left: var(--space-sm);
|
||
}
|
||
|
||
.gm-commit-diff {
|
||
margin-top: var(--space-xs);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-sm);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.gm-load-more {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: var(--space-sm);
|
||
background: none;
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
color: var(--text-muted);
|
||
font-size: 13px;
|
||
cursor: pointer;
|
||
transition: all var(--transition-fast);
|
||
width: 100%;
|
||
margin-top: var(--space-sm);
|
||
}
|
||
|
||
.gm-load-more:hover {
|
||
color: var(--text);
|
||
border-color: var(--text-muted);
|
||
background: color-mix(in srgb, var(--text) 3%, transparent);
|
||
}
|
||
|
||
/* ── Create Form (branches, stashes) ── */
|
||
|
||
.gm-create-form {
|
||
display: flex;
|
||
gap: var(--space-sm);
|
||
align-items: center;
|
||
}
|
||
|
||
.gm-create-form input,
|
||
.gm-create-form select {
|
||
flex: 1;
|
||
min-width: 0;
|
||
padding: calc(var(--space-sm) - var(--space-xs) / 2) var(--space-md);
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-sm);
|
||
color: var(--text);
|
||
font-size: 12px;
|
||
outline: none;
|
||
}
|
||
|
||
.gm-create-form input:focus,
|
||
.gm-create-form select:focus {
|
||
border-color: var(--todo);
|
||
box-shadow: var(--focus-ring);
|
||
}
|
||
|
||
.gm-branch-select {
|
||
max-width: 150px;
|
||
}
|
||
|
||
/* ── Branches List ── */
|
||
|
||
.gm-branches-list {
|
||
display: flex;
|
||
flex: 1;
|
||
flex-direction: column;
|
||
min-height: 0;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.gm-branch-item {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: var(--space-sm) var(--space-md);
|
||
border-bottom: 1px solid color-mix(in srgb, var(--text) 3%, transparent);
|
||
transition: background var(--transition-fast);
|
||
}
|
||
|
||
.gm-branch-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.gm-branch-item:hover {
|
||
background: color-mix(in srgb, var(--text) 3%, transparent);
|
||
}
|
||
|
||
.gm-branch-item.current {
|
||
background: color-mix(in srgb, var(--todo) 5%, transparent);
|
||
}
|
||
|
||
.gm-branch-info {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
min-width: 0;
|
||
flex: 1;
|
||
}
|
||
|
||
.gm-branch-name {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
color: var(--text);
|
||
}
|
||
|
||
.gm-current-icon {
|
||
color: var(--color-success);
|
||
}
|
||
|
||
.gm-branch-remote {
|
||
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.gm-branch-date {
|
||
font-size: 11px;
|
||
color: var(--text-dim);
|
||
}
|
||
|
||
.gm-branch-actions {
|
||
display: flex;
|
||
gap: var(--space-xs);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* ── Branch Selection Details ── */
|
||
|
||
.gm-branch-item.selected {
|
||
background: color-mix(in srgb, var(--todo) 8%, transparent);
|
||
cursor: pointer;
|
||
}
|
||
|
||
.gm-branch-item.selected:hover {
|
||
background: color-mix(in srgb, var(--todo) 12%, transparent);
|
||
}
|
||
|
||
.gm-branch-details {
|
||
background: color-mix(in srgb, var(--bg) 65%, transparent);
|
||
border-bottom: 1px solid color-mix(in srgb, var(--text) 5%, transparent);
|
||
padding: var(--space-sm) var(--space-md);
|
||
}
|
||
|
||
.gm-branch-details-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: var(--space-sm);
|
||
}
|
||
|
||
.gm-branch-details-title {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.gm-branch-details-loading {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-sm) 0;
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.gm-branch-commits-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.gm-branch-commit {
|
||
border-bottom: 1px solid color-mix(in srgb, var(--text) 3%, transparent);
|
||
}
|
||
|
||
.gm-branch-commit:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.gm-branch-commit-row {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: calc(var(--space-xs) / 2);
|
||
width: 100%;
|
||
padding: var(--space-xs) var(--space-sm);
|
||
background: none;
|
||
border: none;
|
||
color: var(--text);
|
||
text-align: left;
|
||
cursor: pointer;
|
||
border-radius: var(--radius-sm);
|
||
transition: background var(--transition-fast);
|
||
}
|
||
|
||
.gm-branch-commit-row:hover {
|
||
background: color-mix(in srgb, var(--text) 3%, transparent);
|
||
}
|
||
|
||
/* ── Worktrees Panel ── */
|
||
|
||
.gm-worktree-stats {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.gm-stat-separator {
|
||
color: var(--text-dim);
|
||
}
|
||
|
||
.gm-worktrees-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
.gm-worktree-item {
|
||
padding: var(--space-sm) var(--space-md);
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
transition: background var(--transition-fast);
|
||
}
|
||
|
||
.gm-worktree-item:hover {
|
||
background: var(--card-hover);
|
||
}
|
||
|
||
.gm-worktree-item.main {
|
||
border-left: 3px solid var(--color-success);
|
||
}
|
||
|
||
.gm-worktree-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
.gm-worktree-path-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.gm-worktree-path {
|
||
font-family: var(--font-mono);
|
||
font-size: 12px;
|
||
color: var(--text);
|
||
}
|
||
|
||
.gm-worktree-detail {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-md);
|
||
}
|
||
|
||
.gm-worktree-branch {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.gm-worktree-task {
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
padding: 1px 6px;
|
||
border-radius: var(--radius-sm);
|
||
background: color-mix(in srgb, var(--todo) 12%, transparent);
|
||
color: var(--todo);
|
||
}
|
||
|
||
.gm-badge {
|
||
font-size: 10px;
|
||
font-weight: 700;
|
||
padding: 1px 5px;
|
||
border-radius: var(--radius-sm);
|
||
text-transform: uppercase;
|
||
}
|
||
|
||
.gm-badge.main {
|
||
background: color-mix(in srgb, var(--color-success) 15%, transparent);
|
||
color: var(--color-success);
|
||
}
|
||
|
||
.gm-badge.bare {
|
||
background: color-mix(in srgb, var(--text-muted) 15%, transparent);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
/* ── Stash Panel ── */
|
||
|
||
.gm-stash-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
.gm-stash-item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-sm) var(--space-md);
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
}
|
||
|
||
.gm-stash-header {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
gap: var(--space-md);
|
||
}
|
||
|
||
.gm-stash-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: calc(var(--space-xs) / 2);
|
||
min-width: 0;
|
||
flex: 1;
|
||
}
|
||
|
||
.gm-stash-ref {
|
||
font-family: var(--font-mono);
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
color: var(--todo);
|
||
}
|
||
|
||
.gm-stash-message {
|
||
font-size: 13px;
|
||
color: var(--text);
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.gm-stash-meta {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.gm-stash-branch {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: calc(var(--space-xs) / 2);
|
||
}
|
||
|
||
.gm-stash-actions {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: var(--space-xs);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.gm-stash-diff {
|
||
border-top: 1px solid var(--border);
|
||
padding-top: var(--space-sm);
|
||
}
|
||
|
||
/* ── Remote Panel ── */
|
||
|
||
.gm-remote-status {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.gm-remote-indicator {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-xs) var(--space-sm);
|
||
border-radius: var(--radius-pill);
|
||
font-size: 0.75rem;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.gm-remote-indicator .status-dot {
|
||
margin-right: 0;
|
||
}
|
||
|
||
.gm-remote-indicator.ahead {
|
||
background: color-mix(in srgb, var(--color-success) 10%, transparent);
|
||
color: var(--color-success);
|
||
}
|
||
|
||
.gm-remote-indicator.behind {
|
||
background: color-mix(in srgb, var(--color-warning) 12%, transparent);
|
||
color: var(--color-warning);
|
||
}
|
||
|
||
.gm-remote-actions {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.gm-remote-actions .btn {
|
||
flex: 1 1 calc(var(--space-2xl) * 5);
|
||
}
|
||
|
||
.gm-pull-split {
|
||
position: relative;
|
||
display: flex;
|
||
align-items: stretch;
|
||
flex: 1 1 calc(var(--space-2xl) * 5);
|
||
}
|
||
|
||
.gm-pull-split .btn {
|
||
flex: 1 1 auto;
|
||
}
|
||
|
||
.gm-pull-split-main {
|
||
border-top-right-radius: 0;
|
||
border-bottom-right-radius: 0;
|
||
}
|
||
|
||
.gm-pull-split-toggle {
|
||
flex: 0 0 auto;
|
||
align-self: stretch;
|
||
width: auto;
|
||
min-width: var(--space-xl);
|
||
border-top-left-radius: 0;
|
||
border-bottom-left-radius: 0;
|
||
border-left: 0;
|
||
padding-inline: var(--space-xs);
|
||
}
|
||
|
||
.gm-pull-menu {
|
||
position: absolute;
|
||
top: calc(100% + var(--space-xs));
|
||
right: 0;
|
||
z-index: 4;
|
||
min-width: calc(var(--space-2xl) * 5);
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
padding: var(--space-sm);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
background: color-mix(in srgb, var(--surface) 80%, var(--card));
|
||
box-shadow: var(--shadow-lg);
|
||
}
|
||
|
||
.gm-pull-menu-item {
|
||
border: 0;
|
||
border-radius: var(--radius-sm);
|
||
background: transparent;
|
||
color: var(--text);
|
||
text-align: left;
|
||
font: inherit;
|
||
padding: var(--space-sm);
|
||
cursor: pointer;
|
||
transition: background var(--transition-fast);
|
||
}
|
||
|
||
.gm-pull-menu-item:hover {
|
||
background: var(--card-hover);
|
||
}
|
||
|
||
.gm-pull-menu-item:focus-visible {
|
||
outline: none;
|
||
box-shadow: var(--focus-ring-strong);
|
||
}
|
||
|
||
.gm-remote-result {
|
||
padding: var(--space-sm) var(--space-md);
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
font-size: 12px;
|
||
font-family: var(--font-mono);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
/* ── Remotes Two-Column Layout ── */
|
||
|
||
.gm-remotes-panel {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 100%;
|
||
}
|
||
|
||
.gm-remotes-layout {
|
||
display: grid;
|
||
grid-template-columns: minmax(calc(var(--space-2xl) * 6), calc(var(--space-2xl) * 8)) minmax(0, 1fr);
|
||
gap: var(--space-md);
|
||
flex: 1;
|
||
min-height: 0;
|
||
}
|
||
|
||
/* ── Remote Selector (Left Column) ── */
|
||
|
||
.gm-remote-selector {
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
overflow-y: auto;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
padding: var(--space-sm);
|
||
background: color-mix(in srgb, var(--surface) 55%, transparent);
|
||
}
|
||
|
||
.gm-remote-selector-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: var(--space-xs) 0;
|
||
position: sticky;
|
||
top: 0;
|
||
background: var(--bg);
|
||
z-index: 1;
|
||
}
|
||
|
||
.gm-remote-selector-title {
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
color: var(--text-muted);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.05em;
|
||
}
|
||
|
||
.gm-remote-selector-item {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-sm);
|
||
border-radius: var(--radius-md);
|
||
border: 1px solid transparent;
|
||
cursor: pointer;
|
||
transition: background var(--transition-fast), border-color var(--transition-fast);
|
||
}
|
||
|
||
.gm-remote-selector-item:hover {
|
||
background: var(--card-hover);
|
||
}
|
||
|
||
.gm-remote-selector-item:focus-visible {
|
||
outline: none;
|
||
border-color: var(--todo);
|
||
box-shadow: var(--focus-ring-strong);
|
||
}
|
||
|
||
.gm-remote-selector-item.selected {
|
||
border-color: var(--todo);
|
||
background: color-mix(in srgb, var(--todo) 12%, transparent);
|
||
}
|
||
|
||
.gm-remote-selector-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
min-width: 0;
|
||
flex: 1;
|
||
}
|
||
|
||
.gm-remote-selector-name {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
min-width: 0;
|
||
font-weight: 600;
|
||
font-size: 14px;
|
||
color: var(--text);
|
||
}
|
||
|
||
.gm-remote-selector-name-text {
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.gm-remote-default-badge {
|
||
font-size: 10px;
|
||
font-weight: 600;
|
||
padding: 0 var(--space-xs);
|
||
border-radius: var(--radius-pill);
|
||
background: color-mix(in srgb, var(--todo) 16%, transparent);
|
||
color: var(--todo);
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.gm-remote-selector-host {
|
||
font-size: 12px;
|
||
font-family: var(--font-mono);
|
||
color: var(--text-muted);
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* ── Remote Detail Panel (Right Column) ── */
|
||
|
||
.gm-remote-detail {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-md);
|
||
overflow-y: auto;
|
||
min-width: 0;
|
||
padding-right: var(--space-xs);
|
||
}
|
||
|
||
/* ── Sync Card ── */
|
||
|
||
.gm-remote-sync-card {
|
||
padding: var(--space-md);
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-md);
|
||
}
|
||
|
||
.gm-remote-sync-card-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.gm-remote-sync-card-title {
|
||
font-weight: 600;
|
||
font-size: 14px;
|
||
color: var(--text);
|
||
}
|
||
|
||
/* ── Detail Card ── */
|
||
|
||
.gm-remote-detail-card {
|
||
padding: var(--space-md);
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.gm-section-subheader {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: var(--space-xs) 0;
|
||
}
|
||
|
||
.gm-section-subheader h5 {
|
||
margin: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: 0.75rem;
|
||
font-weight: 600;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.gm-remote-detail-urls {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
.gm-remote-detail-url-row {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: var(--space-sm);
|
||
font-size: 0.75rem;
|
||
font-family: var(--font-mono);
|
||
}
|
||
|
||
.gm-url-label {
|
||
color: var(--text-muted);
|
||
flex-shrink: 0;
|
||
width: 40px;
|
||
}
|
||
|
||
.gm-url-value {
|
||
color: var(--text);
|
||
flex: 1;
|
||
min-width: 0;
|
||
line-height: 1.5;
|
||
overflow-wrap: anywhere;
|
||
}
|
||
|
||
.gm-remote-inline-actions {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.gm-remote-remove-btn {
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.gm-remote-detail-name-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
padding-top: var(--space-xs);
|
||
border-top: 1px solid var(--border);
|
||
}
|
||
|
||
.gm-remote-edit {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
flex: 1;
|
||
}
|
||
|
||
.gm-remote-edit .gm-input {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
/* ── Remote Section (reused for commits) ── */
|
||
|
||
.gm-remote-section {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
/* ── Remote Form ── */
|
||
|
||
.gm-remote-form {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-sm);
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
margin-bottom: var(--space-xs);
|
||
}
|
||
|
||
.gm-remote-form .gm-input {
|
||
flex: 1;
|
||
}
|
||
|
||
.gm-remote-form .gm-input-url {
|
||
flex: 2;
|
||
}
|
||
|
||
.gm-remote-form .btn {
|
||
align-self: flex-end;
|
||
}
|
||
|
||
/* ── Commit Items (shared) ── */
|
||
|
||
.gm-commit-item-compact {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-xs) var(--space-sm);
|
||
border-radius: var(--radius-sm);
|
||
font-size: 13px;
|
||
}
|
||
|
||
.gm-commit-item-compact:hover {
|
||
background: var(--card-hover);
|
||
}
|
||
|
||
.gm-commit-compact-hash {
|
||
flex-shrink: 0;
|
||
font-family: var(--font-mono);
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
padding-top: 1px;
|
||
}
|
||
|
||
.gm-commit-compact-info {
|
||
flex: 1;
|
||
min-width: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: calc(var(--space-xs) / 2);
|
||
}
|
||
|
||
.gm-commit-compact-info .gm-commit-message {
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
color: var(--text);
|
||
}
|
||
|
||
.gm-commit-compact-info .gm-commit-meta {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-xs);
|
||
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.gm-commit-item-compact-wrapper {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.gm-commit-clickable {
|
||
cursor: pointer;
|
||
transition: background var(--transition-fast);
|
||
}
|
||
|
||
.gm-commit-clickable:hover {
|
||
background: var(--card-hover);
|
||
}
|
||
|
||
.gm-commit-clickable:focus-visible {
|
||
outline: none;
|
||
box-shadow: var(--focus-ring-strong);
|
||
}
|
||
|
||
.gm-commit-expand-icon {
|
||
flex-shrink: 0;
|
||
color: var(--text-muted);
|
||
display: flex;
|
||
align-items: center;
|
||
padding-top: 1px;
|
||
}
|
||
|
||
.gm-commit-diff-compact {
|
||
margin: var(--space-xs) var(--space-sm) var(--space-sm) var(--space-sm);
|
||
}
|
||
|
||
.gm-commit-message-full {
|
||
padding: var(--space-sm);
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
color: var(--text);
|
||
background: var(--surface-1);
|
||
border-bottom: 1px solid var(--border);
|
||
white-space: pre-wrap;
|
||
word-break: break-word;
|
||
}
|
||
|
||
.gm-ahead-commits-list,
|
||
.gm-remote-commits-list {
|
||
max-height: 280px;
|
||
overflow-y: auto;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* ── Responsive ── */
|
||
|
||
@media (max-width: 768px) {
|
||
.gm-changes-split {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.gm-changes-lists {
|
||
min-width: 0;
|
||
max-width: 100%;
|
||
}
|
||
|
||
.gm-file-section {
|
||
min-width: 0;
|
||
max-width: 100%;
|
||
}
|
||
|
||
.gm-file-section-header {
|
||
flex-wrap: wrap;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.gm-file-section-header h5 {
|
||
min-width: 0;
|
||
flex: 1 1 auto;
|
||
}
|
||
|
||
.gm-file-section-actions {
|
||
flex: 1 1 100%;
|
||
flex-wrap: wrap;
|
||
min-width: 0;
|
||
justify-content: flex-start;
|
||
}
|
||
|
||
.gm-file-section-actions .btn {
|
||
flex: 1 1 auto;
|
||
min-width: 0;
|
||
}
|
||
|
||
.gm-file-item {
|
||
min-width: 0;
|
||
flex-wrap: wrap;
|
||
row-gap: var(--space-xs);
|
||
}
|
||
|
||
.gm-file-checkbox,
|
||
.gm-file-icon,
|
||
.gm-file-badge,
|
||
.gm-file-item .gm-icon-btn {
|
||
flex: 0 0 auto;
|
||
}
|
||
|
||
.gm-file-name {
|
||
flex: 1 1 auto;
|
||
min-width: 0;
|
||
}
|
||
|
||
.gm-remotes-layout {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.gm-remote-selector {
|
||
max-height: calc(var(--space-2xl) * 8);
|
||
}
|
||
|
||
.gm-remote-selector-header {
|
||
position: static;
|
||
}
|
||
|
||
.gm-remote-selector-item {
|
||
align-items: flex-start;
|
||
}
|
||
|
||
.gm-remote-selector-name {
|
||
width: 100%;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.gm-remote-detail {
|
||
padding-right: 0;
|
||
}
|
||
|
||
.gm-remote-detail-url-row {
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.gm-remote-inline-actions {
|
||
margin-left: auto;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
/* Full-screen sheet on mobile — drop overlay padding so the modal
|
||
actually fills the viewport instead of being pushed below it.
|
||
FNXC:GitManager 2026-06-22-16:00: scope the viewport-takeover to the
|
||
NON-embedded (dialog) presentation via :not(.gm-modal--embedded). The
|
||
embedded Git Manager renders inside the main-content pane; without the
|
||
guard its base .gm-modal class matched these 100vw/100dvh rules and hid
|
||
the app Header + MobileNavBar. The embedded panel keeps its 100%-of-pane
|
||
sizing from the embedded block above. */
|
||
.modal-overlay.git-manager-modal-overlay,
|
||
.modal-overlay:has(.gm-modal:not(.gm-modal--embedded)) {
|
||
padding-top: 0;
|
||
align-items: stretch;
|
||
justify-content: stretch;
|
||
}
|
||
|
||
.modal.gm-modal:not(.gm-modal--embedded) {
|
||
width: 100vw;
|
||
min-width: 0;
|
||
max-width: 100vw;
|
||
height: 100dvh;
|
||
min-height: 100dvh;
|
||
max-height: 100dvh;
|
||
margin: 0;
|
||
border: none;
|
||
border-radius: 0;
|
||
resize: none;
|
||
flex: 1 1 auto;
|
||
}
|
||
|
||
.modal.gm-modal:not(.gm-modal--embedded)[style*="--keyboard-overlap"] {
|
||
height: var(--vv-height, 100dvh);
|
||
min-height: var(--vv-height, 100dvh);
|
||
max-height: var(--vv-height, 100dvh);
|
||
transform: translateY(var(--vv-offset-top, 0px));
|
||
will-change: transform;
|
||
}
|
||
|
||
/* Same treatment for the Automations modal — same min-width: 480px would
|
||
otherwise force it wider than narrow viewports.
|
||
FNXC:Automations 2026-06-22-16:00: scope the viewport-takeover to the
|
||
dialog presentation only. The embedded Automations view uses the distinct
|
||
.automations-embedded / .automations-embedded-view classes (it does NOT
|
||
carry .automation-modal), so it is unaffected here — but the guard keeps
|
||
this rule from ever leaking onto an embedded variant should the markup
|
||
share the base class later. The embedded view fills its pane and scrolls
|
||
via .automations-embedded-view (inline-size:100% + overflow-y:auto). */
|
||
.modal-overlay:has(.automation-modal:not(.automation-modal--embedded)) {
|
||
padding-top: 0;
|
||
align-items: stretch;
|
||
justify-content: stretch;
|
||
}
|
||
|
||
.modal.automation-modal:not(.automation-modal--embedded) {
|
||
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;
|
||
}
|
||
|
||
.gm-layout {
|
||
flex-direction: column;
|
||
}
|
||
|
||
/*
|
||
FNXC:GitManager 2026-06-21-11:27:
|
||
The mobile global `* { touch-action: pan-y; }` lock from FN-6365 blocks horizontal swipes unless the actual overflowing scroller opts back into pan-x.
|
||
The Git Manager section toolbar must keep all fixed section tabs reachable on touch viewports, so mirror the FN-6450 tab-strip treatment and prevent tab compression (FN-6857).
|
||
|
||
FNXC:GitManager 2026-06-21-18:00:
|
||
FN-6900 requires the Git Manager section tabs to remain visible and switchable on touch viewports. In the mobile column layout, the content pane is the flexible sibling, so the tab strip must be `flex: 0 0 auto` with a token-sized minimum height instead of shrinking to a zero-height row.
|
||
|
||
FNXC:GitManager 2026-06-24-21:25:
|
||
FN-6981 requires the actual mobile tablist scroller to be a single non-wrapping horizontal strip in both modal and embedded presentations. Keep `pan-x pan-y` so horizontal swipes reveal later tabs/Refresh without stealing vertical scroll gestures from the page or content panel.
|
||
*/
|
||
.gm-sidebar {
|
||
flex: 0 0 auto;
|
||
flex-direction: row;
|
||
flex-wrap: nowrap;
|
||
width: 100%;
|
||
min-width: 0;
|
||
min-height: calc(var(--space-2xl) + var(--space-md));
|
||
border-right: none;
|
||
border-bottom: 1px solid var(--border);
|
||
overflow-x: auto;
|
||
overflow-y: hidden;
|
||
touch-action: pan-x pan-y;
|
||
-webkit-overflow-scrolling: touch;
|
||
overscroll-behavior-x: contain;
|
||
padding: var(--space-xs) var(--space-sm);
|
||
gap: var(--space-xs);
|
||
}
|
||
|
||
/*
|
||
FNXC:GitManager 2026-06-22-19:35:
|
||
Mobile (<=768px) nav strip: ICON-ONLY compact tabs in one horizontally-scrolling row so multiple sections are visible at once. width:auto overrides the base .gm-nav-item width:100% that otherwise made each tab fill the row (one tab, swipe-only). Labels are sr-only (button title is the tooltip).
|
||
*/
|
||
.gm-nav-item {
|
||
flex: 0 0 auto;
|
||
width: auto;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 0;
|
||
padding: var(--space-xs);
|
||
border-left: none;
|
||
border-bottom: 2px solid transparent;
|
||
min-width: calc(var(--space-xl) + var(--space-xs));
|
||
min-height: calc(var(--space-xl) + var(--space-sm));
|
||
}
|
||
|
||
.gm-repo-selector-wrap {
|
||
flex: 0 0 auto;
|
||
border-bottom: none;
|
||
padding: var(--space-xs);
|
||
min-height: calc(var(--space-xl) + var(--space-sm));
|
||
}
|
||
|
||
.gm-repo-selector {
|
||
flex: 0 0 auto;
|
||
width: auto;
|
||
max-width: calc(var(--space-2xl) * 4);
|
||
border-radius: var(--radius-sm);
|
||
padding: calc(var(--space-xs) / 2) var(--space-xs);
|
||
font-size: var(--font-size-xs);
|
||
}
|
||
|
||
.gm-nav-label {
|
||
position: absolute;
|
||
width: 1px;
|
||
height: 1px;
|
||
padding: 0;
|
||
margin: -1px;
|
||
overflow: hidden;
|
||
clip: rect(0, 0, 0, 0);
|
||
white-space: nowrap;
|
||
border: 0;
|
||
}
|
||
|
||
.gm-nav-item.active {
|
||
border-left-color: transparent;
|
||
border-bottom-color: var(--todo);
|
||
}
|
||
|
||
/*
|
||
FNXC:GitManager 2026-06-22-19:00:
|
||
Mobile standalone modal horizontal nav strip: refresh mirrors the mobile .gm-nav-item (column, intrinsic width) as the last tab; drop desktop margin-top:auto.
|
||
*/
|
||
.gm-nav-refresh {
|
||
flex: 0 0 auto;
|
||
width: auto;
|
||
margin-top: 0;
|
||
flex-direction: column;
|
||
gap: calc(var(--space-xs) / 2);
|
||
padding: var(--space-xs) var(--space-sm);
|
||
border-left: none;
|
||
font-size: var(--font-size-xs);
|
||
min-width: calc(var(--space-2xl) + var(--space-xl));
|
||
min-height: calc(var(--space-xl) + var(--space-sm));
|
||
text-align: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.gm-content {
|
||
min-height: 200px;
|
||
padding: var(--space-md);
|
||
}
|
||
|
||
.gm-search-box input {
|
||
font-size: 16px;
|
||
}
|
||
|
||
.gm-status-grid {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.gm-create-form {
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.gm-create-form input,
|
||
.gm-create-form select {
|
||
flex: 1 1 100%;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.gm-branch-item {
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.gm-stash-header {
|
||
flex-direction: column;
|
||
gap: var(--space-sm);
|
||
}
|
||
|
||
.gm-stash-actions {
|
||
width: 100%;
|
||
}
|
||
|
||
.gm-remote-actions {
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.gm-pull-split {
|
||
flex: 1 1 100%;
|
||
}
|
||
|
||
.gm-pull-split-toggle {
|
||
min-width: 36px;
|
||
min-height: 36px;
|
||
}
|
||
|
||
.gm-pull-menu {
|
||
left: 0;
|
||
right: auto;
|
||
min-width: 100%;
|
||
}
|
||
|
||
.gm-remotes-layout {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.gm-remote-selector {
|
||
width: 100%;
|
||
min-width: 0;
|
||
border-right: 1px solid var(--border);
|
||
flex-direction: row;
|
||
overflow-x: auto;
|
||
overflow-y: hidden;
|
||
padding-bottom: var(--space-sm);
|
||
}
|
||
|
||
.gm-remote-selector-header {
|
||
flex-direction: column;
|
||
gap: var(--space-xs);
|
||
padding: 0 var(--space-xs) 0 0;
|
||
}
|
||
|
||
.gm-remote-selector-item {
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: var(--space-xs);
|
||
min-width: 120px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.gm-remote-detail {
|
||
min-height: 200px;
|
||
}
|
||
|
||
.gm-remote-form {
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
}
|
||
|
||
.gm-remote-form .gm-input,
|
||
.gm-remote-form .gm-input-url {
|
||
width: 100%;
|
||
min-width: unset;
|
||
}
|
||
|
||
.gm-remote-detail-url-row {
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.gm-commit-form .gm-commit-actions {
|
||
flex-direction: column;
|
||
}
|
||
}
|
||
|
||
/* ── Light Theme Overrides ── */
|
||
|
||
[data-theme="light"] .gm-sidebar {
|
||
background: var(--surface-subtle);
|
||
}
|
||
|
||
[data-theme="light"] .gm-nav-item:hover {
|
||
background: var(--surface-hover);
|
||
}
|
||
|
||
/* FNXC:GitManager 2026-06-22-19:00: relocated refresh hover matches nav-item in light theme. */
|
||
[data-theme="light"] .gm-nav-refresh:hover:not(:disabled) {
|
||
background: var(--surface-hover);
|
||
}
|
||
|
||
[data-theme="light"] .gm-nav-item.active {
|
||
background: color-mix(in srgb, var(--todo) 6%, transparent);
|
||
}
|
||
|
||
[data-theme="light"] .gm-file-item:hover {
|
||
background: var(--surface-subtle);
|
||
}
|
||
|
||
[data-theme="light"] .gm-file-item.staged {
|
||
background: color-mix(in srgb, var(--color-success) 4%, transparent);
|
||
}
|
||
|
||
[data-theme="light"] .gm-commit-header:hover {
|
||
background: var(--surface-muted);
|
||
}
|
||
|
||
[data-theme="light"] .gm-branch-item:hover {
|
||
background: var(--surface-subtle);
|
||
}
|
||
|
||
[data-theme="light"] .gm-branch-item.current {
|
||
background: color-mix(in srgb, var(--todo) 4%, transparent);
|
||
}
|
||
|
||
[data-theme="light"] .gm-branch-item.selected {
|
||
background: color-mix(in srgb, var(--todo) 8%, transparent);
|
||
}
|
||
|
||
[data-theme="light"] .gm-branch-item.selected:hover {
|
||
background: color-mix(in srgb, var(--todo) 12%, transparent);
|
||
}
|
||
|
||
[data-theme="light"] .gm-branch-details {
|
||
background: var(--surface-subtle);
|
||
}
|
||
|
||
/* ── Remotes Two-Column Layout Light Theme ── */
|
||
|
||
[data-theme="light"] .gm-remote-selector {
|
||
background: var(--surface-subtle);
|
||
border-color: var(--border);
|
||
}
|
||
|
||
[data-theme="light"] .gm-remote-selector-item:hover {
|
||
background: var(--surface-hover);
|
||
}
|
||
|
||
[data-theme="light"] .gm-remote-selector-item.selected {
|
||
background: color-mix(in srgb, var(--todo) 8%, transparent);
|
||
}
|
||
|
||
[data-theme="light"] .gm-remote-selector-item.selected:hover {
|
||
background: color-mix(in srgb, var(--todo) 12%, transparent);
|
||
}
|
||
|
||
[data-theme="light"] .gm-remote-sync-card {
|
||
background: var(--surface-subtle);
|
||
border-color: var(--border);
|
||
}
|
||
|
||
[data-theme="light"] .gm-remote-detail-card {
|
||
background: var(--surface-subtle);
|
||
border-color: var(--border);
|
||
}
|
||
|
||
[data-theme="light"] .gm-remote-form {
|
||
background: var(--surface-subtle);
|
||
border-color: var(--border);
|
||
}
|
||
|
||
[data-theme="light"] .gm-remote-detail-name-row {
|
||
border-top-color: var(--border);
|
||
}
|
||
|
||
[data-theme="light"] .gm-remote-default-badge {
|
||
background: color-mix(in srgb, var(--todo) 10%, transparent);
|
||
color: var(--todo);
|
||
}
|
||
|
||
[data-theme="light"] .gm-hash {
|
||
background: var(--surface-emphasis);
|
||
}
|
||
|
||
[data-theme="light"] .gm-icon-btn:hover {
|
||
background: var(--surface-hover-strong);
|
||
}
|
||
|
||
[data-theme="light"] .gm-file-section-header {
|
||
background: var(--surface-muted);
|
||
}
|
||
|
||
[data-theme="light"] .gm-load-more:hover {
|
||
background: var(--surface-muted);
|
||
}
|
||
|
||
/* ── Task Changes Tab Styles ─────────────────────────────────────────────── */
|
||
|
||
.task-changes-tab {
|
||
padding: var(--space-lg);
|
||
}
|
||
|
||
.changes-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: var(--space-lg);
|
||
}
|
||
|
||
.changes-header h4 {
|
||
margin: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.changes-file-list {
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-md);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.changes-file-item {
|
||
border-bottom: 1px solid var(--border);
|
||
}
|
||
|
||
.changes-file-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.changes-file-item.expanded {
|
||
background: var(--surface);
|
||
}
|
||
|
||
.changes-file-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-sm);
|
||
padding: var(--space-md) var(--space-lg);
|
||
background: none;
|
||
border: none;
|
||
width: 100%;
|
||
text-align: left;
|
||
cursor: pointer;
|
||
color: var(--text);
|
||
font-size: 13px;
|
||
transition: background var(--transition-fast);
|
||
}
|
||
|
||
.changes-file-header:hover {
|
||
background: var(--card-hover);
|
||
}
|
||
|
||
.changes-file-toggle {
|
||
display: flex;
|
||
align-items: center;
|
||
color: var(--text-muted);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.changes-file-status {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 20px;
|
||
height: 20px;
|
||
border-radius: var(--radius-sm);
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.changes-file-path {
|
||
flex: 1;
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
direction: rtl;
|
||
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
|
||
}
|
||
|
||
.changes-file-stat {
|
||
color: var(--text-muted);
|
||
font-size: 11px;
|
||
flex-shrink: 0;
|
||
margin-left: 8px;
|
||
}
|
||
|
||
.changes-file-content {
|
||
border-top: 1px solid var(--border);
|
||
background: var(--bg);
|
||
}
|
||
|
||
.changes-diff-patch {
|
||
margin: 0;
|
||
padding: var(--space-sm) 0;
|
||
font-size: 12px;
|
||
line-height: 1.5;
|
||
overflow-x: auto;
|
||
white-space: pre;
|
||
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
|
||
color: var(--text);
|
||
}
|
||
|
||
.changes-diff-patch code {
|
||
background: none;
|
||
padding: 0;
|
||
}
|
||
|
||
/* Syntax highlighting for diff */
|
||
.gm-diff-patch .diff-add,
|
||
.changes-diff-patch .diff-add,
|
||
.gm-diff-patch [data-prefix="+"],
|
||
.changes-diff-patch [data-prefix="+"] {
|
||
color: var(--color-success);
|
||
background-color: color-mix(in srgb, var(--color-success) 12%, transparent);
|
||
}
|
||
|
||
.gm-diff-patch .diff-del,
|
||
.changes-diff-patch .diff-del,
|
||
.gm-diff-patch [data-prefix="-"],
|
||
.changes-diff-patch [data-prefix="-"] {
|
||
color: var(--color-error);
|
||
background-color: color-mix(in srgb, var(--color-error) 12%, transparent);
|
||
}
|
||
|
||
.gm-diff-patch .diff-hunk,
|
||
.changes-diff-patch .diff-hunk,
|
||
.gm-diff-patch [data-prefix="@@"],
|
||
.changes-diff-patch [data-prefix="@@"] {
|
||
color: var(--color-info, #58a6ff);
|
||
}
|
||
|
||
/* Block display for highlighted diff lines */
|
||
.gm-diff-patch .diff-add,
|
||
.gm-diff-patch .diff-del,
|
||
.gm-diff-patch .diff-hunk,
|
||
.changes-diff-patch .diff-add,
|
||
.changes-diff-patch .diff-del,
|
||
.changes-diff-patch .diff-hunk {
|
||
display: block;
|
||
padding: 0 8px;
|
||
margin: 0 -8px;
|
||
}
|
||
|
||
/* Light theme diff highlighting overrides */
|
||
[data-theme="light"] .gm-diff-patch .diff-add,
|
||
[data-theme="light"] .changes-diff-patch .diff-add,
|
||
[data-theme="light"] .gm-diff-patch [data-prefix="+"],
|
||
[data-theme="light"] .changes-diff-patch [data-prefix="+"] {
|
||
color: var(--color-success);
|
||
background-color: color-mix(in srgb, var(--color-success) 10%, transparent);
|
||
}
|
||
|
||
[data-theme="light"] .gm-diff-patch .diff-del,
|
||
[data-theme="light"] .changes-diff-patch .diff-del,
|
||
[data-theme="light"] .gm-diff-patch [data-prefix="-"],
|
||
[data-theme="light"] .changes-diff-patch [data-prefix="-"] {
|
||
color: var(--color-error);
|
||
background-color: color-mix(in srgb, var(--color-error) 10%, transparent);
|
||
}
|
||
|
||
[data-theme="light"] .gm-diff-patch .diff-hunk,
|
||
[data-theme="light"] .changes-diff-patch .diff-hunk,
|
||
[data-theme="light"] .gm-diff-patch [data-prefix="@@"],
|
||
[data-theme="light"] .changes-diff-patch [data-prefix="@@"] {
|
||
color: var(--color-info, #0969da);
|
||
}
|
||
|
||
/* Light theme changed-files modal overrides */
|
||
[data-theme="light"] .gm-diff-loading,
|
||
[data-theme="light"] .changed-files-loading {
|
||
background: var(--surface);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
[data-theme="light"] .gm-diff-error,
|
||
[data-theme="light"] .changed-files-error {
|
||
background: var(--surface);
|
||
color: var(--color-error);
|
||
}
|
||
|
||
[data-theme="light"] .gm-diff-stat {
|
||
background: var(--bg-tertiary);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
[data-theme="light"] .gm-diff-viewer {
|
||
background: var(--card);
|
||
}
|
||
|
||
[data-theme="light"] .gm-diff-patch {
|
||
color: var(--text);
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
/* Git manager: extend the canonical mobile rules above with safe-area and panel scroll behavior only. */
|
||
.gm-content {
|
||
padding-bottom: max(var(--space-md), env(safe-area-inset-bottom, 0px));
|
||
}
|
||
|
||
.gm-panel {
|
||
flex: none;
|
||
min-height: auto;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
/* Git Manager remote edit buttons: always visible on mobile (no hover) */
|
||
.gm-remote-edit-btn {
|
||
opacity: 1;
|
||
width: 36px;
|
||
height: 36px;
|
||
margin-right: -8px;
|
||
margin-top: -8px;
|
||
margin-bottom: -8px;
|
||
border-radius: var(--radius-md);
|
||
}
|
||
|
||
.gm-remote-edit-btn svg {
|
||
width: 16px;
|
||
height: 16px;
|
||
}
|
||
|
||
/* Touch targets for git manager icon buttons and activity log clear */
|
||
.gm-icon-btn,
|
||
.activity-log-clear {
|
||
min-width: 36px;
|
||
min-height: 36px;
|
||
}
|
||
}
|