diff --git a/main.js b/main.js
index 759b1ac..6600577 100644
--- a/main.js
+++ b/main.js
@@ -539,9 +539,11 @@ function createWindow(startUrl, bigPictureMode = false) {
transparent: true,
});
} else if (process.platform === 'win32') {
+ // Use frameless window on Windows with custom title bar controls
+ // rendered in the tab strip area (Firefox-style).
Object.assign(windowOptions, {
- frame: true, // Use default Windows title bar.
- // removed titleBarOverlay to restore native Windows controls.
+ frame: false,
+ backgroundColor: '#0b0d10',
});
} else {
windowOptions.frame = true;
@@ -932,6 +934,9 @@ ipcMain.handle('window-maximize', event => {
ipcMain.handle('window-close', event => {
BrowserWindow.fromWebContents(event.sender).close();
});
+ipcMain.handle('window-is-maximized', event => {
+ return BrowserWindow.fromWebContents(event.sender).isMaximized();
+});
// Add site and search history IPC handlers
// Site history is now handled via localStorage in the renderer
diff --git a/renderer/home.css b/renderer/home.css
index 9b1d31d..a407812 100644
--- a/renderer/home.css
+++ b/renderer/home.css
@@ -49,14 +49,14 @@ body, html {
padding: 4rem 2rem 2rem;
}
-.edit-btn { position: fixed; top: 16px; right: 16px; z-index: 5; background: rgba(255,255,255,0.1); color:#fff; border:1px solid rgba(255,255,255,0.2); border-radius:8px; padding:6px 10px; cursor:pointer; backdrop-filter: blur(6px); }
-.edit-btn[aria-pressed="true"] { background: rgba(255,255,255,0.22); }
+.edit-btn { position: fixed; top: 16px; right: 16px; z-index: 5; background: color-mix(in srgb, var(--text) 10%, transparent); color: var(--text); border:1px solid color-mix(in srgb, var(--text) 20%, transparent); border-radius:8px; padding:6px 10px; cursor:pointer; backdrop-filter: blur(6px); }
+.edit-btn[aria-pressed="true"] { background: color-mix(in srgb, var(--text) 22%, transparent); }
.edit-mode .edit-btn { display:none; }
-.edit-mode .greeting-title, .edit-mode .search-container, .edit-mode .top-sites-card, .edit-mode .glance { outline: 2px dashed rgba(255,255,255,0.35); outline-offset: 4px; cursor: grab; }
+.edit-mode .greeting-title, .edit-mode .search-container, .edit-mode .top-sites-card, .edit-mode .glance { outline: 2px dashed color-mix(in srgb, var(--text) 35%, transparent); outline-offset: 4px; cursor: grab; }
.edit-mode .glance.dragging { cursor: grabbing; }
/* Edit toolbar */
-.edit-toolbar { position: fixed; top: 16px; right: 16px; display:none; gap:10px; z-index:6; backdrop-filter: blur(8px); background: rgba(8,10,16,0.5); border:1px solid rgba(255,255,255,0.15); padding:8px 10px; border-radius:12px; box-shadow: 0 12px 30px -14px rgba(0,0,0,.7); }
+.edit-toolbar { position: fixed; top: 16px; right: 16px; display:none; gap:10px; z-index:6; backdrop-filter: blur(8px); background: color-mix(in srgb, var(--bg) 50%, transparent); border:1px solid color-mix(in srgb, var(--text) 15%, transparent); padding:8px 10px; border-radius:12px; box-shadow: 0 12px 30px -14px color-mix(in srgb, var(--bg) 70%, transparent); }
.edit-mode .edit-toolbar { display:flex; }
.edit-toolbar[hidden] { display: none !important; }
@@ -65,17 +65,17 @@ body, html {
.edit-btn.pos-bl, .edit-toolbar.pos-bl { left:16px; bottom:16px; right:auto; top:auto; }
.edit-btn.pos-tr, .edit-toolbar.pos-tr { right:16px; top:16px; left:auto; bottom:auto; }
.edit-btn.pos-tl, .edit-toolbar.pos-tl { left:16px; top:16px; right:auto; bottom:auto; }
-.edit-toolbar .btn { min-width:90px; padding:8px 12px; border-radius:8px; border:1px solid transparent; color:#fff; cursor:pointer; }
+.edit-toolbar .btn { min-width:90px; padding:8px 12px; border-radius:8px; border:1px solid transparent; color: var(--text); cursor:pointer; }
.edit-toolbar .btn.primary { background: linear-gradient(135deg, var(--accent), var(--primary)); }
-.edit-toolbar .btn.secondary { background: rgba(255,255,255,0.14); border-color: rgba(255,255,255,0.2); }
+.edit-toolbar .btn.secondary { background: color-mix(in srgb, var(--text) 14%, transparent); border-color: color-mix(in srgb, var(--text) 20%, transparent); }
/* Greeting hero title */
.greeting-title {
font-size: clamp(2rem, 5vw, 3.5rem);
font-weight: 700;
letter-spacing: 0.3px;
- color: #cfd4ff;
- text-shadow: 0 4px 22px rgba(0,0,0,0.6);
+ color: var(--text);
+ text-shadow: 0 4px 22px color-mix(in srgb, var(--bg) 60%, transparent);
margin-bottom: 1.25rem;
position: relative;
top: var(--home-greeting-y);
@@ -119,14 +119,10 @@ body, html {
z-index: 300; /* ensure dropdown overlays bookmarks/top-sites stacking contexts */
top: var(--home-search-y);
/* Unified glassy pill */
- background: linear-gradient(
- 180deg,
- rgba(255,255,255,0.14),
- rgba(255,255,255,0.10)
- );
- border: 1px solid rgba(255,255,255,0.20);
+ background: color-mix(in srgb, var(--text) 12%, transparent);
+ border: 1px solid color-mix(in srgb, var(--text) 20%, transparent);
border-radius: 9999px;
- box-shadow: 0 18px 50px -22px rgba(0,0,0,0.8), inset 0 1px 0 rgba(255,255,255,0.12);
+ box-shadow: 0 18px 50px -22px color-mix(in srgb, var(--bg) 80%, transparent), inset 0 1px 0 color-mix(in srgb, var(--text) 12%, transparent);
backdrop-filter: blur(10px) saturate(140%);
-webkit-backdrop-filter: blur(10px) saturate(140%);
padding: 6px 8px;
@@ -134,13 +130,13 @@ body, html {
}
.search-container:hover {
- background: linear-gradient(180deg, rgba(255,255,255,0.18), rgba(255,255,255,0.12));
- border-color: rgba(255,255,255,0.28);
+ background: color-mix(in srgb, var(--text) 16%, transparent);
+ border-color: color-mix(in srgb, var(--text) 28%, transparent);
}
.search-container:focus-within {
- box-shadow: 0 22px 60px -24px rgba(0,0,0,0.9), 0 0 0 2px rgba(123,46,255,0.45), inset 0 1px 0 rgba(255,255,255,0.16);
- border-color: rgba(123,46,255,0.55);
+ box-shadow: 0 22px 60px -24px color-mix(in srgb, var(--bg) 90%, transparent), 0 0 0 2px color-mix(in srgb, var(--primary) 45%, transparent), inset 0 1px 0 color-mix(in srgb, var(--text) 16%, transparent);
+ border-color: color-mix(in srgb, var(--primary) 55%, transparent);
}
/* Search bar */
@@ -161,18 +157,18 @@ body, html {
padding: 0 10px 0 8px;
font-size: 1.05rem;
line-height: 1;
- color: #ffffff;
+ color: var(--text);
caret-color: var(--accent);
}
.search-bar input.search-input::placeholder {
- color: rgba(255,255,255,0.55);
+ color: color-mix(in srgb, var(--text) 55%, transparent);
}
.search-bar button.search-btn {
- border: 1px solid rgba(255,255,255,0.14);
- background: rgba(12,14,20,0.45);
- color: white;
+ border: 1px solid color-mix(in srgb, var(--text) 14%, transparent);
+ background: color-mix(in srgb, var(--bg) 45%, transparent);
+ color: var(--text);
width: 40px;
height: 40px;
border-radius: 9999px;
@@ -184,7 +180,7 @@ body, html {
transition: transform 120ms ease, background 160ms ease, border-color 160ms ease;
}
-.search-bar button.search-btn:hover { transform: scale(1.02); background: rgba(24,26,34,0.55); border-color: rgba(255,255,255,0.24); }
+.search-bar button.search-btn:hover { transform: scale(1.02); background: color-mix(in srgb, var(--bg) 55%, transparent); border-color: color-mix(in srgb, var(--text) 24%, transparent); }
.search-bar button.search-btn:active { transform: scale(0.98); }
.search-bar button.search-btn .material-symbols-outlined {
@@ -194,8 +190,8 @@ body, html {
/* Search engine trigger unified look */
.search-engine-selector { position: relative; display: flex; align-items: center; }
.search-engine-btn {
- background: rgba(12,14,20,0.45);
- border: 1px solid rgba(255,255,255,0.14);
+ background: color-mix(in srgb, var(--bg) 45%, transparent);
+ border: 1px solid color-mix(in srgb, var(--text) 14%, transparent);
border-radius: 9999px;
padding: 8px 10px 8px 12px;
cursor: pointer;
@@ -207,7 +203,7 @@ body, html {
box-shadow: none;
transition: background 160ms ease, border-color 160ms ease, transform 120ms ease;
}
-.search-engine-btn:hover { background: rgba(24,26,34,0.55); border-color: rgba(255,255,255,0.24); }
+.search-engine-btn:hover { background: color-mix(in srgb, var(--bg) 55%, transparent); border-color: color-mix(in srgb, var(--text) 24%, transparent); }
.search-engine-btn:active { transform: scale(0.98); }
.search-engine-btn img { width: 22px; height: 22px; filter: none; }
@@ -220,7 +216,7 @@ body, html {
top: 8px;
bottom: 8px;
width: 1px;
- background: linear-gradient(to bottom, rgba(255,255,255,0.06), rgba(255,255,255,0.24), rgba(255,255,255,0.06));
+ background: linear-gradient(to bottom, color-mix(in srgb, var(--text) 6%, transparent), color-mix(in srgb, var(--text) 24%, transparent), color-mix(in srgb, var(--text) 6%, transparent));
pointer-events: none;
}
@@ -244,10 +240,10 @@ body, html {
position: absolute;
top: 110%;
left: 0;
- background: linear-gradient(180deg, rgba(18,20,24,0.96), rgba(18,20,24,0.9));
+ background: color-mix(in srgb, var(--bg) 94%, #000 6%);
border-radius: 10px;
- border: 1px solid rgba(255,255,255,0.12);
- box-shadow: 0 18px 50px -22px rgba(0,0,0,0.8), inset 0 1px 0 rgba(255,255,255,0.06);
+ border: 1px solid color-mix(in srgb, var(--text) 12%, transparent);
+ box-shadow: 0 18px 50px -22px color-mix(in srgb, var(--bg) 80%, transparent), inset 0 1px 0 color-mix(in srgb, var(--text) 6%, transparent);
z-index: 100;
padding: 0.5rem;
display: flex;
@@ -310,9 +306,9 @@ body, html {
margin-top: 1.25rem;
padding: 1rem 1rem 1.25rem;
border-radius: 16px;
- background: radial-gradient(120% 140% at 0% 0%, rgba(255,255,255,0.06), rgba(255,255,255,0.03) 45%, rgba(255,255,255,0.02));
- border: 1px solid rgba(255,255,255,0.12);
- box-shadow: 0 18px 50px -20px rgba(0,0,0,0.6), inset 0 1px 0 rgba(255,255,255,0.06);
+ background: color-mix(in srgb, var(--text) 6%, transparent);
+ border: 1px solid color-mix(in srgb, var(--text) 12%, transparent);
+ box-shadow: 0 18px 50px -20px color-mix(in srgb, var(--bg) 60%, transparent), inset 0 1px 0 color-mix(in srgb, var(--text) 6%, transparent);
backdrop-filter: blur(6px);
position: relative;
top: var(--home-bookmarks-y);
@@ -321,18 +317,18 @@ body, html {
display:flex; align-items:center; justify-content:space-between;
margin-bottom: 0.75rem; padding: 0 0.25rem;
}
-.top-sites-header h2 { font-size: 1rem; font-weight: 700; color: #dfe3ff; opacity: .9; }
+.top-sites-header h2 { font-size: 1rem; font-weight: 700; color: var(--text); opacity: .9; }
.link-btn {
- background: none; border: none; color: #9aa8ff; cursor: pointer; font-size: .9rem;
+ background: none; border: none; color: var(--accent); cursor: pointer; font-size: .9rem;
}
-.link-btn:hover { color: #c7d0ff; text-decoration: underline; }
+.link-btn:hover { color: var(--primary); text-decoration: underline; }
/* Individual bookmark tile */
.bookmark {
- background: rgba(255,255,255,0.05);
- border: 1px solid rgba(255,255,255,0.1);
+ background: color-mix(in srgb, var(--text) 5%, transparent);
+ border: 1px solid color-mix(in srgb, var(--text) 10%, transparent);
backdrop-filter: blur(6px);
- box-shadow: 0 4px 16px rgba(0,0,0,0.3);
+ box-shadow: 0 4px 16px color-mix(in srgb, var(--bg) 30%, transparent);
transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
color: var(--text);
width: 100px;
@@ -349,7 +345,7 @@ body, html {
.bookmark:hover {
transform: translateY(-4px) scale(1.1);
- box-shadow: 0 8px 24px rgba(0,0,0,0.5);
+ box-shadow: 0 8px 24px color-mix(in srgb, var(--bg) 50%, transparent);
}
.bookmark-icon {
@@ -462,7 +458,7 @@ body[data-theme="dark"] .bookmark .material-symbols-outlined,
left: 0;
right: 0;
bottom: 0;
- background: rgba(18,20,24,0.8);
+ background: color-mix(in srgb, var(--bg) 80%, transparent);
display: flex;
align-items: center;
justify-content: center;
@@ -563,18 +559,18 @@ body[data-theme="dark"] .bookmark .material-symbols-outlined,
.glance.pos-tr { right:22px; top:22px; left:auto; bottom:auto; }
.glance.pos-tl { left:22px; top:22px; right:auto; bottom:auto; }
.glance-card {
- min-width: 280px; background: rgba(12,16,26,0.55); border: 1px solid rgba(255,255,255,0.1);
- border-radius: 16px; padding: 1rem; box-shadow: 0 14px 40px -18px rgba(0,0,0,.8), inset 0 1px 0 rgba(255,255,255,0.05);
+ min-width: 280px; background: color-mix(in srgb, var(--bg) 55%, transparent); border: 1px solid color-mix(in srgb, var(--text) 10%, transparent);
+ border-radius: 16px; padding: 1rem; box-shadow: 0 14px 40px -18px color-mix(in srgb, var(--bg) 80%, transparent), inset 0 1px 0 color-mix(in srgb, var(--text) 5%, transparent);
backdrop-filter: blur(8px);
}
.glance { transition: transform 0.06s linear; will-change: transform; }
.glance.dragging { transform: translate3d(var(--drag-x, 0px), var(--drag-y, 0px), 0) scale(1.02); }
-.glance.dragging .glance-card { box-shadow: 0 24px 60px -24px rgba(0,0,0,.9), 0 0 0 2px rgba(255,255,255,.12) inset; }
-.glance-title { font-size: .95rem; color: #dfe3ff; opacity: .9; margin-bottom: .65rem; }
+.glance.dragging .glance-card { box-shadow: 0 24px 60px -24px color-mix(in srgb, var(--bg) 90%, transparent), 0 0 0 2px color-mix(in srgb, var(--text) 12%, transparent) inset; }
+.glance-title { font-size: .95rem; color: var(--text); opacity: .9; margin-bottom: .65rem; }
.glance-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; }
-.glance-tile { background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); border-radius: 12px; padding: .6rem .75rem; text-align:left; }
-.glance-label { font-size: .7rem; color: #b8c1ff; opacity: .85; margin-bottom: .25rem; }
-.glance-value { font-size: 1.05rem; letter-spacing: .3px; color:#fff; }
+.glance-tile { background: color-mix(in srgb, var(--text) 5%, transparent); border: 1px solid color-mix(in srgb, var(--text) 10%, transparent); border-radius: 12px; padding: .6rem .75rem; text-align:left; }
+.glance-label { font-size: .7rem; color: var(--accent); opacity: .85; margin-bottom: .25rem; }
+.glance-value { font-size: 1.05rem; letter-spacing: .3px; color: var(--text); }
@media (max-width: 700px) {
.glance { position: static; margin-top: 1rem; }
diff --git a/renderer/index.html b/renderer/index.html
index 6e3038a..0280dd1 100644
--- a/renderer/index.html
+++ b/renderer/index.html
@@ -25,7 +25,30 @@
-
+
+
+
+
+
+
+
+
+
diff --git a/renderer/script.js b/renderer/script.js
index 6e6f727..170e889 100644
--- a/renderer/script.js
+++ b/renderer/script.js
@@ -128,25 +128,111 @@ function addToSiteHistory(url) {
}
}
+// Store current theme colors globally for use by renderTabs
+let currentThemeColors = null;
+
// Apply theme colors to the main UI (URL bar and tabs)
function applyThemeToMainUI(theme) {
if (!theme || !theme.colors) return;
-
const root = document.documentElement;
+ const colors = theme.colors;
- // Apply URL bar and tab colors
- if (theme.colors.urlBarBg) root.style.setProperty('--url-bar-bg', theme.colors.urlBarBg);
- if (theme.colors.urlBarText) root.style.setProperty('--url-bar-text', theme.colors.urlBarText);
- if (theme.colors.urlBarBorder) root.style.setProperty('--url-bar-border', theme.colors.urlBarBorder);
- if (theme.colors.tabBg) root.style.setProperty('--tab-bg', theme.colors.tabBg);
- if (theme.colors.tabText) root.style.setProperty('--tab-text', theme.colors.tabText);
- if (theme.colors.tabActive) root.style.setProperty('--tab-active', theme.colors.tabActive);
- if (theme.colors.tabActiveText) root.style.setProperty('--tab-active-text', theme.colors.tabActiveText);
- if (theme.colors.tabBorder) root.style.setProperty('--tab-border', theme.colors.tabBorder);
+ // Store colors globally for renderTabs to use
+ currentThemeColors = colors;
+
+ // Set CSS variables on root for elements using var()
+ const setVar = (cssVar, value, fallback) => {
+ const val = value || fallback;
+ if (val) root.style.setProperty(cssVar, val);
+ };
+
+ // Core palette so popups/menus and the address bar stay in sync
+ setVar('--bg', colors.bg, '#0b0d10');
+ setVar('--dark-blue', colors.darkBlue, '#0b1c2b');
+ setVar('--dark-purple', colors.darkPurple, '#1b1035');
+ setVar('--primary', colors.primary, '#7b2eff');
+ setVar('--accent', colors.accent, '#00c6ff');
+ setVar('--text', colors.text, '#e0e0e0');
+
+ // URL bar + tab strip styling
+ setVar('--url-bar-bg', colors.urlBarBg, '#1c2030');
+ setVar('--url-bar-text', colors.urlBarText, '#e0e0e0');
+ setVar('--url-bar-border', colors.urlBarBorder, '#3e4652');
+ setVar('--tab-bg', colors.tabBg, '#161925');
+ setVar('--tab-text', colors.tabText, '#a4a7b3');
+ setVar('--tab-active', colors.tabActive, '#1c2030');
+ setVar('--tab-active-text', colors.tabActiveText, '#e0e0e0');
+ setVar('--tab-border', colors.tabBorder, '#2b3040');
+
+ // Also directly apply to key elements to ensure styles take effect
+ const nav = document.getElementById('nav');
+ const titlebarContainer = document.getElementById('titlebar-container');
+ const tabBar = document.getElementById('tab-bar');
+ const urlBox = document.getElementById('url');
+ const navCenter = document.querySelector('.nav-center');
- console.log('[THEME] Applied theme colors to main UI');
+ if (nav) {
+ nav.style.setProperty('background', colors.urlBarBg || '#1c2030', 'important');
+ nav.style.setProperty('border-bottom-color', colors.urlBarBorder || '#3e4652', 'important');
+ }
+ if (navCenter) {
+ navCenter.style.setProperty('background', colors.urlBarBg || '#1c2030', 'important');
+ navCenter.style.setProperty('border-color', colors.urlBarBorder || '#3e4652', 'important');
+ }
+ if (titlebarContainer) {
+ titlebarContainer.style.setProperty('background', colors.tabBg || '#161925', 'important');
+ }
+ if (tabBar) {
+ tabBar.style.setProperty('background', colors.tabBg || '#161925', 'important');
+ tabBar.style.setProperty('border-bottom-color', colors.tabBorder || '#2b3040', 'important');
+ }
+ if (urlBox) {
+ urlBox.style.setProperty('color', colors.urlBarText || '#e0e0e0', 'important');
+ }
+
+ // Update existing tab elements to reflect new theme colors
+ document.querySelectorAll('.tab').forEach(tab => {
+ const isActive = tab.classList.contains('active');
+ tab.style.setProperty('background', isActive
+ ? (colors.tabActive || '#1c2030')
+ : (colors.tabBg || '#161925'), 'important');
+ tab.style.setProperty('color', isActive
+ ? (colors.tabActiveText || '#e0e0e0')
+ : (colors.tabText || '#a4a7b3'), 'important');
+ tab.style.setProperty('border-color', colors.tabBorder || '#2b3040', 'important');
+ });
+
+ // Align the chrome background with the theme gradient or fallback
+ if (theme.gradient) {
+ document.body.style.background = theme.gradient;
+ } else if (colors.bg) {
+ document.body.style.background = colors.bg;
+ }
+
+ // Persist so other pages (home/settings) can pull the latest palette
+ try { localStorage.setItem('currentTheme', JSON.stringify(theme)); } catch {}
+
+ console.log('[THEME] Applied theme to main UI:', {
+ urlBarBg: colors.urlBarBg,
+ tabBg: colors.tabBg,
+ navFound: !!nav,
+ titlebarFound: !!titlebarContainer,
+ tabBarFound: !!tabBar
+ });
}
+// Detect platform and add class to body for CSS platform-specific styling
+(function detectPlatform() {
+ const platform = navigator.platform.toLowerCase();
+ if (platform.includes('mac')) {
+ document.body.classList.add('platform-darwin');
+ } else if (platform.includes('win')) {
+ document.body.classList.add('platform-win32');
+ } else {
+ document.body.classList.add('platform-linux');
+ }
+})();
+
// 1) cache hot DOM references
const urlBox = document.getElementById('url');
const tabBarEl = document.getElementById('tab-bar');
@@ -729,6 +815,8 @@ function convertHomeTabToWebview(tabId, inputUrl, resolvedUrl) {
// After creating dynamic webview:
webview.addEventListener('ipc-message', e => {
if (e.channel === 'theme-update') {
+ const theme = e.args && e.args[0];
+ if (theme) applyThemeToMainUI(theme);
const home = document.getElementById('home-webview');
if (home) home.send('theme-update', ...e.args);
} else if (e.channel === 'navigate' && e.args[0]) {
@@ -907,6 +995,18 @@ function renderTabs() {
el.setAttribute('tabindex', tab.id === activeTabId ? '0' : '-1');
el.dataset.tabId = tab.id;
currentOrder.push(tab.id);
+
+ // Apply theme colors to new tab element
+ if (currentThemeColors) {
+ const isActive = tab.id === activeTabId;
+ el.style.setProperty('background', isActive
+ ? (currentThemeColors.tabActive || '#1c2030')
+ : (currentThemeColors.tabBg || '#161925'), 'important');
+ el.style.setProperty('color', isActive
+ ? (currentThemeColors.tabActiveText || '#e0e0e0')
+ : (currentThemeColors.tabText || '#a4a7b3'), 'important');
+ el.style.setProperty('border-color', currentThemeColors.tabBorder || '#2b3040', 'important');
+ }
if (!lastTabOrder.includes(tab.id)) {
// New tab enters with animation
@@ -1215,6 +1315,18 @@ window.addEventListener('DOMContentLoaded', () => {
try {
const theme = JSON.parse(savedTheme);
applyThemeToMainUI(theme);
+ // Also send to home-webview once it's ready
+ const homeWebview = document.getElementById('home-webview');
+ if (homeWebview) {
+ const sendThemeToHome = () => {
+ try { homeWebview.send('theme-update', theme); } catch {}
+ };
+ // If already loaded, send immediately; otherwise wait for dom-ready
+ if (homeWebview.getWebContentsId) {
+ sendThemeToHome();
+ }
+ homeWebview.addEventListener('dom-ready', sendThemeToHome, { once: true });
+ }
} catch (err) {
console.error('Error applying saved theme:', err);
}
@@ -1371,17 +1483,71 @@ window.addEventListener('DOMContentLoaded', () => {
window.downloadsAPI?.onDone(()=> { refreshDownloadsMini(); });
window.downloadsAPI?.onCleared(()=> { refreshDownloadsMini(); });
- // window control bindings
+ // window control bindings (Windows frameless window)
const minBtn = document.getElementById('min-btn');
const maxBtn = document.getElementById('max-btn');
const closeBtn = document.getElementById('close-btn');
- if (minBtn && maxBtn && closeBtn) {
- if (process.platform !== 'darwin') {
- minBtn.addEventListener('click', () => ipcRenderer.invoke('window-minimize'));
- maxBtn.addEventListener('click', () => ipcRenderer.invoke('window-maximize'));
- closeBtn.addEventListener('click', () => ipcRenderer.invoke('window-close'));
- } else {
- document.getElementById('window-controls').style.display = 'none';
+ const windowControls = document.getElementById('window-controls');
+
+ console.log('[WindowControls] Elements found:', { minBtn: !!minBtn, maxBtn: !!maxBtn, closeBtn: !!closeBtn, windowControls: !!windowControls });
+
+ // Detect platform - hide controls on macOS (uses native traffic lights)
+ const isMacOS = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
+ console.log('[WindowControls] Platform:', navigator.platform, 'isMacOS:', isMacOS);
+
+ if (windowControls) {
+ if (isMacOS) {
+ // Hide window controls on macOS
+ windowControls.style.display = 'none';
+ // Remove right padding for window controls
+ document.getElementById('tab-bar').style.paddingRight = '10px';
+ } else if (minBtn && maxBtn && closeBtn) {
+ // Windows/Linux: Set up custom title bar controls
+ console.log('[WindowControls] Setting up event listeners for Windows/Linux');
+
+ minBtn.addEventListener('click', (e) => {
+ console.log('[WindowControls] Minimize clicked');
+ e.stopPropagation();
+ ipcRenderer.invoke('window-minimize');
+ });
+ maxBtn.addEventListener('click', async (e) => {
+ console.log('[WindowControls] Maximize clicked');
+ e.stopPropagation();
+ await ipcRenderer.invoke('window-maximize');
+ updateMaximizeIcon();
+ });
+ closeBtn.addEventListener('click', (e) => {
+ console.log('[WindowControls] Close clicked');
+ e.stopPropagation();
+ ipcRenderer.invoke('window-close');
+ });
+
+ // Update maximize icon based on window state
+ async function updateMaximizeIcon() {
+ try {
+ const isMaximized = await ipcRenderer.invoke('window-is-maximized');
+ const maximizeIcon = maxBtn.querySelector('.maximize-icon');
+ const restoreIcon = maxBtn.querySelector('.restore-icon');
+ if (maximizeIcon && restoreIcon) {
+ maximizeIcon.style.display = isMaximized ? 'none' : 'block';
+ restoreIcon.style.display = isMaximized ? 'block' : 'none';
+ maxBtn.title = isMaximized ? 'Restore' : 'Maximize';
+ maxBtn.setAttribute('aria-label', isMaximized ? 'Restore' : 'Maximize');
+ }
+ } catch (e) {
+ // Ignore errors during state check
+ }
+ }
+
+ // Initial state check
+ updateMaximizeIcon();
+
+ // Listen for window resize to update maximize icon
+ window.addEventListener('resize', () => {
+ // Debounce resize events
+ clearTimeout(window._maximizeIconTimeout);
+ window._maximizeIconTimeout = setTimeout(updateMaximizeIcon, 100);
+ });
}
}
diff --git a/renderer/settings.css b/renderer/settings.css
index af89a64..4e931b2 100644
--- a/renderer/settings.css
+++ b/renderer/settings.css
@@ -53,7 +53,7 @@ body {
.container {
position: relative;
- background: linear-gradient(180deg, rgba(20, 14, 40, 0.6), rgba(16, 10, 28, 0.6));
+ background: linear-gradient(180deg, color-mix(in srgb, var(--bg) 85%, #000 15%), color-mix(in srgb, var(--dark-purple, var(--bg)) 80%, #000 20%));
backdrop-filter: blur(14px) saturate(120%);
-webkit-backdrop-filter: blur(14px) saturate(120%);
padding: 0;
@@ -73,7 +73,7 @@ body {
position: absolute;
inset: -1px;
border-radius: inherit;
- background: linear-gradient(135deg, rgba(123,46,255,0.25), rgba(0,198,255,0.15) 40%, transparent 60%);
+ background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 25%, transparent), color-mix(in srgb, var(--accent) 18%, transparent) 40%, transparent 60%);
filter: blur(20px);
z-index: 0;
pointer-events: none;
@@ -82,7 +82,7 @@ body {
/* Sidebar + content layout */
.sidebar {
width: 280px;
- background: linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0.02));
+ background: linear-gradient(180deg, color-mix(in srgb, var(--text) 6%, transparent), color-mix(in srgb, var(--text) 4%, transparent));
border-right: 1px solid rgba(255,255,255,0.08);
padding: 1.25rem 1rem;
position: relative;
@@ -127,10 +127,10 @@ body {
}
.tab-link.active {
- background: linear-gradient(180deg, rgba(123, 46, 255, 0.18), rgba(0, 198, 255, 0.10));
- color: #fff;
- border: 1px solid rgba(123,46,255,0.35);
- box-shadow: inset 0 0 0 1px rgba(255,255,255,0.06);
+ background: linear-gradient(180deg, color-mix(in srgb, var(--primary) 22%, transparent), color-mix(in srgb, var(--accent) 14%, transparent));
+ color: var(--text);
+ border: 1px solid color-mix(in srgb, var(--primary) 35%, transparent);
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 8%, transparent);
}
/* Left accent bar */
@@ -185,24 +185,24 @@ label {
input {
padding: 0.6rem;
font-size: 1rem;
- border: 1px solid rgba(255,255,255,0.12);
+ border: 1px solid color-mix(in srgb, var(--text) 12%, transparent);
border-radius: 10px;
margin-bottom: 0.75rem;
- background-color: rgba(11, 28, 43, 0.6);
+ background-color: color-mix(in srgb, var(--bg) 82%, #000 18%);
color: var(--text);
outline: none;
}
input:focus {
box-shadow: var(--ring);
- border-color: rgba(123,46,255,0.5);
+ border-color: color-mix(in srgb, var(--primary) 50%, transparent);
}
button {
padding: 0.65rem 0.9rem;
font-size: 0.95rem;
- background: linear-gradient(180deg, rgba(123,46,255,0.95), rgba(90, 20, 220, 0.95));
- color: #fff;
- border: 1px solid rgba(255,255,255,0.08);
+ background: linear-gradient(180deg, color-mix(in srgb, var(--primary) 90%, var(--accent) 10%), color-mix(in srgb, var(--primary) 80%, #000 20%));
+ color: var(--text);
+ border: 1px solid color-mix(in srgb, var(--primary) 18%, transparent);
border-radius: 10px;
cursor: pointer;
transition: transform 0.08s ease, box-shadow 0.2s ease, background 0.2s ease, filter 0.2s ease;
@@ -225,30 +225,30 @@ button:active {
padding: 12px 24px;
font-size: 1rem;
font-weight: 600;
- background: linear-gradient(135deg, #7B2EFF 0%, #5a1fd4 50%, #00C6FF 100%);
+ background: linear-gradient(135deg, var(--primary) 0%, color-mix(in srgb, var(--primary) 60%, #000 40%) 50%, var(--accent) 100%);
background-size: 200% 100%;
- color: #fff;
+ color: var(--text);
border: 1px solid rgba(255,255,255,0.15);
border-radius: 12px;
cursor: pointer;
transition: all 0.3s ease;
- box-shadow: 0 4px 20px rgba(123, 46, 255, 0.3);
+ box-shadow: 0 4px 20px color-mix(in srgb, var(--primary) 30%, transparent);
}
.primary-btn:hover {
background-position: 100% 0;
- box-shadow: 0 6px 30px rgba(123, 46, 255, 0.45), 0 0 20px rgba(0, 198, 255, 0.2);
+ box-shadow: 0 6px 30px color-mix(in srgb, var(--primary) 45%, transparent), 0 0 20px color-mix(in srgb, var(--accent) 20%, transparent);
transform: translateY(-2px);
}
.primary-btn:active {
transform: translateY(0);
- box-shadow: 0 2px 10px rgba(123, 46, 255, 0.3);
+ box-shadow: 0 2px 10px color-mix(in srgb, var(--primary) 30%, transparent);
}
.note {
font-size: 0.8rem;
- color: #aaa;
+ color: color-mix(in srgb, var(--text) 70%, transparent);
margin-top: 1rem;
}
@@ -260,11 +260,11 @@ button:active {
display: flex;
align-items: center;
gap: 0.5rem;
- background-color: rgba(18,20,24,0.8);
- color: white;
+ background-color: color-mix(in srgb, var(--bg) 82%, #000 18%);
+ color: var(--text);
padding: 0.8rem 1.2rem;
border-radius: 12px;
- border: 1px solid rgba(255,255,255,0.08);
+ border: 1px solid color-mix(in srgb, var(--text) 8%, transparent);
box-shadow: 0 8px 30px rgba(0,0,0,0.5);
font-size: 1rem;
z-index: 1000;
@@ -300,7 +300,7 @@ button:active {
/* Cards (customization groups) */
.customization-group {
- background: linear-gradient(180deg, var(--surface-1), var(--surface-2));
+ background: linear-gradient(180deg, var(--surface-1, color-mix(in srgb, var(--bg) 85%, #000 15%)), var(--surface-2, color-mix(in srgb, var(--bg) 78%, #000 22%)));
border: 1px solid var(--card-border);
border-radius: 14px;
padding: 14px 16px 16px 16px;
@@ -348,6 +348,10 @@ h2::after {
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 16px;
padding: 10px 0;
+ background: linear-gradient(180deg, var(--surface-1, color-mix(in srgb, var(--bg) 85%, #000 15%)), var(--surface-2, color-mix(in srgb, var(--bg) 78%, #000 22%)));
+ border: 1px solid var(--card-border);
+ border-radius: 12px;
+ padding: 12px;
}
.theme-btn {
display: flex;
@@ -494,8 +498,8 @@ input[type="color"] {
align-items: center;
gap: 8px;
padding: 8px 12px;
- background: linear-gradient(180deg, rgba(123,46,255,0.95), rgba(90, 20, 220, 0.95));
- color: #fff;
+ background: var(--accent);
+ color: var(--text);
border: 1px solid rgba(255,255,255,0.08) !important;
border-radius: 10px !important;
text-decoration: none;
diff --git a/renderer/style.css b/renderer/style.css
index dae1033..2e3ef1e 100644
--- a/renderer/style.css
+++ b/renderer/style.css
@@ -2,12 +2,9 @@ html, body {
height: 100%;
margin: 0;
padding: 0;
- /* Subtle aurora background that peeks through glassy chrome */
- background:
- radial-gradient(1200px 600px at 10% -10%, rgba(62, 33, 110, 0.18), transparent 45%),
- radial-gradient(1000px 500px at 90% -20%, rgba(18, 124, 201, 0.16), transparent 40%),
- #0b0d10;
- color: white;
+ /* Background now driven by theme */
+ background: var(--bg, #0b0d10);
+ color: var(--text, white);
font-family: 'Segoe UI', system-ui, -apple-system, Ubuntu, Roboto, sans-serif;
}
@@ -16,6 +13,8 @@ html, body {
/* Space reserved on the left for system window controls (traffic lights on macOS).
Applied cross-platform per request to keep a consistent layout. */
--window-controls-offset: 80px; /* adjust if needed */
+ /* Space reserved on the right for Windows title bar controls */
+ --window-controls-width: 138px;
/* Design tokens */
--bg: #0b0d10;
@@ -50,22 +49,30 @@ html, body {
--tab-border: #2B3040;
}
+/* TITLEBAR CONTAINER - holds tab bar and window controls */
+#titlebar-container {
+ display: flex;
+ position: relative;
+ background: var(--tab-bg);
+ -webkit-app-region: drag;
+}
+
/* TAB STRIP */
#tab-bar {
display: flex;
align-items: flex-end;
gap: 2px;
- /* Increase left padding to avoid overlap with OS window controls area */
- padding: 6px 10px 0 var(--window-controls-offset);
+ flex: 1;
+ /* Default: small left padding for Windows/Linux (no traffic lights) */
+ padding: 6px 10px 0 10px;
background: var(--tab-bg);
border-bottom: 1px solid var(--tab-border);
overflow-x: auto; /* scroll when many tabs */
scrollbar-color: #444 #2a2a3c; /* thumb and track for Firefox */
scrollbar-width: thin; /* slimmer track */
- -webkit-backdrop-filter: blur(var(--blur));
- backdrop-filter: blur(var(--blur));
- /* Only the background areas are draggable. Individual tabs opt-out via no-drag. */
+ /* Inherit drag from container */
-webkit-app-region: drag;
+ min-height: 38px;
}
/* NAVBAR LAYOUT */
@@ -153,13 +160,9 @@ html, body {
.nav-right > button,
#reload-btn,
#menu-btn {
- background:
- /* brighter, more opaque fill for contrast */
- linear-gradient(180deg, rgba(50,54,74,0.96), rgba(38,42,60,0.96)) padding-box,
- /* stronger border highlight */
- linear-gradient(180deg, rgba(255,255,255,0.18), rgba(0,0,0,0.45)) border-box;
+ background: color-mix(in srgb, var(--url-bar-bg) 90%, var(--text) 10%);
color: var(--text);
- border: 1px solid transparent;
+ border: 1px solid color-mix(in srgb, var(--text) 15%, transparent);
width: 34px;
height: 34px;
display: inline-grid;
@@ -167,7 +170,7 @@ html, body {
border-radius: 50%;
cursor: pointer;
/* subtle inner highlight adds edge definition */
- box-shadow: inset 0 1px 0 rgba(255,255,255,0.08);
+ box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 8%, transparent);
transition: transform 120ms ease, box-shadow 120ms ease, filter 120ms ease;
line-height: 0; /* avoid vertical misalignment for glyphs */
padding: 0;
@@ -177,24 +180,21 @@ html, body {
/* Downloads button chrome to match other nav buttons */
#downloads-btn {
- background:
- linear-gradient(180deg, rgba(50,54,74,0.96), rgba(38,42,60,0.96)) padding-box,
- linear-gradient(180deg, rgba(255,255,255,0.18), rgba(0,0,0,0.45)) border-box;
- color: var(--muted);
- border: 1px solid transparent;
+ background: color-mix(in srgb, var(--url-bar-bg) 90%, var(--text) 10%);
+ color: var(--text);
+ border: 1px solid color-mix(in srgb, var(--text) 15%, transparent);
width: 34px;
height: 34px;
display: inline-grid;
place-items: center;
border-radius: 50%;
cursor: pointer;
- box-shadow: inset 0 1px 0 rgba(255,255,255,0.08);
+ box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 8%, transparent);
transition: transform 120ms ease, box-shadow 120ms ease, filter 120ms ease, color 120ms ease;
line-height: 0;
padding: 0;
-webkit-appearance: none;
appearance: none;
- background-color: transparent;
}
#downloads-btn:hover { filter: brightness(1.05); box-shadow: 0 4px 14px rgba(0,0,0,0.35); color: var(--text); }
#downloads-btn:active { transform: translateY(1px) scale(0.98); }
@@ -203,10 +203,8 @@ html, body {
/* Match home-active chrome variant */
body:has(#home-container.active) #downloads-btn {
- background:
- linear-gradient(180deg, rgba(60,66,90,0.98), rgba(44,48,68,0.98)) padding-box,
- linear-gradient(180deg, rgba(255,255,255,0.22), rgba(0,0,0,0.5)) border-box;
- box-shadow: inset 0 1px 0 rgba(255,255,255,0.10);
+ background: color-mix(in srgb, var(--url-bar-bg) 85%, var(--text) 15%);
+ box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 10%, transparent);
}
.nav-left button:hover,
@@ -214,7 +212,7 @@ body:has(#home-container.active) #downloads-btn {
#reload-btn:hover,
#menu-btn:hover {
filter: brightness(1.05);
- box-shadow: 0 4px 14px rgba(0,0,0,0.35);
+ box-shadow: 0 4px 14px color-mix(in srgb, var(--bg) 50%, transparent);
}
.nav-left button:active,
@@ -227,9 +225,8 @@ body:has(#home-container.active) #downloads-btn {
/* Primary action (Go button) keeps rectangular look but modernized */
.nav-center + button,
.nav-center button {
- background:
- linear-gradient(180deg, var(--accent), var(--accent-700));
- color: white !important;
+ background: var(--accent);
+ color: var(--text);
border: 1px solid transparent;
padding: 8px 14px;
border-radius: 10px;
@@ -237,7 +234,7 @@ body:has(#home-container.active) #downloads-btn {
transition: transform 120ms ease, box-shadow 120ms ease, filter 120ms ease;
}
.nav-center + button:hover,
-.nav-center button:hover { box-shadow: 0 8px 20px rgba(111, 76, 255, 0.35); }
+.nav-center button:hover { box-shadow: 0 8px 20px color-mix(in srgb, var(--primary) 35%, transparent); }
.nav-center + button:active,
.nav-center button:active { transform: translateY(1px) scale(0.98); }
@@ -252,9 +249,8 @@ body:has(#home-container.active) #downloads-btn {
position: absolute;
top: 30px;
right: 0;
- background:
- linear-gradient(180deg, rgba(30,34,50,0.92), rgba(25,28,42,0.92)) padding-box,
- linear-gradient(135deg, rgba(140, 86, 255, 0.25), rgba(62, 149, 255, 0.18)) border-box;
+ background: color-mix(in srgb, var(--url-bar-bg) 92%, var(--text) 8%);
+ border: 1px solid color-mix(in srgb, var(--primary) 25%, color-mix(in srgb, var(--accent) 18%, transparent));
border-radius: 14px;
padding: 8px;
display: flex;
@@ -288,13 +284,13 @@ body:has(#home-container.active) #downloads-btn {
}
#menu-popup button:hover {
- background: rgba(255,255,255,0.06);
+ background: color-mix(in srgb, var(--text) 8%, transparent);
}
/* Big Picture Mode button special style */
#bigpicture-btn {
- background: linear-gradient(135deg, rgba(123, 46, 255, 0.15) 0%, rgba(0, 198, 255, 0.1) 100%) !important;
- border: 1px solid rgba(123, 46, 255, 0.3) !important;
+ background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 15%, transparent) 0%, color-mix(in srgb, var(--accent) 10%, transparent) 100%) !important;
+ border: 1px solid color-mix(in srgb, var(--primary) 30%, transparent) !important;
margin: 4px 0;
}
@@ -322,10 +318,8 @@ body:has(#home-container.active) #downloads-btn {
position: absolute;
top: 34px;
right: 0;
- background:
- linear-gradient(180deg, rgba(30,34,50,0.95), rgba(25,28,42,0.95)) padding-box,
- linear-gradient(135deg, rgba(140, 86, 255, 0.18), rgba(62, 149, 255, 0.14)) border-box;
- border: 1px solid transparent;
+ background: color-mix(in srgb, var(--url-bar-bg) 95%, var(--text) 5%);
+ border: 1px solid color-mix(in srgb, var(--primary) 18%, color-mix(in srgb, var(--accent) 14%, transparent));
border-radius: 12px;
min-width: 280px;
box-shadow: var(--shadow-1);
@@ -339,14 +333,14 @@ body:has(#home-container.active) #downloads-btn {
.downloads-pop-header > span { font-weight: 600; color: var(--text); }
.downloads-pop-header > button { background: transparent; border: none; color: var(--accent); cursor: pointer; }
.downloads-pop-list { display:flex; flex-direction: column; gap: 8px; max-height: 280px; overflow: auto; }
-.downloads-empty { color: #aaa; font-size: 12px; text-align: center; padding: 16px 8px; }
-.dl-item { display:grid; grid-template-columns: 1fr auto; gap: 6px 8px; background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.06); border-radius: 10px; padding: 8px; }
-.dl-file { font-size: 12px; color: #eee; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }
-.dl-meta { font-size: 11px; color: #bbb; }
+.downloads-empty { color: var(--tab-text); font-size: 12px; text-align: center; padding: 16px 8px; }
+.dl-item { display:grid; grid-template-columns: 1fr auto; gap: 6px 8px; background: color-mix(in srgb, var(--text) 3%, transparent); border: 1px solid color-mix(in srgb, var(--text) 6%, transparent); border-radius: 10px; padding: 8px; }
+.dl-file { font-size: 12px; color: var(--text); white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }
+.dl-meta { font-size: 11px; color: var(--tab-text); }
.dl-actions { display:flex; gap:6px; }
-.dl-actions button { background: transparent; color: #ddd; border: 1px solid rgba(255,255,255,0.12); border-radius: 8px; padding: 4px 8px; cursor: pointer; }
-.dl-progress { height: 4px; background: rgba(255,255,255,0.08); border-radius: 3px; overflow: hidden; grid-column: 1 / -1; }
-.dl-bar { height: 100%; background: #3b82f6; width: 0%; transition: width .12s linear; }
+.dl-actions button { background: transparent; color: var(--text); border: 1px solid color-mix(in srgb, var(--text) 12%, transparent); border-radius: 8px; padding: 4px 8px; cursor: pointer; }
+.dl-progress { height: 4px; background: color-mix(in srgb, var(--text) 8%, transparent); border-radius: 3px; overflow: hidden; grid-column: 1 / -1; }
+.dl-bar { height: 100%; background: var(--accent); width: 0%; transition: width .12s linear; }
/* Circular progress ring around downloads button */
#downloads-btn { position: relative; }
@@ -361,8 +355,8 @@ body:has(#home-container.active) #downloads-btn {
pointer-events: none;
}
#downloads-btn .ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
-#downloads-btn .ring circle.bg { stroke: rgba(255,255,255,0.15); stroke-width: 3; fill: none; }
-#downloads-btn .ring circle.fg { stroke: #3b82f6; stroke-width: 3; fill: none; stroke-linecap: round; transition: stroke-dashoffset .12s linear, opacity .12s ease; }
+#downloads-btn .ring circle.bg { stroke: color-mix(in srgb, var(--text) 15%, transparent); stroke-width: 3; fill: none; }
+#downloads-btn .ring circle.fg { stroke: var(--accent); stroke-width: 3; fill: none; stroke-linecap: round; transition: stroke-dashoffset .12s linear, opacity .12s ease; }
/* WEBVIEWS */
#webviews {
@@ -452,7 +446,7 @@ body:has(#home-container.active) #downloads-btn {
.tab.active {
color: var(--tab-active-text);
background: var(--tab-active);
- box-shadow: 0 8px 22px rgba(0,0,0,0.35);
+ box-shadow: 0 8px 22px color-mix(in srgb, var(--bg) 35%, transparent);
}
.tab.active::after {
@@ -462,7 +456,7 @@ body:has(#home-container.active) #downloads-btn {
right: 0;
top: 0;
height: 2px;
- background: linear-gradient(90deg, var(--accent), var(--accent-600));
+ background: var(--accent);
}
.tab .tab-favicon {
@@ -489,15 +483,15 @@ body:has(#home-container.active) #downloads-btn {
border: none;
border-radius: 11px;
background: transparent;
- color: #b5b5b5;
+ color: var(--tab-text);
opacity: 0; /* hidden by default */
transition: background 120ms ease, color 120ms ease, opacity 120ms ease;
}
.tab:hover .tab-close,
.tab.active .tab-close { opacity: 1; }
-.tab .tab-close:hover { background: #3b3e47; color: #fff; }
-.tab .tab-close:active { background: #2e3139; }
+.tab .tab-close:hover { background: color-mix(in srgb, var(--text) 20%, transparent); color: var(--text); }
+.tab .tab-close:active { background: color-mix(in srgb, var(--text) 15%, transparent); }
/* New tab (+) button aligned to the right end of the strip */
.new-tab-button {
@@ -508,15 +502,13 @@ body:has(#home-container.active) #downloads-btn {
display: grid;
place-items: center;
border-radius: 13px;
- border: 1px solid transparent;
- background:
- linear-gradient(180deg, rgba(50,54,74,0.98), rgba(38,42,60,0.98)) padding-box,
- linear-gradient(180deg, rgba(255,255,255,0.18), rgba(0,0,0,0.45)) border-box;
- color: #f0f0f6;
+ border: 1px solid color-mix(in srgb, var(--text) 18%, transparent);
+ background: color-mix(in srgb, var(--tab-bg) 90%, var(--text) 10%);
+ color: var(--text);
cursor: pointer;
transition: transform 120ms ease, background 120ms ease, color 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
}
-.new-tab-button:hover { filter: brightness(1.06); box-shadow: 0 6px 16px rgba(0,0,0,0.35); }
+.new-tab-button:hover { filter: brightness(1.06); box-shadow: 0 6px 16px color-mix(in srgb, var(--bg) 35%, transparent); }
.new-tab-button:active { transform: translateY(1px) scale(0.98); }
/* ZOOM CONTROLS */
@@ -525,8 +517,8 @@ body:has(#home-container.active) #downloads-btn {
align-items: center;
gap: 6px;
padding: 6px 8px;
- background: rgba(255,255,255,0.04);
- border: 1px solid rgba(255,255,255,0.07);
+ background: color-mix(in srgb, var(--text) 4%, transparent);
+ border: 1px solid color-mix(in srgb, var(--text) 7%, transparent);
border-radius: 10px;
}
.zoom-controls .zoom-label {
@@ -556,31 +548,58 @@ body:has(#home-container.active) #downloads-btn {
color: var(--muted);
}
-/* window controls (Windows only) */
+/* window controls (Windows/Linux only) - Firefox-style next to tabs */
#window-controls {
- position: absolute;
- top: 0;
- right: 0;
display: flex;
- gap: 2px;
- padding: 4px;
- z-index: 200;
+ align-items: stretch;
+ align-self: stretch;
+ -webkit-app-region: no-drag;
+ background: transparent;
+ border-bottom: 1px solid var(--tab-border);
}
+
#window-controls button {
width: 46px;
- height: 28px;
background: transparent;
border: none;
- color: white;
- font-size: 12px;
+ color: var(--text);
cursor: pointer;
- transition: background 120ms ease;
+ transition: background 120ms ease, color 120ms ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ -webkit-app-region: no-drag;
+ padding: 0;
}
+
+#window-controls button svg {
+ width: 12px;
+ height: 12px;
+ pointer-events: none;
+}
+
#window-controls button:hover {
background: rgba(255,255,255,0.1);
+ color: var(--text);
}
+
#window-controls #close-btn:hover {
background: #e81123;
+ color: white;
+}
+
+#window-controls #close-btn:hover svg path {
+ stroke: white;
+}
+
+/* Hide window controls on macOS via body class set by JS */
+body.platform-darwin #window-controls {
+ display: none !important;
+}
+
+/* macOS: add left padding for traffic lights */
+body.platform-darwin #tab-bar {
+ padding-left: var(--window-controls-offset);
}
#tab-bar::-webkit-scrollbar {
@@ -709,35 +728,32 @@ body:has(#home-container.active) #downloads-btn {
box-shadow: none;
}
-/* Stronger chrome contrast when Home is visible */
+/* Stronger chrome contrast when Home is visible - uses theme variables */
body:has(#home-container.active) #tab-bar {
- background: linear-gradient(180deg, rgba(12,14,20,0.88), rgba(12,14,20,0.82));
- border-bottom-color: rgba(255,255,255,0.08);
+ background: color-mix(in srgb, var(--tab-bg) 92%, black);
+ border-bottom-color: color-mix(in srgb, var(--tab-border) 80%, transparent);
box-shadow: 0 10px 24px -12px rgba(0,0,0,0.6);
}
body:has(#home-container.active) #nav {
- background: linear-gradient(180deg, rgba(14,16,22,0.9), rgba(14,16,22,0.84));
- border-bottom: 1px solid rgba(255,255,255,0.08);
+ background: color-mix(in srgb, var(--url-bar-bg) 92%, black);
+ border-bottom: 1px solid color-mix(in srgb, var(--url-bar-border) 80%, transparent);
box-shadow: 0 14px 36px -16px rgba(0,0,0,0.7);
}
body:has(#home-container.active) .nav-center {
- background:
- linear-gradient(180deg, rgba(24,26,36,0.96), rgba(20,22,32,0.96)) padding-box,
- linear-gradient(135deg, rgba(140, 86, 255, 0.45), rgba(62, 149, 255, 0.32)) border-box;
- border: 1px solid transparent;
+ background: color-mix(in srgb, var(--url-bar-bg) 96%, black);
+ border: 1px solid color-mix(in srgb, var(--primary, var(--accent)) 45%, transparent);
}
body:has(#home-container.active) .nav-left button,
body:has(#home-container.active) .nav-right > button,
body:has(#home-container.active) #reload-btn,
body:has(#home-container.active) #menu-btn {
- /* slightly lighter than nav to pop over Home */
- background:
- linear-gradient(180deg, rgba(60,66,90,0.98), rgba(44,48,68,0.98)) padding-box,
- linear-gradient(180deg, rgba(255,255,255,0.22), rgba(0,0,0,0.5)) border-box;
- box-shadow: inset 0 1px 0 rgba(255,255,255,0.10);
+ /* slightly lighter than nav to pop over Home - uses theme colors */
+ background: color-mix(in srgb, var(--url-bar-bg) 85%, var(--text) 15%);
+ border: 1px solid color-mix(in srgb, var(--text) 20%, transparent);
+ box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 10%, transparent);
}
/* Elevate active tab a touch more over home */