/* === 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 ──────────────────────────────────────────────── */ /* Scheduling toolbar below modal header */ .scheduling-toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-md); padding: var(--space-sm) var(--modal-padding, var(--space-lg)); border-bottom: 1px solid var(--border); background: color-mix(in srgb, var(--text) 10%, transparent); } .scheduling-toolbar-left { display: flex; align-items: center; gap: var(--space-md); min-width: 0; } .scheduling-toolbar-right { display: flex; align-items: center; gap: var(--space-sm); } .scheduling-count { display: inline-flex; align-items: center; gap: var(--space-xs); font-size: var(--text-xs, 12px); 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; } /* Scheduling scope selector */ .scheduling-scope-selector { display: flex; align-items: center; gap: var(--space-xs); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-xs); } .scope-btn { display: inline-flex; align-items: center; gap: var(--space-xs); padding: var(--space-xs) var(--space-md); font-size: var(--text-xs, 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); } .scope-btn:hover { background: var(--card-hover); color: var(--text); } .scope-btn.active { background: var(--todo); color: var(--cta-text); } .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-primary); } .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-bg); transition: border-color var(--transition-fast); } .schedule-card:hover { border-color: var(--border-hover, var(--border)); } .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-primary); } .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-primary); } .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-primary); } .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-primary); } .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-primary); 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-primary); } .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: var(--border-hover, var(--border)); } .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)); } .spinner { animation: 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-primary); } .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: var(--border-hover, var(--border)); background: var(--bg-secondary); color: var(--text-primary); } .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 { max-height: 80vh; display: flex; flex-direction: column; } .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: 300px; } .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: spin 1s linear infinite; } @keyframes 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 — 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 */ .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; } /* 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; } .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; } /* ── 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(--danger, #c0392b); 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(--warning, #f4b400) 12%, transparent); border: 1px solid color-mix(in srgb, var(--warning, #f4b400) 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(--warning, #f4b400); } .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(--warning, #f4b400) 8%, transparent); } .gm-status-advances .gm-advance-handled { background: color-mix(in srgb, var(--success, #27ae60) 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 `` 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