Opt/light mode #23
+47
-2
@@ -98,6 +98,7 @@
|
|||||||
|
|
||||||
import type {
|
import type {
|
||||||
AiSettings,
|
AiSettings,
|
||||||
|
AppTheme,
|
||||||
AnalyticsSettings,
|
AnalyticsSettings,
|
||||||
CommitAiPhase,
|
CommitAiPhase,
|
||||||
ConflictFile,
|
ConflictFile,
|
||||||
@@ -165,6 +166,7 @@
|
|||||||
const REPO_STATUS_CACHE_KEY = "gitlite.repoStatusCache.v1";
|
const REPO_STATUS_CACHE_KEY = "gitlite.repoStatusCache.v1";
|
||||||
const AI_SETTINGS_KEY = "gitlite.aiSettings.v1";
|
const AI_SETTINGS_KEY = "gitlite.aiSettings.v1";
|
||||||
const ANALYTICS_SETTINGS_KEY = "gitlite.analyticsSettings.v1";
|
const ANALYTICS_SETTINGS_KEY = "gitlite.analyticsSettings.v1";
|
||||||
|
const APP_THEME_KEY = "gitlite.theme.v1";
|
||||||
const COMMIT_PANEL_HEIGHT_KEY = "gitlite.commitPanelHeight.v1";
|
const COMMIT_PANEL_HEIGHT_KEY = "gitlite.commitPanelHeight.v1";
|
||||||
const LEFT_SIDEBAR_WIDTH_KEY = "gitlite.leftSidebarWidth.v1";
|
const LEFT_SIDEBAR_WIDTH_KEY = "gitlite.leftSidebarWidth.v1";
|
||||||
const LEFT_BRANCH_PANEL_HEIGHT_KEY = "gitlite.leftBranchPanelHeight.v1";
|
const LEFT_BRANCH_PANEL_HEIGHT_KEY = "gitlite.leftBranchPanelHeight.v1";
|
||||||
@@ -239,6 +241,7 @@
|
|||||||
let appSettingsOpen = false;
|
let appSettingsOpen = false;
|
||||||
let analyticsNoticeOpen = false;
|
let analyticsNoticeOpen = false;
|
||||||
let analyticsSettings: AnalyticsSettings = defaultAnalyticsSettings();
|
let analyticsSettings: AnalyticsSettings = defaultAnalyticsSettings();
|
||||||
|
let appTheme: AppTheme = loadThemePreference();
|
||||||
let localModelOptions: LocalModelOption[] = [];
|
let localModelOptions: LocalModelOption[] = [];
|
||||||
let errorMessage = "";
|
let errorMessage = "";
|
||||||
let operation = "";
|
let operation = "";
|
||||||
@@ -337,6 +340,7 @@
|
|||||||
let fileHistoryResizeStartX = 0;
|
let fileHistoryResizeStartX = 0;
|
||||||
let fileHistoryResizeStartWidth = 0;
|
let fileHistoryResizeStartWidth = 0;
|
||||||
let fileHistoryCollapsed = true;
|
let fileHistoryCollapsed = true;
|
||||||
|
let themeMediaQuery: MediaQueryList | undefined;
|
||||||
|
|
||||||
// ── Derived ────────────────────────────────────────────────────────────────
|
// ── Derived ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -389,13 +393,18 @@
|
|||||||
$: leftSidebarRows = buildLeftSidebarRows(branchPanelCollapsed, stashPanelCollapsed, explorerPanelCollapsed);
|
$: leftSidebarRows = buildLeftSidebarRows(branchPanelCollapsed, stashPanelCollapsed, explorerPanelCollapsed);
|
||||||
$: allLeftPanelsCollapsed = branchPanelCollapsed && stashPanelCollapsed && explorerPanelCollapsed;
|
$: allLeftPanelsCollapsed = branchPanelCollapsed && stashPanelCollapsed && explorerPanelCollapsed;
|
||||||
|
|
||||||
|
$: applyThemePreference(appTheme);
|
||||||
|
|
||||||
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
themeMediaQuery = window.matchMedia("(prefers-color-scheme: light)");
|
||||||
|
themeMediaQuery.addEventListener("change", handleSystemThemeChange);
|
||||||
void runStartupSequence();
|
void runStartupSequence();
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
|
themeMediaQuery?.removeEventListener("change", handleSystemThemeChange);
|
||||||
if (autoRefreshTimer) clearInterval(autoRefreshTimer);
|
if (autoRefreshTimer) clearInterval(autoRefreshTimer);
|
||||||
if (backgroundRepoStatusTimer) clearInterval(backgroundRepoStatusTimer);
|
if (backgroundRepoStatusTimer) clearInterval(backgroundRepoStatusTimer);
|
||||||
if (backgroundFetchTimer) clearInterval(backgroundFetchTimer);
|
if (backgroundFetchTimer) clearInterval(backgroundFetchTimer);
|
||||||
@@ -754,11 +763,46 @@
|
|||||||
trackEvent("app_started", { first_run: 1 });
|
trackEvent("app_started", { first_run: 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveAppSettings(next: AnalyticsSettings) {
|
function loadThemePreference(): AppTheme {
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem(APP_THEME_KEY);
|
||||||
|
if (stored === "system" || stored === "light" || stored === "dark") return stored;
|
||||||
|
} catch {
|
||||||
|
// Local storage is optional; system theme is a sane default.
|
||||||
|
}
|
||||||
|
return "system";
|
||||||
|
}
|
||||||
|
|
||||||
|
function persistThemePreference(next: AppTheme) {
|
||||||
|
try {
|
||||||
|
localStorage.setItem(APP_THEME_KEY, next);
|
||||||
|
} catch {
|
||||||
|
// Ignore storage quota/private-mode errors.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyThemePreference(next: AppTheme) {
|
||||||
|
const prefersLight = themeMediaQuery?.matches ?? window.matchMedia("(prefers-color-scheme: light)").matches;
|
||||||
|
const resolved = next === "system"
|
||||||
|
? prefersLight
|
||||||
|
? "light"
|
||||||
|
: "dark"
|
||||||
|
: next;
|
||||||
|
document.documentElement.dataset.themePreference = next;
|
||||||
|
document.documentElement.dataset.theme = resolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSystemThemeChange() {
|
||||||
|
if (appTheme === "system") applyThemePreference(appTheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveAppSettings(next: AnalyticsSettings, nextTheme: AppTheme) {
|
||||||
analyticsSettings = next;
|
analyticsSettings = next;
|
||||||
|
appTheme = nextTheme;
|
||||||
persistAnalyticsSettings(next);
|
persistAnalyticsSettings(next);
|
||||||
|
persistThemePreference(nextTheme);
|
||||||
appSettingsOpen = false;
|
appSettingsOpen = false;
|
||||||
if (next.enabled) trackEvent("settings_saved", { analytics_enabled: 1 });
|
if (next.enabled) trackEvent("settings_saved", { analytics_enabled: 1, theme: nextTheme });
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCommitMessage(message: string) {
|
function updateCommitMessage(message: string) {
|
||||||
@@ -3932,6 +3976,7 @@
|
|||||||
{#if appSettingsOpen}
|
{#if appSettingsOpen}
|
||||||
<AppSettingsDialog
|
<AppSettingsDialog
|
||||||
analytics={analyticsSettings}
|
analytics={analyticsSettings}
|
||||||
|
theme={appTheme}
|
||||||
onSave={saveAppSettings}
|
onSave={saveAppSettings}
|
||||||
onClose={() => { appSettingsOpen = false; }}
|
onClose={() => { appSettingsOpen = false; }}
|
||||||
/>
|
/>
|
||||||
|
|||||||
+581
-92
@@ -1,54 +1,112 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
@theme {
|
@theme {
|
||||||
--color-ink: #f5f7ff;
|
--color-ink: #edf3ff;
|
||||||
--color-ink-muted: #a8b1d8;
|
--color-ink-muted: #b1bad0;
|
||||||
--color-ink-faint: #687197;
|
--color-ink-faint: #6f7c96;
|
||||||
--color-ink-dim: #838cb8;
|
--color-ink-dim: #8895ad;
|
||||||
--color-ink-quiet: #949bc8;
|
--color-ink-quiet: #98a4bb;
|
||||||
|
|
||||||
--color-surface: rgba(22, 22, 36, 0.82);
|
--color-surface: rgba(18, 23, 34, 0.88);
|
||||||
--color-surface-alt: #0b0b14;
|
--color-surface-alt: #090d14;
|
||||||
--color-surface-dim: rgba(18, 18, 30, 0.9);
|
--color-surface-dim: rgba(15, 20, 30, 0.94);
|
||||||
--color-surface-hover: rgba(47, 48, 78, 0.76);
|
--color-surface-hover: rgba(36, 45, 64, 0.78);
|
||||||
--color-surface-raised: rgba(28, 29, 48, 0.88);
|
--color-surface-raised: rgba(23, 29, 43, 0.92);
|
||||||
--color-surface-solid: #1c1d30;
|
--color-surface-solid: #171d2b;
|
||||||
|
|
||||||
--color-border: rgba(100, 108, 255, 0.28);
|
--color-border: rgba(90, 111, 154, 0.3);
|
||||||
--color-border-subtle: rgba(255, 255, 255, 0.08);
|
--color-border-subtle: rgba(226, 232, 240, 0.08);
|
||||||
--color-border-input: rgba(65, 209, 255, 0.26);
|
--color-border-input: rgba(77, 182, 214, 0.26);
|
||||||
|
|
||||||
--color-primary: #646cff;
|
--color-primary: #6f8cff;
|
||||||
--color-primary-dark: #535bf2;
|
--color-primary-dark: #5d74e8;
|
||||||
--color-accent: #41d1ff;
|
--color-accent: #4db6d6;
|
||||||
|
|
||||||
--color-bar: rgba(9, 9, 18, 0.92);
|
--color-bar: rgba(7, 10, 16, 0.94);
|
||||||
--color-bar-text: #f4f6ff;
|
--color-bar-text: #f1f5ff;
|
||||||
--color-bar-muted: #7b84b2;
|
--color-bar-muted: #7f8ba3;
|
||||||
|
|
||||||
--font-mono: "Cascadia Code", "SFMono-Regular", Consolas, monospace;
|
--font-mono: "Cascadia Code", "SFMono-Regular", Consolas, monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--app-color-scheme: dark;
|
||||||
|
--app-bg: linear-gradient(135deg, #070a10 0%, #0c111a 48%, #090e16 100%);
|
||||||
|
--app-button-bg: linear-gradient(180deg, rgba(36, 45, 64, 0.92), rgba(22, 28, 42, 0.94));
|
||||||
|
--app-input-bg: rgba(10, 14, 22, 0.82);
|
||||||
|
--app-select-option-bg: #171d2b;
|
||||||
|
--app-panel-highlight: linear-gradient(180deg, rgba(255,255,255,0.038), transparent 70%);
|
||||||
|
--app-panel-shadow: 0 18px 48px rgba(0,0,0,0.28), inset 0 1px 0 rgba(255,255,255,0.045);
|
||||||
|
--app-dialog-backdrop: #070a10;
|
||||||
|
--app-dialog-bg: #101622;
|
||||||
|
--app-dialog-chrome: #141b29;
|
||||||
|
--app-dialog-shadow: 0 24px 68px rgba(0, 0, 0, 0.54), 0 2px 12px rgba(0,0,0,0.32);
|
||||||
|
--app-settings-row-bg: #141b29;
|
||||||
|
--app-scrollbar-thumb: #303a4f;
|
||||||
|
--app-scrollbar-thumb-hover: #44506a;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] {
|
||||||
|
--color-ink: #172033;
|
||||||
|
--color-ink-muted: #475569;
|
||||||
|
--color-ink-faint: #728098;
|
||||||
|
--color-ink-dim: #5f6f89;
|
||||||
|
--color-ink-quiet: #66758d;
|
||||||
|
|
||||||
|
--color-surface: rgba(255, 255, 255, 0.86);
|
||||||
|
--color-surface-alt: #f3f6fb;
|
||||||
|
--color-surface-dim: rgba(244, 247, 252, 0.92);
|
||||||
|
--color-surface-hover: rgba(226, 233, 245, 0.82);
|
||||||
|
--color-surface-raised: rgba(255, 255, 255, 0.94);
|
||||||
|
--color-surface-solid: #ffffff;
|
||||||
|
|
||||||
|
--color-border: rgba(61, 89, 142, 0.24);
|
||||||
|
--color-border-subtle: rgba(34, 49, 78, 0.11);
|
||||||
|
--color-border-input: rgba(46, 117, 182, 0.28);
|
||||||
|
|
||||||
|
--color-primary: #315fd6;
|
||||||
|
--color-primary-dark: #284cb4;
|
||||||
|
--color-accent: #0f8fb5;
|
||||||
|
|
||||||
|
--color-bar: rgba(248, 251, 255, 0.94);
|
||||||
|
--color-bar-text: #172033;
|
||||||
|
--color-bar-muted: #64728a;
|
||||||
|
|
||||||
|
--app-color-scheme: light;
|
||||||
|
--app-bg:
|
||||||
|
radial-gradient(circle at 12% 0%, rgba(49, 95, 214, 0.12), transparent 30%),
|
||||||
|
radial-gradient(circle at 82% 4%, rgba(15, 143, 181, 0.12), transparent 28%),
|
||||||
|
linear-gradient(135deg, #f7f9fd 0%, #eef3f9 48%, #f8fafc 100%);
|
||||||
|
--app-button-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(235, 240, 249, 0.95));
|
||||||
|
--app-input-bg: rgba(255, 255, 255, 0.9);
|
||||||
|
--app-select-option-bg: #ffffff;
|
||||||
|
--app-panel-highlight: linear-gradient(180deg, rgba(255,255,255,0.72), transparent 70%);
|
||||||
|
--app-panel-shadow: 0 18px 48px rgba(28, 44, 74, 0.12), inset 0 1px 0 rgba(255,255,255,0.86);
|
||||||
|
--app-dialog-backdrop: rgba(232, 238, 248, 0.96);
|
||||||
|
--app-dialog-bg: #ffffff;
|
||||||
|
--app-dialog-chrome: #f4f7fc;
|
||||||
|
--app-dialog-shadow: 0 24px 72px rgba(28, 44, 74, 0.2), 0 2px 12px rgba(28,44,74,0.1);
|
||||||
|
--app-settings-row-bg: #f8fafd;
|
||||||
|
--app-scrollbar-thumb: #c2cada;
|
||||||
|
--app-scrollbar-thumb-hover: #aeb8cb;
|
||||||
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
*, *::before, *::after { box-sizing: border-box; }
|
*, *::before, *::after { box-sizing: border-box; }
|
||||||
|
|
||||||
html, body, #app { width: 100%; height: 100%; margin: 0; }
|
html, body, #app { width: 100%; height: 100%; margin: 0; }
|
||||||
|
|
||||||
* { scrollbar-width: thin; scrollbar-color: #2a2f45 transparent; }
|
* { scrollbar-width: thin; scrollbar-color: var(--app-scrollbar-thumb) transparent; }
|
||||||
::-webkit-scrollbar { width: 5px; height: 5px; }
|
::-webkit-scrollbar { width: 5px; height: 5px; }
|
||||||
::-webkit-scrollbar-track { background: transparent; }
|
::-webkit-scrollbar-track { background: transparent; }
|
||||||
::-webkit-scrollbar-thumb { background: #2a2f45; border-radius: 3px; }
|
::-webkit-scrollbar-thumb { background: var(--app-scrollbar-thumb); border-radius: 3px; }
|
||||||
::-webkit-scrollbar-thumb:hover { background: #3a3f58; }
|
::-webkit-scrollbar-thumb:hover { background: var(--app-scrollbar-thumb-hover); }
|
||||||
|
|
||||||
html { color-scheme: dark; }
|
html { color-scheme: var(--app-color-scheme); }
|
||||||
body {
|
body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: var(--color-ink);
|
color: var(--color-ink);
|
||||||
background:
|
background: var(--app-bg);
|
||||||
radial-gradient(circle at 22% 8%, rgba(189, 52, 254, 0.28), transparent 34%),
|
|
||||||
radial-gradient(circle at 74% 10%, rgba(65, 209, 255, 0.22), transparent 30%),
|
|
||||||
radial-gradient(circle at 88% 78%, rgba(255, 211, 67, 0.1), transparent 26%),
|
|
||||||
linear-gradient(135deg, #090912 0%, #111122 45%, #0b0b14 100%);
|
|
||||||
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||||
font-synthesis: none;
|
font-synthesis: none;
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
@@ -68,7 +126,7 @@
|
|||||||
border: 1px solid var(--color-border);
|
border: 1px solid var(--color-border);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
color: var(--color-ink-muted);
|
color: var(--color-ink-muted);
|
||||||
background: linear-gradient(180deg, rgba(42, 43, 70, 0.9), rgba(27, 28, 48, 0.92));
|
background: var(--app-button-bg);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
|
transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
@@ -85,7 +143,7 @@
|
|||||||
border: 1px solid var(--color-border-input);
|
border: 1px solid var(--color-border-input);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
color: var(--color-ink);
|
color: var(--color-ink);
|
||||||
background: rgba(13, 14, 26, 0.78);
|
background: var(--app-input-bg);
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
input:focus, textarea:focus, select:focus {
|
input:focus, textarea:focus, select:focus {
|
||||||
@@ -117,7 +175,7 @@
|
|||||||
border-color: var(--color-primary);
|
border-color: var(--color-primary);
|
||||||
box-shadow: 0 0 0 3px rgba(90, 140, 248, 0.18);
|
box-shadow: 0 0 0 3px rgba(90, 140, 248, 0.18);
|
||||||
}
|
}
|
||||||
select option { background: #1c2033; color: var(--color-ink); }
|
select option { background: var(--app-select-option-bg); color: var(--color-ink); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@layer components {
|
@layer components {
|
||||||
@@ -126,28 +184,28 @@
|
|||||||
.btn-sm { min-height: 26px; padding: 0 8px; font-size: 12px; }
|
.btn-sm { min-height: 26px; padding: 0 8px; font-size: 12px; }
|
||||||
|
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
border-color: rgba(100, 108, 255, 0.75);
|
border-color: rgba(111, 140, 255, 0.72);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
background: linear-gradient(135deg, #646cff 0%, #bd34fe 100%);
|
background: linear-gradient(135deg, #5f7df2 0%, #238eb4 100%);
|
||||||
box-shadow: 0 0 24px rgba(100, 108, 255, 0.2);
|
box-shadow: 0 10px 24px rgba(77, 182, 214, 0.16);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
.btn-primary:hover:not(:disabled) {
|
.btn-primary:hover:not(:disabled) {
|
||||||
border-color: rgba(65, 209, 255, 0.82);
|
border-color: rgba(77, 182, 214, 0.78);
|
||||||
background: linear-gradient(135deg, #747bff 0%, #c966ff 100%);
|
background: linear-gradient(135deg, #6f8cff 0%, #2da0c7 100%);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-secondary {
|
.btn-secondary {
|
||||||
border-color: rgba(65, 209, 255, 0.32);
|
border-color: rgba(77, 182, 214, 0.3);
|
||||||
color: #b9e9ff;
|
color: #b8e7f6;
|
||||||
background: linear-gradient(180deg, rgba(65, 209, 255, 0.12), rgba(100, 108, 255, 0.1));
|
background: linear-gradient(180deg, rgba(77, 182, 214, 0.1), rgba(111, 140, 255, 0.07));
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
.btn-secondary:hover:not(:disabled) {
|
.btn-secondary:hover:not(:disabled) {
|
||||||
border-color: rgba(65, 209, 255, 0.64);
|
border-color: rgba(77, 182, 214, 0.58);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
background: linear-gradient(180deg, rgba(65, 209, 255, 0.18), rgba(100, 108, 255, 0.16));
|
background: linear-gradient(180deg, rgba(77, 182, 214, 0.16), rgba(111, 140, 255, 0.12));
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-danger {
|
.btn-danger {
|
||||||
@@ -169,9 +227,9 @@
|
|||||||
border: 1px solid var(--color-border);
|
border: 1px solid var(--color-border);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
background:
|
background:
|
||||||
linear-gradient(180deg, rgba(255,255,255,0.045), transparent 72%),
|
var(--app-panel-highlight),
|
||||||
var(--color-surface);
|
var(--color-surface);
|
||||||
box-shadow: 0 18px 60px rgba(0,0,0,0.24), inset 0 1px 0 rgba(255,255,255,0.05);
|
box-shadow: var(--app-panel-shadow);
|
||||||
backdrop-filter: blur(16px);
|
backdrop-filter: blur(16px);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +241,7 @@
|
|||||||
min-height: 46px;
|
min-height: 46px;
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
border-bottom: 1px solid var(--color-border-subtle);
|
border-bottom: 1px solid var(--color-border-subtle);
|
||||||
background: linear-gradient(90deg, rgba(100,108,255,0.09), rgba(65,209,255,0.025));
|
background: linear-gradient(90deg, rgba(111,140,255,0.07), rgba(77,182,214,0.025));
|
||||||
}
|
}
|
||||||
.section-head h2 { margin: 1px 0 0; color: var(--color-ink); font-size: 14px; line-height: 1.2; font-weight: 600; }
|
.section-head h2 { margin: 1px 0 0; color: var(--color-ink); font-size: 14px; line-height: 1.2; font-weight: 600; }
|
||||||
|
|
||||||
@@ -466,7 +524,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
height: var(--app-titlebar-height);
|
height: var(--app-titlebar-height);
|
||||||
background:
|
background:
|
||||||
linear-gradient(90deg, rgba(100,108,255,0.16), rgba(65,209,255,0.08), rgba(255,211,67,0.035)),
|
linear-gradient(90deg, rgba(111,140,255,0.08), rgba(77,182,214,0.045), rgba(255,255,255,0.012)),
|
||||||
var(--color-bar);
|
var(--color-bar);
|
||||||
color: var(--color-bar-text);
|
color: var(--color-bar-text);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
@@ -518,9 +576,9 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.titlebar-info svg { color: #41d1ff; flex-shrink: 0; }
|
.titlebar-info svg { color: var(--color-accent); flex-shrink: 0; }
|
||||||
|
|
||||||
.tb-repo { color: #8e95c9; font-size: 12px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 160px; }
|
.tb-repo { color: var(--color-bar-muted); font-size: 12px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 160px; }
|
||||||
.tb-sep { color: rgba(255,255,255,0.22); font-size: 13px; }
|
.tb-sep { color: rgba(255,255,255,0.22); font-size: 13px; }
|
||||||
.tb-branch { color: #f5f7ff; font-size: 12px; font-weight: 700; font-family: var(--font-mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 220px; }
|
.tb-branch { color: #f5f7ff; font-size: 12px; font-weight: 700; font-family: var(--font-mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 220px; }
|
||||||
|
|
||||||
@@ -528,7 +586,7 @@
|
|||||||
.tb-sync.ahead { color: #e0a040; background: rgba(224,160,64,0.13); }
|
.tb-sync.ahead { color: #e0a040; background: rgba(224,160,64,0.13); }
|
||||||
.tb-sync.behind { color: #7aacff; background: rgba(122,172,255,0.13); }
|
.tb-sync.behind { color: #7aacff; background: rgba(122,172,255,0.13); }
|
||||||
|
|
||||||
.tb-no-repo { color: #7b84b2; font-size: 12px; font-style: italic; }
|
.tb-no-repo { color: var(--color-bar-muted); font-size: 12px; font-style: italic; }
|
||||||
|
|
||||||
.titlebar-right { display: flex; align-items: stretch; height: 100%; border-left: 1px solid rgba(255,255,255,0.06); }
|
.titlebar-right { display: flex; align-items: stretch; height: 100%; border-left: 1px solid rgba(255,255,255,0.06); }
|
||||||
.titlebar-actions { display: flex; align-items: stretch; }
|
.titlebar-actions { display: flex; align-items: stretch; }
|
||||||
@@ -549,7 +607,7 @@
|
|||||||
transition: background 120ms ease, color 120ms ease;
|
transition: background 120ms ease, color 120ms ease;
|
||||||
-webkit-app-region: no-drag;
|
-webkit-app-region: no-drag;
|
||||||
}
|
}
|
||||||
.tb-action:hover:not(:disabled) { background: rgba(255,255,255,0.07); border-color: transparent; color: #c0cce0; }
|
.tb-action:hover:not(:disabled) { background: rgba(255,255,255,0.06); border-color: transparent; color: #d6def0; }
|
||||||
.tb-action:disabled { opacity: 0.3; cursor: not-allowed; }
|
.tb-action:disabled { opacity: 0.3; cursor: not-allowed; }
|
||||||
.tb-action.auto-toggle.active { color: #4eca76; }
|
.tb-action.auto-toggle.active { color: #4eca76; }
|
||||||
.tb-action.auto-toggle.active:hover:not(:disabled) { color: #6ee090; background: rgba(78,202,118,0.1); }
|
.tb-action.auto-toggle.active:hover:not(:disabled) { color: #6ee090; background: rgba(78,202,118,0.1); }
|
||||||
@@ -570,22 +628,22 @@
|
|||||||
border: none;
|
border: none;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: #3a4a5c;
|
color: #536078;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background 120ms ease, color 120ms ease;
|
transition: background 120ms ease, color 120ms ease;
|
||||||
-webkit-app-region: no-drag;
|
-webkit-app-region: no-drag;
|
||||||
}
|
}
|
||||||
.tb-btn:hover:not(:disabled) { background: rgba(255,255,255,0.09); border-color: transparent; color: #c0cce0; }
|
.tb-btn:hover:not(:disabled) { background: rgba(255,255,255,0.08); border-color: transparent; color: #d6def0; }
|
||||||
.tb-btn.close:hover:not(:disabled) { background: #c0392b; color: #ffffff; }
|
.tb-btn.close:hover:not(:disabled) { background: #c0392b; color: #ffffff; }
|
||||||
|
|
||||||
/* --- Top bar (repo form) --- */
|
/* --- Top bar (repo form) --- */
|
||||||
|
|
||||||
.topbar {
|
.topbar {
|
||||||
padding: 9px 10px;
|
padding: 9px 10px;
|
||||||
border: 1px solid rgba(100,108,255,0.28);
|
border: 1px solid var(--color-border);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
background:
|
background:
|
||||||
linear-gradient(90deg, rgba(189,52,254,0.1), rgba(65,209,255,0.075), rgba(255,211,67,0.035)),
|
linear-gradient(90deg, rgba(111,140,255,0.055), rgba(77,182,214,0.045), rgba(255,255,255,0.012)),
|
||||||
var(--color-surface);
|
var(--color-surface);
|
||||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);
|
||||||
backdrop-filter: blur(16px);
|
backdrop-filter: blur(16px);
|
||||||
@@ -1049,7 +1107,7 @@
|
|||||||
inset: 0 auto 0 0;
|
inset: 0 auto 0 0;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
background: linear-gradient(90deg, #41d1ff, #646cff, #bd34fe);
|
background: linear-gradient(90deg, #4db6d6, #6f8cff, #238eb4);
|
||||||
transition: width 160ms ease;
|
transition: width 160ms ease;
|
||||||
}
|
}
|
||||||
.update-progress.indeterminate span {
|
.update-progress.indeterminate span {
|
||||||
@@ -1077,14 +1135,14 @@
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
.update-toast-primary {
|
.update-toast-primary {
|
||||||
border-color: rgba(100,108,255,0.72);
|
border-color: rgba(111,140,255,0.72);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
background: linear-gradient(135deg, #646cff, #bd34fe);
|
background: linear-gradient(135deg, #5f7df2, #238eb4);
|
||||||
}
|
}
|
||||||
.update-toast-primary:hover:not(:disabled) {
|
.update-toast-primary:hover:not(:disabled) {
|
||||||
border-color: rgba(65,209,255,0.74);
|
border-color: rgba(77,182,214,0.74);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
background: linear-gradient(135deg, #747bff, #c966ff);
|
background: linear-gradient(135deg, #6f8cff, #2da0c7);
|
||||||
}
|
}
|
||||||
.update-toast-secondary {
|
.update-toast-secondary {
|
||||||
border-color: rgba(255,255,255,0.1);
|
border-color: rgba(255,255,255,0.1);
|
||||||
@@ -2308,7 +2366,7 @@
|
|||||||
padding: 22px;
|
padding: 22px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle at center 42%, rgba(151, 118, 255, 0.12), transparent 52%),
|
radial-gradient(circle at center 42%, rgba(111, 140, 255, 0.1), transparent 52%),
|
||||||
linear-gradient(180deg, rgba(15, 18, 31, 0.55), transparent);
|
linear-gradient(180deg, rgba(15, 18, 31, 0.55), transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2324,7 +2382,7 @@
|
|||||||
.file-history-loading-halo {
|
.file-history-loading-halo {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 10px;
|
inset: 10px;
|
||||||
border: 1px solid rgba(151, 118, 255, 0.24);
|
border: 1px solid rgba(111, 140, 255, 0.22);
|
||||||
border-radius: 18px;
|
border-radius: 18px;
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
animation: fhl-halo-breathe 2.4s ease-in-out infinite;
|
animation: fhl-halo-breathe 2.4s ease-in-out infinite;
|
||||||
@@ -2344,14 +2402,14 @@
|
|||||||
stroke-linecap: round;
|
stroke-linecap: round;
|
||||||
stroke-dasharray: 92;
|
stroke-dasharray: 92;
|
||||||
stroke-dashoffset: 92;
|
stroke-dashoffset: 92;
|
||||||
filter: drop-shadow(0 0 6px rgba(151, 118, 255, 0.5));
|
filter: drop-shadow(0 0 6px rgba(77, 182, 214, 0.3));
|
||||||
animation: fhl-trace-draw 2.4s ease-in-out infinite;
|
animation: fhl-trace-draw 2.4s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
.file-history-loading-traces .fhl-trace-main {
|
.file-history-loading-traces .fhl-trace-main {
|
||||||
stroke: #9b70ff;
|
stroke: #6f8cff;
|
||||||
}
|
}
|
||||||
.file-history-loading-traces .fhl-trace-branch {
|
.file-history-loading-traces .fhl-trace-branch {
|
||||||
stroke: #ff6d26;
|
stroke: #4db6d6;
|
||||||
animation-delay: 0.28s;
|
animation-delay: 0.28s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2363,7 +2421,7 @@
|
|||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
filter:
|
filter:
|
||||||
drop-shadow(0 10px 14px rgba(0, 0, 0, 0.45))
|
drop-shadow(0 10px 14px rgba(0, 0, 0, 0.45))
|
||||||
drop-shadow(0 0 12px rgba(151, 118, 255, 0.28));
|
drop-shadow(0 0 12px rgba(77, 182, 214, 0.2));
|
||||||
animation: fhl-icon-float 2.4s ease-in-out infinite;
|
animation: fhl-icon-float 2.4s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2379,15 +2437,15 @@
|
|||||||
height: 3px;
|
height: 3px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
background: rgba(151, 118, 255, 0.14);
|
background: rgba(111, 140, 255, 0.14);
|
||||||
}
|
}
|
||||||
.file-history-loading-bar span {
|
.file-history-loading-bar span {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
width: 46%;
|
width: 46%;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
background: linear-gradient(90deg, transparent, #9b70ff 42%, #ff6d26 74%, transparent);
|
background: linear-gradient(90deg, transparent, #6f8cff 42%, #4db6d6 74%, transparent);
|
||||||
box-shadow: 0 0 12px rgba(255, 109, 38, 0.26);
|
box-shadow: 0 0 12px rgba(77, 182, 214, 0.24);
|
||||||
animation: fhl-bar-slide 1.35s ease-in-out infinite;
|
animation: fhl-bar-slide 1.35s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2441,8 +2499,10 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
min-width: 42px;
|
min-width: 42px;
|
||||||
border-right: 1px solid rgba(94,110,156,0.12);
|
border-right: 1px solid rgba(226,232,240,0.08);
|
||||||
background: rgba(7,8,16,0.2);
|
background:
|
||||||
|
linear-gradient(90deg, rgba(111,140,255,0.025), transparent),
|
||||||
|
rgba(7,10,16,0.24);
|
||||||
}
|
}
|
||||||
.graph-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
|
.graph-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
|
||||||
.graph-svg path {
|
.graph-svg path {
|
||||||
@@ -2472,8 +2532,8 @@
|
|||||||
height: 12px;
|
height: 12px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
background: var(--dot-color, #5a8cf8);
|
background: var(--dot-color, #5a8cf8);
|
||||||
border: 2px solid #111321;
|
border: 2px solid var(--app-dialog-bg);
|
||||||
box-shadow: 0 0 0 1px rgba(255,255,255,0.07);
|
box-shadow: 0 0 0 1px rgba(255,255,255,0.08), 0 2px 8px rgba(0,0,0,0.22);
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
transition: transform 120ms ease, box-shadow 120ms ease;
|
transition: transform 120ms ease, box-shadow 120ms ease;
|
||||||
}
|
}
|
||||||
@@ -2495,7 +2555,7 @@
|
|||||||
height: 15px;
|
height: 15px;
|
||||||
background: var(--color-surface-alt);
|
background: var(--color-surface-alt);
|
||||||
border-color: var(--dot-color, #5a8cf8);
|
border-color: var(--dot-color, #5a8cf8);
|
||||||
box-shadow: 0 0 0 1px rgba(255,255,255,0.08);
|
box-shadow: 0 0 0 1px rgba(255,255,255,0.1);
|
||||||
}
|
}
|
||||||
.graph-hover-branches {
|
.graph-hover-branches {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -2525,8 +2585,8 @@
|
|||||||
border: 1px solid rgba(91,209,138,0.28);
|
border: 1px solid rgba(91,209,138,0.28);
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
color: #b2f0c2;
|
color: #b2f0c2;
|
||||||
background: rgba(20,35,29,0.94);
|
background: rgba(14,36,27,0.94);
|
||||||
box-shadow: 0 8px 22px rgba(0,0,0,0.3);
|
box-shadow: 0 8px 22px rgba(0,0,0,0.24);
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
font-size: 9.5px;
|
font-size: 9.5px;
|
||||||
font-weight: 750;
|
font-weight: 750;
|
||||||
@@ -2559,28 +2619,28 @@
|
|||||||
gap: 5px;
|
gap: 5px;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
padding: 8px 10px;
|
padding: 8px 10px;
|
||||||
background: rgba(28,29,48,0.34);
|
background: rgba(18,24,36,0.5);
|
||||||
transition: background 120ms ease;
|
transition: background 120ms ease;
|
||||||
}
|
}
|
||||||
.graph-row + .graph-row .commit-body { border-top: 1px solid rgba(94,110,156,0.1); }
|
.graph-row + .graph-row .commit-body { border-top: 1px solid rgba(226,232,240,0.075); }
|
||||||
.graph-row.graph-ahead-row .commit-body {
|
.graph-row.graph-ahead-row .commit-body {
|
||||||
box-shadow: inset 3px 0 0 rgba(224,160,64,0.72);
|
box-shadow: inset 3px 0 0 rgba(224,160,64,0.72);
|
||||||
}
|
}
|
||||||
.graph-row.graph-behind-row .commit-body {
|
.graph-row.graph-behind-row .commit-body {
|
||||||
box-shadow: inset 3px 0 0 rgba(122,172,255,0.72);
|
box-shadow: inset 3px 0 0 rgba(122,172,255,0.72);
|
||||||
}
|
}
|
||||||
.graph-row:hover .commit-body { background: rgba(37,40,62,0.54); }
|
.graph-row:hover .commit-body { background: rgba(30,39,57,0.72); }
|
||||||
.graph-row:hover .graph-svg path { opacity: 1; stroke-width: 2.65; }
|
.graph-row:hover .graph-svg path { opacity: 1; stroke-width: 2.65; }
|
||||||
.graph-row:hover .graph-svg path.hidden-branch { opacity: 0.12; stroke-width: 2.2; }
|
.graph-row:hover .graph-svg path.hidden-branch { opacity: 0.12; stroke-width: 2.2; }
|
||||||
.graph-row:hover .graph-dot { transform: translate(-50%, -50%) scale(1.12); }
|
.graph-row:hover .graph-dot { transform: translate(-50%, -50%) scale(1.12); }
|
||||||
.graph-row:hover .graph-dot.hidden-branch { transform: translate(-50%, -50%) scale(1); }
|
.graph-row:hover .graph-dot.hidden-branch { transform: translate(-50%, -50%) scale(1); }
|
||||||
.graph-row.merge-row .commit-body {
|
.graph-row.merge-row .commit-body {
|
||||||
background: rgba(36,31,54,0.46);
|
background: rgba(26,27,43,0.56);
|
||||||
}
|
}
|
||||||
.graph-row.tip-row .commit-body {
|
.graph-row.tip-row .commit-body {
|
||||||
background:
|
background:
|
||||||
linear-gradient(90deg, rgba(105,167,255,0.055), transparent 32%),
|
linear-gradient(90deg, rgba(111,140,255,0.065), transparent 34%),
|
||||||
rgba(28,29,48,0.38);
|
rgba(20,27,40,0.62);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Compare panel --- */
|
/* --- Compare panel --- */
|
||||||
@@ -2630,7 +2690,7 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
background-color: #050712;
|
background-color: var(--app-dialog-backdrop);
|
||||||
background-image: none;
|
background-image: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2645,9 +2705,9 @@
|
|||||||
height: min(760px, 100%);
|
height: min(760px, 100%);
|
||||||
border: 1px solid var(--color-border);
|
border: 1px solid var(--color-border);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
background-color: #111321;
|
background-color: var(--app-dialog-bg);
|
||||||
background-image: none;
|
background-image: none;
|
||||||
box-shadow: 0 24px 72px rgba(0, 0, 0, 0.6), 0 2px 12px rgba(0,0,0,0.4);
|
box-shadow: var(--app-dialog-shadow);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.compare-dialog {
|
.compare-dialog {
|
||||||
@@ -2795,6 +2855,56 @@
|
|||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 750;
|
font-weight: 750;
|
||||||
}
|
}
|
||||||
|
.settings-segmented {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 6px;
|
||||||
|
min-width: 0;
|
||||||
|
padding: 4px;
|
||||||
|
border: 1px solid var(--color-border-subtle);
|
||||||
|
border-radius: 8px;
|
||||||
|
background: var(--app-settings-row-bg);
|
||||||
|
}
|
||||||
|
.settings-segmented label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 32px;
|
||||||
|
padding: 0 10px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: var(--color-ink-dim);
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
|
||||||
|
}
|
||||||
|
.settings-segmented label:hover {
|
||||||
|
border-color: var(--color-border-subtle);
|
||||||
|
color: var(--color-ink);
|
||||||
|
background: var(--color-surface-hover);
|
||||||
|
}
|
||||||
|
.settings-segmented label.active {
|
||||||
|
border-color: var(--color-border-input);
|
||||||
|
color: var(--color-ink);
|
||||||
|
background: var(--color-surface-raised);
|
||||||
|
box-shadow: 0 1px 4px rgba(28,44,74,0.08);
|
||||||
|
}
|
||||||
|
.settings-segmented input {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.settings-segmented span {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.settings-toggle-row {
|
.settings-toggle-row {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: auto minmax(0, 1fr);
|
grid-template-columns: auto minmax(0, 1fr);
|
||||||
@@ -2804,7 +2914,7 @@
|
|||||||
padding: 12px;
|
padding: 12px;
|
||||||
border: 1px solid var(--color-border-subtle);
|
border: 1px solid var(--color-border-subtle);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: #151827;
|
background: var(--app-settings-row-bg);
|
||||||
color: var(--color-ink-muted);
|
color: var(--color-ink-muted);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@@ -2970,7 +3080,7 @@
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--color-border-subtle); background: #171a2b; }
|
.dialog-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--color-border-subtle); background: var(--app-dialog-chrome); }
|
||||||
.dialog-header > div:first-child { min-width: 0; }
|
.dialog-header > div:first-child { min-width: 0; }
|
||||||
.dialog-header-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex: 0 0 auto; min-width: 0; }
|
.dialog-header-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex: 0 0 auto; min-width: 0; }
|
||||||
.compare-restore { max-width: 170px; min-width: 0; }
|
.compare-restore { max-width: 170px; min-width: 0; }
|
||||||
@@ -2984,7 +3094,7 @@
|
|||||||
.dialog-body { display: grid; grid-template-columns: 280px minmax(0, 1fr); min-height: 0; }
|
.dialog-body { display: grid; grid-template-columns: 280px minmax(0, 1fr); min-height: 0; }
|
||||||
.compare-dialog .dialog-body { grid-template-columns: minmax(260px, 320px) minmax(0, 1fr); }
|
.compare-dialog .dialog-body { grid-template-columns: minmax(260px, 320px) minmax(0, 1fr); }
|
||||||
|
|
||||||
.dialog-files { display: grid; align-content: start; gap: 4px; padding: 8px; overflow: auto; border-right: 1px solid var(--color-border-subtle); background: #171a2b; }
|
.dialog-files { display: grid; align-content: start; gap: 4px; padding: 8px; overflow: auto; border-right: 1px solid var(--color-border-subtle); background: var(--app-dialog-chrome); }
|
||||||
|
|
||||||
.dialog-file-row {
|
.dialog-file-row {
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -3132,7 +3242,7 @@
|
|||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 16px; border-top: 1px solid var(--color-border-subtle); background: #171a2b; }
|
.dialog-footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 16px; border-top: 1px solid var(--color-border-subtle); background: var(--app-dialog-chrome); }
|
||||||
.dialog-footer-info { color: var(--color-ink-dim); font-size: 13px; font-weight: 700; }
|
.dialog-footer-info { color: var(--color-ink-dim); font-size: 13px; font-weight: 700; }
|
||||||
|
|
||||||
.prepared-tag { display: inline-flex; align-items: center; gap: 4px; margin-right: auto; color: #4eca76; font-size: 12px; font-weight: 700; }
|
.prepared-tag { display: inline-flex; align-items: center; gap: 4px; margin-right: auto; color: #4eca76; font-size: 12px; font-weight: 700; }
|
||||||
@@ -4178,9 +4288,9 @@
|
|||||||
gap: 6px;
|
gap: 6px;
|
||||||
min-height: 36px;
|
min-height: 36px;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
border: 1px solid rgba(100,108,255,0.78);
|
border: 1px solid rgba(111,140,255,0.72);
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
background: linear-gradient(135deg, #646cff, #bd34fe);
|
background: linear-gradient(135deg, #5f7df2, #238eb4);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@@ -4188,8 +4298,8 @@
|
|||||||
transition: background 0.12s, border-color 0.12s;
|
transition: background 0.12s, border-color 0.12s;
|
||||||
}
|
}
|
||||||
.cred-submit:hover:not(:disabled) {
|
.cred-submit:hover:not(:disabled) {
|
||||||
background: linear-gradient(135deg, #747bff, #c966ff);
|
background: linear-gradient(135deg, #6f8cff, #2da0c7);
|
||||||
border-color: rgba(65,209,255,0.7);
|
border-color: rgba(77,182,214,0.7);
|
||||||
}
|
}
|
||||||
.cred-submit:disabled { opacity: 0.45; cursor: not-allowed; }
|
.cred-submit:disabled { opacity: 0.45; cursor: not-allowed; }
|
||||||
|
|
||||||
@@ -4388,6 +4498,381 @@
|
|||||||
.resolve-path { overflow: hidden; color: var(--color-ink-faint); font-family: var(--font-mono); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
|
.resolve-path { overflow: hidden; color: var(--color-ink-faint); font-family: var(--font-mono); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] button:hover:not(:disabled) {
|
||||||
|
background: var(--color-surface-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] input:focus,
|
||||||
|
:root[data-theme="light"] textarea:focus,
|
||||||
|
:root[data-theme="light"] select:focus {
|
||||||
|
box-shadow: 0 0 0 3px rgba(49, 95, 214, 0.14), 0 10px 24px rgba(28, 44, 74, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .btn-primary {
|
||||||
|
border-color: rgba(49, 95, 214, 0.72);
|
||||||
|
background: linear-gradient(135deg, #315fd6 0%, #0f8fb5 100%);
|
||||||
|
box-shadow: 0 10px 24px rgba(49, 95, 214, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .btn-primary:hover:not(:disabled) {
|
||||||
|
border-color: rgba(15, 143, 181, 0.72);
|
||||||
|
background: linear-gradient(135deg, #3d6ee4 0%, #139dc7 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .btn-secondary {
|
||||||
|
border-color: rgba(15, 143, 181, 0.28);
|
||||||
|
color: #0c6683;
|
||||||
|
background: linear-gradient(180deg, rgba(15, 143, 181, 0.08), rgba(49, 95, 214, 0.06));
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .btn-secondary:hover:not(:disabled) {
|
||||||
|
color: #0d4f9e;
|
||||||
|
background: linear-gradient(180deg, rgba(15, 143, 181, 0.13), rgba(49, 95, 214, 0.1));
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .titlebar {
|
||||||
|
background:
|
||||||
|
linear-gradient(90deg, rgba(49, 95, 214, 0.08), rgba(15, 143, 181, 0.05), rgba(214, 156, 49, 0.04)),
|
||||||
|
var(--color-bar);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .titlebar-brand,
|
||||||
|
:root[data-theme="light"] .titlebar-right {
|
||||||
|
border-color: rgba(34,49,78,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .titlebar-brand-icon img {
|
||||||
|
filter: drop-shadow(0 1px 2px rgba(28,44,74,0.18));
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .tb-version {
|
||||||
|
color: rgba(23,32,51,0.36);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .titlebar-info svg {
|
||||||
|
color: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .tb-repo,
|
||||||
|
:root[data-theme="light"] .tb-no-repo {
|
||||||
|
color: var(--color-bar-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .tb-sep {
|
||||||
|
color: rgba(23,32,51,0.28);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .tb-branch {
|
||||||
|
color: var(--color-bar-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .tb-action:hover:not(:disabled),
|
||||||
|
:root[data-theme="light"] .tb-btn:hover:not(:disabled) {
|
||||||
|
background: rgba(49,95,214,0.08);
|
||||||
|
color: var(--color-ink);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .titlebar-divider {
|
||||||
|
background: rgba(34,49,78,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .tb-btn {
|
||||||
|
color: var(--color-bar-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .topbar {
|
||||||
|
border-color: var(--color-border);
|
||||||
|
background:
|
||||||
|
linear-gradient(90deg, rgba(49,95,214,0.06), rgba(15,143,181,0.045), rgba(214,156,49,0.035)),
|
||||||
|
var(--color-surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .repo-tabbar,
|
||||||
|
:root[data-theme="light"] .repo-management-tools {
|
||||||
|
background: rgba(255,255,255,0.78);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .repo-tab-wrap {
|
||||||
|
background: rgba(244,247,252,0.72);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .repo-tab-wrap.active {
|
||||||
|
background: rgba(49,95,214,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .repo-row {
|
||||||
|
border-bottom-color: rgba(34,49,78,0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .repo-row-main:hover:not(:disabled) {
|
||||||
|
background: rgba(49,95,214,0.07);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .repo-row-icon {
|
||||||
|
border-left-color: rgba(34,49,78,0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .notice.error,
|
||||||
|
:root[data-theme="light"] .cred-error {
|
||||||
|
color: #b33445;
|
||||||
|
background: rgba(210, 55, 75, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .notice.busy {
|
||||||
|
color: #315fd6;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .notice.conflict,
|
||||||
|
:root[data-theme="light"] .notice-action.conflict,
|
||||||
|
:root[data-theme="light"] .resolve-status,
|
||||||
|
:root[data-theme="light"] .resolve-conflict-label {
|
||||||
|
color: #96620f;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .notice.rebase,
|
||||||
|
:root[data-theme="light"] .notice-action.rebase {
|
||||||
|
color: #6f3ca8;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .update-toast {
|
||||||
|
box-shadow: 0 22px 56px rgba(28,44,74,0.18), 0 0 0 1px rgba(255,255,255,0.75) inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .branch-filter-backdrop {
|
||||||
|
background: rgba(232,238,248,0.96);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .branch-filter-dialog {
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, #ffffff 0%, #f4f7fc 72%),
|
||||||
|
#f4f7fc;
|
||||||
|
box-shadow: var(--app-dialog-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .graph-branch-dialog-button,
|
||||||
|
:root[data-theme="light"] .branch-filter-option {
|
||||||
|
color: #16723b;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .graph-branch-dialog-button span {
|
||||||
|
color: #ffffff;
|
||||||
|
background: #22834a;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .main-panel {
|
||||||
|
background: var(--color-surface);
|
||||||
|
box-shadow: var(--app-panel-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .repo-management {
|
||||||
|
background: var(--color-surface);
|
||||||
|
box-shadow: var(--app-panel-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .repo-section {
|
||||||
|
background: rgba(255,255,255,0.62);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .repo-section > header {
|
||||||
|
background: rgba(244,247,252,0.88);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .repo-empty {
|
||||||
|
background: rgba(255,255,255,0.48);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .repo-summary,
|
||||||
|
:root[data-theme="light"] .lane-header,
|
||||||
|
:root[data-theme="light"] .stash-toolbar,
|
||||||
|
:root[data-theme="light"] .dialog-footer,
|
||||||
|
:root[data-theme="light"] .cred-header {
|
||||||
|
background: var(--color-surface-dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .file-row.selected,
|
||||||
|
:root[data-theme="light"] .branch-row.current,
|
||||||
|
:root[data-theme="light"] .file-history-row.active {
|
||||||
|
background: rgba(49,95,214,0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .graph-list {
|
||||||
|
background: rgba(248,250,253,0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .graph-gutter {
|
||||||
|
border-right-color: rgba(34,49,78,0.1);
|
||||||
|
background:
|
||||||
|
linear-gradient(90deg, rgba(49,95,214,0.035), rgba(255,255,255,0.18)),
|
||||||
|
rgba(238,243,249,0.78);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .graph-dot {
|
||||||
|
border-color: #ffffff;
|
||||||
|
box-shadow: 0 0 0 1px rgba(34,49,78,0.16), 0 2px 6px rgba(28,44,74,0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .graph-dot.merge {
|
||||||
|
background: #ffffff;
|
||||||
|
box-shadow: 0 0 0 1px rgba(34,49,78,0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .commit-body {
|
||||||
|
background: rgba(255,255,255,0.72);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .graph-row + .graph-row .commit-body {
|
||||||
|
border-top-color: rgba(34,49,78,0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .graph-row:hover .commit-body {
|
||||||
|
background: rgba(235,241,250,0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .graph-row.merge-row .commit-body {
|
||||||
|
background: rgba(248,244,252,0.82);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .graph-row.tip-row .commit-body {
|
||||||
|
background:
|
||||||
|
linear-gradient(90deg, rgba(49,95,214,0.075), transparent 34%),
|
||||||
|
rgba(255,255,255,0.82);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .commit-summary {
|
||||||
|
color: var(--color-ink);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .commit-avatar {
|
||||||
|
border-color: rgba(49,95,214,0.18);
|
||||||
|
color: #315fd6;
|
||||||
|
background: rgba(232,238,248,0.92);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .commit-kind {
|
||||||
|
background: rgba(244,247,252,0.82);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .commit-hash {
|
||||||
|
color: #315fd6;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .commit-branch-chip,
|
||||||
|
:root[data-theme="light"] .graph-hover-branches span {
|
||||||
|
border-color: rgba(31,128,76,0.22);
|
||||||
|
color: #146b3b;
|
||||||
|
background: rgba(224,246,233,0.92);
|
||||||
|
box-shadow: 0 8px 22px rgba(28,44,74,0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .graph-hover-branches span.remote,
|
||||||
|
:root[data-theme="light"] .branch-filter-option.remote {
|
||||||
|
border-color: rgba(49,95,214,0.22);
|
||||||
|
color: #315fd6;
|
||||||
|
background: rgba(231,237,255,0.92);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .graph-hover-branches span.ahead {
|
||||||
|
border-color: rgba(150,98,15,0.28);
|
||||||
|
color: #96620f;
|
||||||
|
background: rgba(255,244,224,0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .graph-hover-branches span.behind {
|
||||||
|
border-color: rgba(49,95,214,0.26);
|
||||||
|
color: #315fd6;
|
||||||
|
background: rgba(231,237,255,0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .ref-list .ref-chip.head {
|
||||||
|
color: #ffffff;
|
||||||
|
background: linear-gradient(135deg, #0f8fb5, #315fd6);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .ref-list .ref-chip.branch {
|
||||||
|
color: #16723b;
|
||||||
|
background: rgba(78,202,118,0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .ref-list .ref-chip.remote {
|
||||||
|
color: #315fd6;
|
||||||
|
background: rgba(49,95,214,0.09);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .commit-files,
|
||||||
|
:root[data-theme="light"] .commit-file-button {
|
||||||
|
background: rgba(248,250,253,0.78);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .file-history-rail-toggle {
|
||||||
|
background: linear-gradient(180deg, rgba(49,95,214,0.08), rgba(15,143,181,0.04));
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .file-history-rail-toggle:hover:not(:disabled) {
|
||||||
|
background: linear-gradient(180deg, rgba(49,95,214,0.12), rgba(15,143,181,0.08));
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .file-history-loading {
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at center 42%, rgba(49,95,214,0.1), transparent 52%),
|
||||||
|
linear-gradient(180deg, rgba(244,247,252,0.88), transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .file-history-loading-icon {
|
||||||
|
filter:
|
||||||
|
drop-shadow(0 10px 14px rgba(28,44,74,0.18))
|
||||||
|
drop-shadow(0 0 12px rgba(49,95,214,0.18));
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .branch-context-menu {
|
||||||
|
box-shadow: 0 18px 50px rgba(28,44,74,0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .dialog-file-row:hover,
|
||||||
|
:root[data-theme="light"] .branch-row:hover,
|
||||||
|
:root[data-theme="light"] .explorer-row:hover,
|
||||||
|
:root[data-theme="light"] .commit-files-toggle:hover:not(:disabled) {
|
||||||
|
background: var(--color-surface-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .split-span.split-meta {
|
||||||
|
background: #e9eef7;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .resolve-split,
|
||||||
|
:root[data-theme="light"] .resolve-num,
|
||||||
|
:root[data-theme="light"] .resolve-cell.empty,
|
||||||
|
:root[data-theme="light"] .resolve-num.empty {
|
||||||
|
background: rgba(234,239,248,0.72);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .diff-line.meta,
|
||||||
|
:root[data-theme="light"] .resolve-split-marker {
|
||||||
|
color: #64728a;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .cred-input input,
|
||||||
|
:root[data-theme="light"] .cred-expiry input[type="date"] {
|
||||||
|
background: rgba(255,255,255,0.92);
|
||||||
|
color-scheme: light;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .cred-token-hint code {
|
||||||
|
color: #0d78a0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .status-panel-overlay {
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 50% 38%, rgba(49, 95, 214, 0.12), transparent 55%),
|
||||||
|
rgba(244, 247, 252, 0.68);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] .status-panel-overlay-card {
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(255,255,255,0.96), rgba(244,247,252,0.94)),
|
||||||
|
var(--color-surface-raised);
|
||||||
|
box-shadow: 0 18px 44px rgba(28,44,74,0.16), inset 0 1px 0 rgba(255,255,255,0.9);
|
||||||
|
}
|
||||||
|
|
||||||
/* Custom tooltip — appended to body, not clipped by overflow:hidden parents */
|
/* Custom tooltip — appended to body, not clipped by overflow:hidden parents */
|
||||||
.path-tooltip {
|
.path-tooltip {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -4476,6 +4961,10 @@
|
|||||||
@media (max-width: 740px) {
|
@media (max-width: 740px) {
|
||||||
body { overflow: auto; }
|
body { overflow: auto; }
|
||||||
.shell-body { min-height: 100%; gap: 6px; }
|
.shell-body { min-height: 100%; gap: 6px; }
|
||||||
|
.titlebar-info { padding: 0 8px; }
|
||||||
|
.titlebar-actions .tb-action:not(.auto-toggle):not(:last-child) { display: none; }
|
||||||
|
.tb-action { width: 36px; padding: 0 8px; }
|
||||||
|
.tb-btn { width: 34px; }
|
||||||
.workspace { grid-template-columns: 1fr; gap: 6px; }
|
.workspace { grid-template-columns: 1fr; gap: 6px; }
|
||||||
.left-sidebar-resize-handle { display: none; }
|
.left-sidebar-resize-handle { display: none; }
|
||||||
.history-aside { grid-template-columns: 1fr; grid-template-rows: minmax(200px, 1fr) minmax(150px, 0.5fr); min-height: 380px; }
|
.history-aside { grid-template-columns: 1fr; grid-template-rows: minmax(200px, 1fr) minmax(150px, 0.5fr); min-height: 380px; }
|
||||||
|
|||||||
+27
-5
@@ -24,22 +24,44 @@
|
|||||||
export let onToggleAutoRefresh: () => void = () => {};
|
export let onToggleAutoRefresh: () => void = () => {};
|
||||||
export let onOpenSettings: () => void = () => {};
|
export let onOpenSettings: () => void = () => {};
|
||||||
|
|
||||||
const win = getCurrentWindow();
|
let win: ReturnType<typeof getCurrentWindow> | null = null;
|
||||||
let isMaximized = false;
|
let isMaximized = false;
|
||||||
let unlisten: (() => void) | undefined;
|
let unlisten: (() => void) | undefined;
|
||||||
let appVersion = "";
|
let appVersion = "";
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
|
try {
|
||||||
|
win = getCurrentWindow();
|
||||||
isMaximized = await win.isMaximized();
|
isMaximized = await win.isMaximized();
|
||||||
unlisten = await win.onResized(async () => {
|
unlisten = await win.onResized(async () => {
|
||||||
isMaximized = await win.isMaximized();
|
isMaximized = await win?.isMaximized() ?? false;
|
||||||
});
|
});
|
||||||
|
} catch {
|
||||||
|
win = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
appVersion = await getVersion();
|
appVersion = await getVersion();
|
||||||
|
} catch {
|
||||||
|
appVersion = "";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
unlisten?.();
|
unlisten?.();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function minimizeWindow() {
|
||||||
|
void win?.minimize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleMaximizeWindow() {
|
||||||
|
void win?.toggleMaximize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeWindow() {
|
||||||
|
void win?.close();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<header class="titlebar" data-tauri-drag-region>
|
<header class="titlebar" data-tauri-drag-region>
|
||||||
@@ -200,12 +222,12 @@
|
|||||||
<div class="titlebar-divider" aria-hidden="true"></div>
|
<div class="titlebar-divider" aria-hidden="true"></div>
|
||||||
|
|
||||||
<div class="titlebar-controls">
|
<div class="titlebar-controls">
|
||||||
<button class="tb-btn" onclick={() => win.minimize()} title="Minimize" aria-label="Minimize">
|
<button class="tb-btn" onclick={minimizeWindow} title="Minimize" aria-label="Minimize">
|
||||||
<Minus size={12} aria-hidden="true" />
|
<Minus size={12} aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="tb-btn"
|
class="tb-btn"
|
||||||
onclick={() => win.toggleMaximize()}
|
onclick={toggleMaximizeWindow}
|
||||||
title={isMaximized ? "Restore" : "Maximize"}
|
title={isMaximized ? "Restore" : "Maximize"}
|
||||||
aria-label={isMaximized ? "Restore" : "Maximize"}
|
aria-label={isMaximized ? "Restore" : "Maximize"}
|
||||||
>
|
>
|
||||||
@@ -220,7 +242,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
<button class="tb-btn close" onclick={() => win.close()} title="Close" aria-label="Close">
|
<button class="tb-btn close" onclick={closeWindow} title="Close" aria-label="Close">
|
||||||
<X size={12} aria-hidden="true" />
|
<X size={12} aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Check, Settings, X } from "@lucide/svelte";
|
import { Check, Settings, X } from "@lucide/svelte";
|
||||||
import type { AnalyticsSettings } from "../types";
|
import type { AnalyticsSettings, AppTheme } from "../types";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
analytics: AnalyticsSettings;
|
analytics: AnalyticsSettings;
|
||||||
onSave: (settings: AnalyticsSettings) => void;
|
theme: AppTheme;
|
||||||
|
onSave: (settings: AnalyticsSettings, theme: AppTheme) => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { analytics, onSave = () => {}, onClose = () => {} }: Props = $props();
|
let { analytics, theme = "system", onSave = () => {}, onClose = () => {} }: Props = $props();
|
||||||
|
|
||||||
let analyticsEnabled = $state(true);
|
let analyticsEnabled = $state(true);
|
||||||
|
let selectedTheme = $state<AppTheme>("system");
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
analyticsEnabled = analytics.enabled;
|
analyticsEnabled = analytics.enabled;
|
||||||
|
selectedTheme = theme;
|
||||||
});
|
});
|
||||||
|
|
||||||
function save() {
|
function save() {
|
||||||
@@ -21,7 +24,7 @@
|
|||||||
...analytics,
|
...analytics,
|
||||||
enabled: analyticsEnabled,
|
enabled: analyticsEnabled,
|
||||||
noticeSeen: true,
|
noticeSeen: true,
|
||||||
});
|
}, selectedTheme);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -38,6 +41,31 @@
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<form class="app-settings-form" onsubmit={(event) => { event.preventDefault(); save(); }}>
|
<form class="app-settings-form" onsubmit={(event) => { event.preventDefault(); save(); }}>
|
||||||
|
<section class="settings-section">
|
||||||
|
<header>
|
||||||
|
<Settings size={16} aria-hidden="true" />
|
||||||
|
<div>
|
||||||
|
<span class="eyebrow">Appearance</span>
|
||||||
|
<h3>Theme</h3>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="settings-segmented" role="radiogroup" aria-label="Theme">
|
||||||
|
<label class:active={selectedTheme === "system"}>
|
||||||
|
<input type="radio" bind:group={selectedTheme} value="system" />
|
||||||
|
<span>System</span>
|
||||||
|
</label>
|
||||||
|
<label class:active={selectedTheme === "light"}>
|
||||||
|
<input type="radio" bind:group={selectedTheme} value="light" />
|
||||||
|
<span>Light</span>
|
||||||
|
</label>
|
||||||
|
<label class:active={selectedTheme === "dark"}>
|
||||||
|
<input type="radio" bind:group={selectedTheme} value="dark" />
|
||||||
|
<span>Dark</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section class="settings-section">
|
<section class="settings-section">
|
||||||
<header>
|
<header>
|
||||||
<Settings size={16} aria-hidden="true" />
|
<Settings size={16} aria-hidden="true" />
|
||||||
|
|||||||
@@ -41,9 +41,7 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background:
|
background: linear-gradient(135deg, #070a10 0%, #0c111a 48%, #090e16 100%);
|
||||||
radial-gradient(circle at 50% 42%, rgba(137, 92, 255, 0.18), transparent 34%),
|
|
||||||
linear-gradient(135deg, #050712 0%, #080b16 46%, #120b18 100%);
|
|
||||||
animation: overlay-in 180ms ease;
|
animation: overlay-in 180ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,8 +50,8 @@
|
|||||||
inset: 0;
|
inset: 0;
|
||||||
opacity: 0.28;
|
opacity: 0.28;
|
||||||
background-image:
|
background-image:
|
||||||
linear-gradient(rgba(151, 118, 255, 0.12) 1px, transparent 1px),
|
linear-gradient(rgba(111, 140, 255, 0.09) 1px, transparent 1px),
|
||||||
linear-gradient(90deg, rgba(255, 109, 38, 0.08) 1px, transparent 1px);
|
linear-gradient(90deg, rgba(77, 182, 214, 0.07) 1px, transparent 1px);
|
||||||
background-size: 42px 42px;
|
background-size: 42px 42px;
|
||||||
mask-image: radial-gradient(circle at center, black 0%, transparent 68%);
|
mask-image: radial-gradient(circle at center, black 0%, transparent 68%);
|
||||||
animation: grid-drift 10s linear infinite;
|
animation: grid-drift 10s linear infinite;
|
||||||
@@ -67,14 +65,14 @@
|
|||||||
gap: 18px;
|
gap: 18px;
|
||||||
width: min(420px, calc(100vw - 42px));
|
width: min(420px, calc(100vw - 42px));
|
||||||
padding: 30px 34px 28px;
|
padding: 30px 34px 28px;
|
||||||
border: 1px solid rgba(160, 124, 255, 0.24);
|
border: 1px solid rgba(90, 111, 154, 0.28);
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
background:
|
background:
|
||||||
linear-gradient(180deg, rgba(23, 26, 43, 0.9), rgba(12, 15, 27, 0.92)),
|
linear-gradient(180deg, rgba(23, 29, 43, 0.92), rgba(12, 17, 27, 0.94)),
|
||||||
var(--color-surface-raised);
|
var(--color-surface-raised);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 26px 90px rgba(0, 0, 0, 0.62),
|
0 26px 78px rgba(0, 0, 0, 0.54),
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.06);
|
inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.repo-loading-mark {
|
.repo-loading-mark {
|
||||||
@@ -89,7 +87,7 @@
|
|||||||
.repo-loading-halo {
|
.repo-loading-halo {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 10px;
|
inset: 10px;
|
||||||
border: 1px solid rgba(151, 118, 255, 0.24);
|
border: 1px solid rgba(111, 140, 255, 0.22);
|
||||||
border-radius: 34px;
|
border-radius: 34px;
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
@@ -98,7 +96,7 @@
|
|||||||
}
|
}
|
||||||
.repo-loading-halo.halo-two {
|
.repo-loading-halo.halo-two {
|
||||||
inset: 24px;
|
inset: 24px;
|
||||||
border-color: rgba(255, 109, 38, 0.26);
|
border-color: rgba(77, 182, 214, 0.24);
|
||||||
animation: halo-breathe 2.4s ease-in-out infinite reverse;
|
animation: halo-breathe 2.4s ease-in-out infinite reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,18 +114,18 @@
|
|||||||
stroke-linecap: round;
|
stroke-linecap: round;
|
||||||
stroke-dasharray: 165;
|
stroke-dasharray: 165;
|
||||||
stroke-dashoffset: 165;
|
stroke-dashoffset: 165;
|
||||||
filter: drop-shadow(0 0 8px rgba(151, 118, 255, 0.55));
|
filter: drop-shadow(0 0 8px rgba(77, 182, 214, 0.32));
|
||||||
animation: trace-draw 2.6s ease-in-out infinite;
|
animation: trace-draw 2.6s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
.repo-loading-traces .trace-main {
|
.repo-loading-traces .trace-main {
|
||||||
stroke: #9b70ff;
|
stroke: #6f8cff;
|
||||||
}
|
}
|
||||||
.repo-loading-traces .trace-branch {
|
.repo-loading-traces .trace-branch {
|
||||||
stroke: #ff6d26;
|
stroke: #4db6d6;
|
||||||
animation-delay: 0.28s;
|
animation-delay: 0.28s;
|
||||||
}
|
}
|
||||||
.repo-loading-traces .trace-cut {
|
.repo-loading-traces .trace-cut {
|
||||||
stroke: rgba(255, 255, 255, 0.42);
|
stroke: rgba(177, 186, 208, 0.42);
|
||||||
stroke-dasharray: 128;
|
stroke-dasharray: 128;
|
||||||
stroke-dashoffset: 128;
|
stroke-dashoffset: 128;
|
||||||
animation-delay: 0.55s;
|
animation-delay: 0.55s;
|
||||||
@@ -141,7 +139,7 @@
|
|||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
filter:
|
filter:
|
||||||
drop-shadow(0 18px 24px rgba(0, 0, 0, 0.55))
|
drop-shadow(0 18px 24px rgba(0, 0, 0, 0.55))
|
||||||
drop-shadow(0 0 18px rgba(151, 118, 255, 0.28));
|
drop-shadow(0 0 18px rgba(77, 182, 214, 0.2));
|
||||||
animation: icon-float 2.4s ease-in-out infinite;
|
animation: icon-float 2.4s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,18 +173,59 @@
|
|||||||
height: 4px;
|
height: 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
background: rgba(151, 118, 255, 0.14);
|
background: rgba(111, 140, 255, 0.14);
|
||||||
}
|
}
|
||||||
.repo-loading-bar span {
|
.repo-loading-bar span {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
width: 46%;
|
width: 46%;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
background: linear-gradient(90deg, transparent, #9b70ff 40%, #ff6d26 74%, transparent);
|
background: linear-gradient(90deg, transparent, #6f8cff 40%, #4db6d6 74%, transparent);
|
||||||
box-shadow: 0 0 16px rgba(255, 109, 38, 0.32);
|
box-shadow: 0 0 16px rgba(77, 182, 214, 0.26);
|
||||||
animation: bar-slide 1.35s ease-in-out infinite;
|
animation: bar-slide 1.35s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(:root[data-theme="light"]) .repo-loading {
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 50% 42%, rgba(49, 95, 214, 0.12), transparent 34%),
|
||||||
|
linear-gradient(135deg, #f7f9fd 0%, #eef3f9 48%, #f8fafc 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(:root[data-theme="light"]) .repo-loading-grid {
|
||||||
|
opacity: 0.38;
|
||||||
|
background-image:
|
||||||
|
linear-gradient(rgba(49, 95, 214, 0.1) 1px, transparent 1px),
|
||||||
|
linear-gradient(90deg, rgba(15, 143, 181, 0.08) 1px, transparent 1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(:root[data-theme="light"]) .repo-loading-card {
|
||||||
|
border-color: rgba(61, 89, 142, 0.2);
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(255,255,255,0.96), rgba(244,247,252,0.94)),
|
||||||
|
var(--color-surface-raised);
|
||||||
|
box-shadow:
|
||||||
|
0 26px 72px rgba(28,44,74,0.18),
|
||||||
|
inset 0 1px 0 rgba(255,255,255,0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(:root[data-theme="light"]) .repo-loading-traces .trace {
|
||||||
|
filter: drop-shadow(0 0 8px rgba(49,95,214,0.22));
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(:root[data-theme="light"]) .repo-loading-traces .trace-cut {
|
||||||
|
stroke: rgba(49,95,214,0.34);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(:root[data-theme="light"]) .repo-loading-icon {
|
||||||
|
filter:
|
||||||
|
drop-shadow(0 18px 24px rgba(28,44,74,0.2))
|
||||||
|
drop-shadow(0 0 18px rgba(49,95,214,0.18));
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(:root[data-theme="light"]) .repo-loading-bar {
|
||||||
|
background: rgba(49,95,214,0.12);
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes overlay-in { from { opacity: 0; } to { opacity: 1; } }
|
@keyframes overlay-in { from { opacity: 0; } to { opacity: 1; } }
|
||||||
@keyframes grid-drift { to { transform: translate3d(42px, 42px, 0); } }
|
@keyframes grid-drift { to { transform: translate3d(42px, 42px, 0); } }
|
||||||
@keyframes icon-float {
|
@keyframes icon-float {
|
||||||
|
|||||||
@@ -347,8 +347,8 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle at 50% 38%, rgba(137, 92, 255, 0.16), transparent 55%),
|
radial-gradient(circle at 50% 38%, rgba(111, 140, 255, 0.1), transparent 55%),
|
||||||
rgba(8, 9, 16, 0.58);
|
rgba(7, 10, 16, 0.62);
|
||||||
backdrop-filter: blur(4px);
|
backdrop-filter: blur(4px);
|
||||||
animation: status-panel-overlay-in 120ms ease;
|
animation: status-panel-overlay-in 120ms ease;
|
||||||
}
|
}
|
||||||
@@ -360,13 +360,13 @@
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
width: min(300px, calc(100% - 32px));
|
width: min(300px, calc(100% - 32px));
|
||||||
padding: 26px 28px 26px;
|
padding: 26px 28px 26px;
|
||||||
border: 1px solid rgba(160, 124, 255, 0.24);
|
border: 1px solid rgba(90, 111, 154, 0.28);
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
background:
|
background:
|
||||||
linear-gradient(180deg, rgba(23, 26, 43, 0.9), rgba(12, 15, 27, 0.92)),
|
linear-gradient(180deg, rgba(23, 29, 43, 0.92), rgba(12, 17, 27, 0.94)),
|
||||||
var(--color-surface-raised);
|
var(--color-surface-raised);
|
||||||
color: var(--color-ink);
|
color: var(--color-ink);
|
||||||
box-shadow: 0 18px 44px rgba(0, 0, 0, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.06);
|
box-shadow: 0 18px 44px rgba(0, 0, 0, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-panel-overlay-mark {
|
.status-panel-overlay-mark {
|
||||||
@@ -381,7 +381,7 @@
|
|||||||
.status-panel-overlay-halo {
|
.status-panel-overlay-halo {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 6px;
|
inset: 6px;
|
||||||
border: 1px solid rgba(151, 118, 255, 0.24);
|
border: 1px solid rgba(111, 140, 255, 0.22);
|
||||||
border-radius: 22px;
|
border-radius: 22px;
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
@@ -390,7 +390,7 @@
|
|||||||
}
|
}
|
||||||
.status-panel-overlay-halo.halo-two {
|
.status-panel-overlay-halo.halo-two {
|
||||||
inset: 16px;
|
inset: 16px;
|
||||||
border-color: rgba(255, 109, 38, 0.26);
|
border-color: rgba(77, 182, 214, 0.24);
|
||||||
animation: status-panel-overlay-halo-breathe 2.4s ease-in-out infinite reverse;
|
animation: status-panel-overlay-halo-breathe 2.4s ease-in-out infinite reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,16 +408,16 @@
|
|||||||
stroke-linecap: round;
|
stroke-linecap: round;
|
||||||
stroke-dasharray: 165;
|
stroke-dasharray: 165;
|
||||||
stroke-dashoffset: 165;
|
stroke-dashoffset: 165;
|
||||||
filter: drop-shadow(0 0 6px rgba(151, 118, 255, 0.55));
|
filter: drop-shadow(0 0 6px rgba(77, 182, 214, 0.32));
|
||||||
animation: status-panel-overlay-trace-draw 2.6s ease-in-out infinite;
|
animation: status-panel-overlay-trace-draw 2.6s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
.status-panel-overlay-traces .trace-main { stroke: #9b70ff; }
|
.status-panel-overlay-traces .trace-main { stroke: #6f8cff; }
|
||||||
.status-panel-overlay-traces .trace-branch {
|
.status-panel-overlay-traces .trace-branch {
|
||||||
stroke: #ff6d26;
|
stroke: #4db6d6;
|
||||||
animation-delay: 0.28s;
|
animation-delay: 0.28s;
|
||||||
}
|
}
|
||||||
.status-panel-overlay-traces .trace-cut {
|
.status-panel-overlay-traces .trace-cut {
|
||||||
stroke: rgba(255, 255, 255, 0.42);
|
stroke: rgba(177, 186, 208, 0.42);
|
||||||
stroke-dasharray: 128;
|
stroke-dasharray: 128;
|
||||||
stroke-dashoffset: 128;
|
stroke-dashoffset: 128;
|
||||||
animation-delay: 0.55s;
|
animation-delay: 0.55s;
|
||||||
@@ -431,7 +431,7 @@
|
|||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
filter:
|
filter:
|
||||||
drop-shadow(0 8px 12px rgba(0, 0, 0, 0.5))
|
drop-shadow(0 8px 12px rgba(0, 0, 0, 0.5))
|
||||||
drop-shadow(0 0 10px rgba(151, 118, 255, 0.28));
|
drop-shadow(0 0 10px rgba(77, 182, 214, 0.2));
|
||||||
animation: status-panel-overlay-icon-float 2.4s ease-in-out infinite;
|
animation: status-panel-overlay-icon-float 2.4s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,15 +452,15 @@
|
|||||||
height: 4px;
|
height: 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
background: rgba(151, 118, 255, 0.14);
|
background: rgba(111, 140, 255, 0.14);
|
||||||
}
|
}
|
||||||
.status-panel-overlay-bar span {
|
.status-panel-overlay-bar span {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
width: 46%;
|
width: 46%;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
background: linear-gradient(90deg, transparent, #9b70ff 40%, #ff6d26 74%, transparent);
|
background: linear-gradient(90deg, transparent, #6f8cff 40%, #4db6d6 74%, transparent);
|
||||||
box-shadow: 0 0 12px rgba(255, 109, 38, 0.32);
|
box-shadow: 0 0 12px rgba(77, 182, 214, 0.26);
|
||||||
animation: status-panel-overlay-bar-slide 1.35s ease-in-out infinite;
|
animation: status-panel-overlay-bar-slide 1.35s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export type FileStatusKind =
|
|||||||
export type CommitAiPhase = "idle" | "loading" | "ready" | "error";
|
export type CommitAiPhase = "idle" | "loading" | "ready" | "error";
|
||||||
export type CommitAiProvider = "local" | "openai" | "anthropic" | "custom";
|
export type CommitAiProvider = "local" | "openai" | "anthropic" | "custom";
|
||||||
export type CommitAiLocalProfile = "fast" | "balanced" | "detailed";
|
export type CommitAiLocalProfile = "fast" | "balanced" | "detailed";
|
||||||
|
export type AppTheme = "system" | "light" | "dark";
|
||||||
|
|
||||||
export interface CommitAiStatus {
|
export interface CommitAiStatus {
|
||||||
phase: CommitAiPhase;
|
phase: CommitAiPhase;
|
||||||
|
|||||||
+17
@@ -3,12 +3,29 @@ import { mount } from "svelte";
|
|||||||
import App from "./App.svelte";
|
import App from "./App.svelte";
|
||||||
import "./app.css";
|
import "./app.css";
|
||||||
|
|
||||||
|
const THEME_KEY = "gitlite.theme.v1";
|
||||||
const target = document.getElementById("app");
|
const target = document.getElementById("app");
|
||||||
|
|
||||||
if (!target) {
|
if (!target) {
|
||||||
throw new Error("App target element was not found.");
|
throw new Error("App target element was not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const storedTheme = localStorage.getItem(THEME_KEY);
|
||||||
|
const preference = storedTheme === "light" || storedTheme === "dark" || storedTheme === "system"
|
||||||
|
? storedTheme
|
||||||
|
: "system";
|
||||||
|
const resolved = preference === "system" && window.matchMedia("(prefers-color-scheme: light)").matches
|
||||||
|
? "light"
|
||||||
|
: preference === "system"
|
||||||
|
? "dark"
|
||||||
|
: preference;
|
||||||
|
document.documentElement.dataset.themePreference = preference;
|
||||||
|
document.documentElement.dataset.theme = resolved;
|
||||||
|
} catch {
|
||||||
|
// Storage is best-effort; the CSS system theme fallback still applies.
|
||||||
|
}
|
||||||
|
|
||||||
const app = mount(App, { target });
|
const app = mount(App, { target });
|
||||||
|
|
||||||
export default app;
|
export default app;
|
||||||
|
|||||||
Reference in New Issue
Block a user