diff --git a/electron/main.js b/electron/main.js index e384711..7f07f4e 100644 --- a/electron/main.js +++ b/electron/main.js @@ -16,6 +16,8 @@ const createWindow = () => { mainWindow = new BrowserWindow({ width: 1200, height: 800, + minWidth: 900, + minHeight: 600, icon: path.join(__dirname, 'toolkitIcon.png'), webPreferences: { nodeIntegration: true, diff --git a/electron/renderer.js b/electron/renderer.js index b18b943..f7db468 100644 --- a/electron/renderer.js +++ b/electron/renderer.js @@ -4,50 +4,15 @@ const path = require('path'); // --- STATE --- let currentBundle = null; -// --- DOM ELEMENTS --- -// Views -const welcomeScreen = document.getElementById('welcome-screen'); -const bundleView = document.getElementById('bundle-view'); -const createBundleForm = document.getElementById('create-bundle-form'); // This will be a modal later - -// Sidebar buttons -const openBundleBtn = document.getElementById('open-bundle-btn'); -const createBundleBtn = document.getElementById('create-bundle-btn'); - -// Bundle action buttons -const signBundleBtn = document.getElementById('sign-bundle-btn'); -const validateBundleBtn = document.getElementById('validate-bundle-btn'); -// Fill button removed - Fill tab is now always visible -const clearBundleBtn = document.getElementById('clear-bundle-btn'); -const saveMetadataBtn = document.getElementById('save-metadata-btn'); - -// Save options modal elements -const saveOptionsModal = document.getElementById('save-options-modal'); -const overwriteBundleBtn = document.getElementById('overwrite-bundle-btn'); -const saveAsNewBtn = document.getElementById('save-as-new-btn'); - -// Signature warning modal elements -const signatureWarningModal = document.getElementById('signature-warning-modal'); -const signatureWarningCancel = document.getElementById('signature-warning-cancel'); -const signatureWarningContinue = document.getElementById('signature-warning-continue'); -let pendingOperation = null; // Store the operation to execute after warning confirmation - -// Fill tab elements -const fillTabLink = document.getElementById('fill-tab-link'); -const loadFillableTargetsBtn = document.getElementById('load-fillable-targets-btn'); -const fillLoading = document.getElementById('fill-loading'); -const fillPluginsTables = document.getElementById('fill-plugins-tables'); -const fillNoTargets = document.getElementById('fill-no-targets'); -const fillTargetsContent = document.getElementById('fill-targets-content'); -const selectAllTargetsBtn = document.getElementById('select-all-targets'); -const deselectAllTargetsBtn = document.getElementById('deselect-all-targets'); -const startFillProcessBtn = document.getElementById('start-fill-process'); -const fillProgressContainer = document.getElementById('fill-progress-container'); -const fillProgressContent = document.getElementById('fill-progress-content'); - -// Bundle display -const bundleTitle = document.getElementById('bundle-title'); -const manifestDetails = document.getElementById('manifest-details'); +// --- DOM ELEMENTS (will be initialized in DOMContentLoaded) --- +let welcomeScreen, bundleView, createBundleForm; +let openBundleBtn, createBundleBtn; +let signBundleBtn, validateBundleBtn, clearBundleBtn, saveMetadataBtn; +let saveOptionsModal, overwriteBundleBtn, saveAsNewBtn; +let signatureWarningModal, signatureWarningCancel, signatureWarningContinue; +let fillTabLink, loadFillableTargetsBtn, fillLoading, fillPluginsTables, fillNoTargets, fillTargetsContent; +let selectAllTargetsBtn, deselectAllTargetsBtn, startFillProcessBtn, fillProgressContainer, fillProgressContent; +let bundleTitle, manifestDetails; const pluginsList = document.getElementById('plugins-list'); const validationResults = document.getElementById('validation-results'); @@ -79,8 +44,13 @@ let currentBundlePath = null; let hasUnsavedChanges = false; let originalMetadata = {}; +let pendingOperation = null; // Store the operation to execute after warning confirmation + // --- INITIALIZATION --- document.addEventListener('DOMContentLoaded', async () => { + // Initialize DOM elements + initializeDOMElements(); + // Set initial view showView('welcome-screen'); @@ -92,6 +62,50 @@ document.addEventListener('DOMContentLoaded', async () => { setupEventListeners(); }); +function initializeDOMElements() { + // Views + welcomeScreen = document.getElementById('welcome-screen'); + bundleView = document.getElementById('bundle-view'); + createBundleForm = document.getElementById('create-bundle-form'); + + // Sidebar buttons + openBundleBtn = document.getElementById('open-bundle-btn'); + createBundleBtn = document.getElementById('create-bundle-btn'); + + // Bundle action buttons + signBundleBtn = document.getElementById('sign-bundle-btn'); + validateBundleBtn = document.getElementById('validate-bundle-btn'); + clearBundleBtn = document.getElementById('clear-bundle-btn'); + saveMetadataBtn = document.getElementById('save-metadata-btn'); + + // Save options modal elements + saveOptionsModal = document.getElementById('save-options-modal'); + overwriteBundleBtn = document.getElementById('overwrite-bundle-btn'); + saveAsNewBtn = document.getElementById('save-as-new-btn'); + + // Signature warning modal elements + signatureWarningModal = document.getElementById('signature-warning-modal'); + signatureWarningCancel = document.getElementById('signature-warning-cancel'); + signatureWarningContinue = document.getElementById('signature-warning-continue'); + + // Fill tab elements + fillTabLink = document.getElementById('fill-tab-link'); + loadFillableTargetsBtn = document.getElementById('load-fillable-targets-btn'); + fillLoading = document.getElementById('fill-loading'); + fillPluginsTables = document.getElementById('fill-plugins-tables'); + fillNoTargets = document.getElementById('fill-no-targets'); + fillTargetsContent = document.getElementById('fill-targets-content'); + selectAllTargetsBtn = document.getElementById('select-all-targets'); + deselectAllTargetsBtn = document.getElementById('deselect-all-targets'); + startFillProcessBtn = document.getElementById('start-fill-process'); + fillProgressContainer = document.getElementById('fill-progress-container'); + fillProgressContent = document.getElementById('fill-progress-content'); + + // Bundle display + bundleTitle = document.getElementById('bundle-title'); + manifestDetails = document.getElementById('manifest-details'); +} + // --- EVENT LISTENERS --- function setupEventListeners() { // Theme updates @@ -188,6 +202,8 @@ function setupEventListeners() { console.log('Populating fillable targets table'); fillTargetsContent.classList.remove('hidden'); populateFillTargetsTable(targets); + // Hide the Load Available Targets button after successful load + loadFillableTargetsBtn.style.display = 'none'; } } catch (error) { console.error('Error in loadFillableTargets:', error); @@ -366,7 +382,7 @@ function setupEventListeners() { ${target.triplet} ${target.arch} ${target.type} - ${target.details?.compiler || 'N/A'} ${target.details?.compiler_version || ''} + ${target.type === 'docker' ? 'GCC' : (target.details?.compiler || 'N/A')} ${target.details?.compiler_version || ''} `; tbody.appendChild(row); }); @@ -516,6 +532,9 @@ async function handleOpenBundle() { const bundlePath = await ipcRenderer.invoke('select-file'); if (!bundlePath) return; + // Small delay to ensure file dialog closes properly + await new Promise(resolve => setTimeout(resolve, 100)); + showSpinner(); showModal('Opening...', `Opening bundle: ${path.basename(bundlePath)}`); const result = await ipcRenderer.invoke('open-bundle', bundlePath); diff --git a/electron/styles.css b/electron/styles.css index 2e44398..22b3f3b 100644 --- a/electron/styles.css +++ b/electron/styles.css @@ -9,19 +9,28 @@ :root { --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; - --bg-color: #f4f7fa; - --sidebar-bg: #ffffff; - --content-bg: #ffffff; - --text-color: #2c3e50; - --text-light: #7f8c8d; - --border-color: #e1e5e8; - --primary-color: #3498db; - --primary-hover: #2980b9; - --danger-color: #e74c3c; - --success-color: #27ae60; - --warning-color: #f39c12; - --sidebar-width: 220px; - --header-height: 60px; + --primary-color: #3b82f6; + --secondary-color: #1e40af; + --background-color: #ffffff; + --text-color: #1f2937; + --text-light: #6b7280; + --border-color: #e5e7eb; + --hover-color: #f3f4f6; + --sidebar-bg: #2d3748; + --sidebar-width: 200px; + + /* Responsive breakpoints */ + --breakpoint-sm: 768px; + --breakpoint-md: 1024px; + --breakpoint-lg: 1280px; + --breakpoint-xl: 1440px; + + /* Responsive sidebar widths */ + --primary-sidebar-collapsed: 60px; + --primary-sidebar-expanded: 200px; + --secondary-sidebar-width: 200px; + --secondary-sidebar-width-lg: 240px; + --secondary-sidebar-width-xl: 280px; } body.dark-mode { @@ -47,14 +56,17 @@ body { .main-container { display: flex; height: 100vh; + min-width: 800px; + overflow-x: auto; } /* Two-Tiered Sidebar System */ /* Primary Sidebar (Tier 1) - Category Bar */ .primary-sidebar { - width: 60px; - background-color: var(--sidebar-bg); + width: var(--primary-sidebar-collapsed); + min-width: var(--primary-sidebar-collapsed); + background-color: #f8f9fa; border-right: 1px solid var(--border-color); display: flex; flex-direction: column; @@ -64,8 +76,30 @@ body { z-index: 100; } +body.dark-mode .primary-sidebar { + background-color: #2d3748; +} + .primary-sidebar:hover { - width: 200px; + width: var(--primary-sidebar-expanded); +} + +/* Responsive primary sidebar adjustments */ +@media (max-width: 1024px) { + .primary-sidebar:hover { + width: 180px; + } +} + +@media (max-width: 768px) { + .primary-sidebar { + width: 50px; + min-width: 50px; + } + + .primary-sidebar:hover { + width: 160px; + } } .primary-sidebar-header { @@ -97,14 +131,19 @@ body { .star-icon { font-size: 18px; color: #3b82f6; - opacity: 0.9; } .brand-text { - font-size: 16px; + font-size: 0.9rem; font-weight: 700; color: #1f2937; - letter-spacing: 1px; + letter-spacing: 0.5px; + margin-left: 8px; + transition: color 0.2s ease; +} + +body.dark-mode .primary-sidebar-header .brand-text { + color: #f9fafb; } .app-title { @@ -179,17 +218,38 @@ body { padding: 12px 16px 16px 16px; border-top: 1px solid var(--border-color); display: flex; - flex-direction: row; + flex-direction: column; align-items: center; - justify-content: space-between; + justify-content: center; min-height: 40px; + gap: 8px; +} + +/* When sidebar is collapsed, only show version centered */ +.primary-sidebar:not(:hover) .primary-sidebar-footer { + flex-direction: column; + align-items: center; + justify-content: center; +} + +/* When sidebar is expanded, show both version and info button */ +.primary-sidebar:hover .primary-sidebar-footer { + flex-direction: row; + justify-content: space-between; + align-items: center; } .version-info { font-size: 0.8rem; color: var(--text-light); - opacity: 0; + opacity: 1; transition: opacity 0.3s ease; + text-align: center; +} + +/* Hide version when collapsed, show when expanded */ +.primary-sidebar:not(:hover) .version-info { + opacity: 1; } .primary-sidebar:hover .version-info { @@ -198,16 +258,52 @@ body { /* Secondary Sidebar (Tier 2) - Content Sidebar */ .secondary-sidebar { - width: var(--sidebar-width); + width: var(--secondary-sidebar-width); + min-width: var(--secondary-sidebar-width); background-color: #fafbfc; border-right: 1px solid #e5e7eb; display: flex; flex-direction: column; flex-shrink: 0; - transition: background-color 0.2s; + transition: all 0.2s ease; box-shadow: inset -1px 0 0 rgba(0, 0, 0, 0.05); } +body.dark-mode .secondary-sidebar { + background-color: #374151; + border-right: 1px solid #4b5563; + box-shadow: inset -1px 0 0 rgba(255, 255, 255, 0.05); +} + +/* Responsive secondary sidebar */ +@media (min-width: 1280px) { + .secondary-sidebar { + width: var(--secondary-sidebar-width-lg); + min-width: var(--secondary-sidebar-width-lg); + } +} + +@media (min-width: 1440px) { + .secondary-sidebar { + width: var(--secondary-sidebar-width-xl); + min-width: var(--secondary-sidebar-width-xl); + } +} + +@media (max-width: 1024px) { + .secondary-sidebar { + width: 180px; + min-width: 180px; + } +} + +@media (max-width: 768px) { + .secondary-sidebar { + width: 160px; + min-width: 160px; + } +} + .sidebar-content { display: flex; flex-direction: column; @@ -225,6 +321,12 @@ body { background: linear-gradient(135deg, rgba(59, 130, 246, 0.02) 0%, rgba(147, 197, 253, 0.01) 100%); } +/* Dark mode sidebar header */ +body.dark-mode .sidebar-header { + border-bottom: 1px solid #4b5563; + background: linear-gradient(135deg, rgba(59, 130, 246, 0.05) 0%, rgba(147, 197, 253, 0.02) 100%); +} + .sidebar-header h3 { font-size: 1.3rem; font-weight: 700; @@ -233,43 +335,66 @@ body { letter-spacing: -0.025em; } +/* Dark mode sidebar header text */ +body.dark-mode .sidebar-header h3 { + color: #f3f4f6; +} + .sidebar-nav { padding: 24px 20px; flex-grow: 1; } .nav-button { - display: block; width: 100%; padding: 14px 20px; margin-bottom: 8px; background: white; border: 1px solid #e5e7eb; - text-align: left; - cursor: pointer; border-radius: 10px; - transition: all 0.2s ease; - font-size: 0.95rem; - font-weight: 500; color: #374151; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + font-size: 0.9rem; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + text-align: left; } .nav-button:hover { - background-color: #f8fafc; + background: #f9fafb; border-color: #d1d5db; transform: translateY(-1px); - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15); } .nav-button.active { - background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); - border-color: #2563eb; + background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%); color: white; - font-weight: 600; + border-color: #2563eb; box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3); } +body.dark-mode .nav-button { + background: #4b5563; + border: 1px solid #6b7280; + color: #f3f4f6; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); +} + +body.dark-mode .nav-button:hover { + background: #5b6572; + border-color: #9ca3af; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4); +} + +body.dark-mode .nav-button.active { + background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%); + color: white; + border-color: #2563eb; + box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4); +} + .nav-button.active:hover { transform: translateY(-1px); box-shadow: 0 6px 16px rgba(59, 130, 246, 0.4); @@ -289,18 +414,36 @@ body { align-items: center; justify-content: center; gap: 8px; - background: rgba(255, 255, 255, 0.1); - color: white; - border: 1px solid rgba(255, 255, 255, 0.2); + background: rgba(107, 114, 128, 0.15); + color: #4b5563; + border: 1px solid rgba(107, 114, 128, 0.25); border-radius: 6px; padding: 8px 12px; cursor: pointer; font-size: 12px; transition: all 0.2s ease; width: fit-content; + opacity: 0; } .info-button:hover { + background: rgba(107, 114, 128, 0.2); + border-color: rgba(107, 114, 128, 0.35); +} + +/* Show info button only when sidebar is expanded */ +.primary-sidebar:hover .info-button { + opacity: 1; +} + +/* Dark mode info button */ +body.dark-mode .info-button { + background: rgba(255, 255, 255, 0.1); + color: white; + border: 1px solid rgba(255, 255, 255, 0.2); +} + +body.dark-mode .info-button:hover { background: rgba(255, 255, 255, 0.2); border-color: rgba(255, 255, 255, 0.3); } @@ -324,6 +467,8 @@ body { display: flex; flex-direction: column; overflow: hidden; + min-width: 0; + padding: 0; } #welcome-screen { @@ -334,19 +479,50 @@ body { height: 100%; text-align: center; color: var(--text-light); + padding: 20px; } #welcome-screen h1 { font-size: 2rem; - margin-bottom: 10px; + margin-bottom: 0.5rem; + color: var(--text-color); +} + +#welcome-screen p { + font-size: 1.1rem; +} + +/* Responsive content area */ +@media (max-width: 1024px) { + #welcome-screen h1 { + font-size: 1.75rem; + } + + #welcome-screen p { + font-size: 1rem; + } +} + +@media (max-width: 768px) { + #welcome-screen { + padding: 15px; + } + + #welcome-screen h1 { + font-size: 1.5rem; + } + + #welcome-screen p { + font-size: 0.95rem; + } } .content-header { display: flex; justify-content: space-between; align-items: center; - padding: 0 25px; - height: var(--header-height); + padding: 20px 25px; + min-height: 80px; border-bottom: 1px solid var(--border-color); background-color: var(--content-bg); flex-shrink: 0; @@ -372,28 +548,35 @@ body { color: white; } +/* Bundle View */ +#bundle-view { + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; +} + /* Tabs */ .tab-nav { display: flex; - padding: 0 25px; border-bottom: 1px solid var(--border-color); - background-color: var(--content-bg); + background-color: var(--background-color); + overflow-x: auto; flex-shrink: 0; + padding: 0 25px; } .tab-link { padding: 15px 20px; - border: none; background: none; + border: none; cursor: pointer; - color: var(--text-light); font-size: 1rem; + color: var(--text-light); border-bottom: 3px solid transparent; - transition: color 0.2s, border-color 0.2s; -} - -.tab-link:hover { - color: var(--primary-color); + transition: all 0.2s; + white-space: nowrap; + flex-shrink: 0; } .tab-link.active { @@ -402,6 +585,49 @@ body { font-weight: 600; } +.tab-link:hover { + color: var(--primary-color); +} + +/* Dark mode tab styling */ +body.dark-mode .tab-nav { + background-color: #374151; + border-bottom: 1px solid #4b5563; +} + +body.dark-mode .tab-link { + color: #9ca3af; +} + +body.dark-mode .tab-link.active { + color: #f3f4f6; + border-bottom-color: var(--primary-color); +} + +body.dark-mode .tab-link:hover { + color: var(--primary-color); +} + +/* Responsive tabs */ +@media (max-width: 1024px) { + .tab-link { + padding: 12px 16px; + font-size: 0.9rem; + } +} + +@media (max-width: 768px) { + .tab-link { + padding: 10px 12px; + font-size: 0.85rem; + } + + .tab-nav { + padding: 0 15px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + } +} + #tab-content { padding: 25px; overflow-y: auto; @@ -464,12 +690,35 @@ body { height: 12px; border-radius: 50%; flex-shrink: 0; + display: inline-block; } -.trust-indicator.trusted { background-color: var(--success-color); } -.trust-indicator.untrusted { background-color: var(--danger-color); } -.trust-indicator.unsigned { background-color: var(--warning-color); } -.trust-indicator.warning { background-color: var(--warning-color); } +.trust-indicator.trusted { + background-color: #10b981; /* Green for trusted */ +} +.trust-indicator.untrusted { + background-color: #ef4444; /* Red for untrusted */ +} +.trust-indicator.unsigned { + background-color: #f59e0b; /* Amber for unsigned */ +} +.trust-indicator.warning { + background-color: #f59e0b; /* Amber for warning */ +} + +/* Dark mode trust indicators */ +body.dark-mode .trust-indicator.trusted { + background-color: #34d399; /* Lighter green for dark mode */ +} +body.dark-mode .trust-indicator.untrusted { + background-color: #f87171; /* Lighter red for dark mode */ +} +body.dark-mode .trust-indicator.unsigned { + background-color: #fbbf24; /* Lighter amber for dark mode */ +} +body.dark-mode .trust-indicator.warning { + background-color: #fbbf24; /* Lighter amber for dark mode */ +} /* Plugins List */ #plugins-list .plugin-item { @@ -496,42 +745,94 @@ body { font-family: monospace; } -/* Modal */ +/* Modal Styles */ .modal-container { position: fixed; top: 0; left: 0; width: 100%; height: 100%; - background-color: rgba(0, 0, 0, 0.6); + background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; z-index: 1000; + padding: 20px; } .modal-content { - background-color: var(--content-bg); - padding: 30px; + background-color: white; border-radius: 8px; - min-width: 400px; - max-width: 600px; - box-shadow: 0 5px 15px rgba(0,0,0,0.3); + padding: 20px; + max-width: 500px; + width: 90%; + max-height: 80vh; + overflow-y: auto; position: relative; + color: #1f2937; +} + +/* Dark mode modal content */ +body.dark-mode .modal-content { + background-color: #374151; + color: #f3f4f6; +} + +/* Responsive modal adjustments */ +@media (max-width: 1024px) { + .modal-content { + max-width: 450px; + width: 95%; + padding: 18px; + } +} + +@media (max-width: 768px) { + .modal-container { + padding: 15px; + } + + .modal-content { + max-width: 100%; + width: 100%; + max-height: 85vh; + padding: 16px; + border-radius: 6px; + } } .modal-close { position: absolute; top: 15px; right: 15px; - font-size: 1.5rem; - font-weight: bold; + width: 32px; + height: 32px; + border-radius: 6px; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.2rem; + font-weight: 500; cursor: pointer; - color: var(--text-light); + color: #6b7280; + background: transparent; + border: none; + transition: all 0.2s ease; } .modal-close:hover { - color: var(--text-color); + color: #374151; + background: rgba(107, 114, 128, 0.1); +} + +/* Dark mode close button */ +body.dark-mode .modal-close { + color: #9ca3af; +} + +body.dark-mode .modal-close:hover { + color: #f3f4f6; + background: rgba(156, 163, 175, 0.1); } #modal-title { @@ -694,9 +995,17 @@ body { } .fill-targets-table th { - background-color: var(--sidebar-bg); + background-color: #f8f9fa; font-weight: 600; - color: var(--text-color); + color: #374151; + border-bottom: 2px solid #e5e7eb; +} + +/* Dark mode table headers */ +body.dark-mode .fill-targets-table th { + background-color: #374151; + color: #f3f4f6; + border-bottom: 2px solid #4b5563; } .fill-targets-table tr:last-child td { @@ -704,7 +1013,18 @@ body { } .fill-targets-table tr:hover { - background-color: rgba(52, 152, 219, 0.05); + background-color: rgba(59, 130, 246, 0.05); +} + +/* Dark mode table row hover */ +body.dark-mode .fill-targets-table tr:hover { + background-color: rgba(59, 130, 246, 0.1); +} + +/* Dark mode table cells */ +body.dark-mode .fill-targets-table td { + color: #f3f4f6; + border-bottom: 1px solid #4b5563; } .fill-target-checkbox { @@ -712,6 +1032,61 @@ body { border-color: var(--primary-hover); } +/* Modern Action Button Base Styling */ +.action-button { + padding: 12px 24px; + border-radius: 8px; + font-size: 0.9rem; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; + border: none; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +.action-button:hover { + transform: translateY(-1px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); +} + +.action-button.primary { + background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); + color: white; + border: 1px solid #2563eb; +} + +.action-button.primary:hover { + background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%); + box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3); +} + +.action-button.secondary { + background: white; + color: #374151; + border: 1px solid #d1d5db; +} + +.action-button.secondary:hover { + background: #f9fafb; + border-color: #9ca3af; +} + +/* Dark mode action buttons */ +body.dark-mode .action-button.secondary { + background: #4b5563; + color: #f3f4f6; + border: 1px solid #6b7280; +} + +body.dark-mode .action-button.secondary:hover { + background: #5b6572; + border-color: #9ca3af; +} + .fill-actions { display: flex; gap: 12px; @@ -721,25 +1096,49 @@ body { margin-top: 20px; } -.action-button.secondary { - background-color: var(--sidebar-bg); - color: var(--text-color); - border: 1px solid var(--border-color); +/* Fill tab header with sticky blurred background */ +.fill-header { + position: sticky; + top: 0; + z-index: 10; + background: rgba(255, 255, 255, 0.9); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border-bottom: 1px solid rgba(229, 231, 235, 0.5); + padding: 20px 25px; + margin: -25px -25px 20px -25px; } -.action-button.secondary:hover { - background-color: var(--border-color); +/* Dark mode sticky header */ +body.dark-mode .fill-header { + background: rgba(55, 65, 81, 0.9); + border-bottom: 1px solid rgba(75, 85, 99, 0.5); } -.action-button.primary { - background-color: var(--primary-color); - color: white; - border: 1px solid var(--primary-color); +.fill-header h3 { + margin: 0 0 8px 0; + font-size: 1.3rem; + font-weight: 600; + color: #1f2937; } -.action-button.primary:hover { - background-color: var(--primary-hover); - border-color: var(--primary-hover); +body.dark-mode .fill-header h3 { + color: #f3f4f6; +} + +.fill-header p { + margin: 0 0 16px 0; + color: #6b7280; + font-size: 0.95rem; +} + +body.dark-mode .fill-header p { + color: #9ca3af; +} + +.fill-header-actions { + display: flex; + gap: 12px; } #fill-progress-container { @@ -808,15 +1207,31 @@ body { margin-top: 2px; } +/* Dark mode warning message */ +body.dark-mode .warning-message { + background-color: rgba(245, 158, 11, 0.15); + border: 1px solid rgba(245, 158, 11, 0.4); +} + .warning-text { line-height: 1.5; color: #92400e; } +/* Dark mode warning text */ +body.dark-mode .warning-text { + color: #fbbf24; +} + .warning-text strong { color: #78350f; } +/* Dark mode warning text strong */ +body.dark-mode .warning-text strong { + color: #f59e0b; +} + /* Save Options Modal */ .save-options { display: flex; @@ -838,30 +1253,58 @@ body { text-align: left; } +/* Dark mode save option buttons */ +body.dark-mode .save-option-btn { + background: #4b5563; + border-color: #6b7280; +} + .save-option-btn:hover { border-color: var(--primary-color); background-color: rgba(52, 152, 219, 0.05); } +/* Dark mode save option buttons hover */ +body.dark-mode .save-option-btn:hover { + border-color: var(--primary-color); + background-color: rgba(59, 130, 246, 0.15); +} + .save-option-btn.primary { border-color: var(--primary-color); } +body.dark-mode .save-option-btn.primary { + border-color: var(--primary-color); +} + .save-option-btn.secondary { border-color: var(--text-light); } +body.dark-mode .save-option-btn.secondary { + border-color: #9ca3af; +} + .save-option-btn strong { font-size: 16px; margin-bottom: 4px; color: var(--text-color); } +body.dark-mode .save-option-btn strong { + color: #f3f4f6; +} + .save-option-btn small { font-size: 14px; color: var(--text-light); } +body.dark-mode .save-option-btn small { + color: #d1d5db; +} + .progress-indicator.spinner-icon { border: 2px solid var(--text-color-light); border-top: 2px solid var(--primary-color); @@ -933,6 +1376,12 @@ body { background-color: #f8f9fa; } +/* Dark mode info tab nav */ +body.dark-mode .info-tab-nav { + background-color: #374151; + border-bottom: 1px solid #4b5563; +} + .info-tab-link { flex: 1; padding: 12px 16px; @@ -945,21 +1394,45 @@ body { border-bottom: 2px solid transparent; } +/* Dark mode info tab links */ +body.dark-mode .info-tab-link { + color: #9ca3af; +} + .info-tab-link:hover { background-color: #e5e7eb; color: #374151; } +body.dark-mode .info-tab-link:hover { + background-color: #4b5563; + color: #f3f4f6; +} + .info-tab-link.active { color: #3b82f6; border-bottom-color: #3b82f6; background-color: white; } +body.dark-mode .info-tab-link.active { + color: #3b82f6; + border-bottom-color: #3b82f6; + background-color: #4b5563; +} + .info-tab-content { padding: 24px; max-height: 400px; overflow-y: auto; + background-color: white; + color: #1f2937; +} + +/* Dark mode info tab content */ +body.dark-mode .info-tab-content { + background-color: #374151; + color: #f3f4f6; } .info-tab-pane { @@ -977,6 +1450,10 @@ body { font-size: 1.25rem; } +body.dark-mode .info-tab-pane h4 { + color: #f3f4f6; +} + .info-tab-pane h5 { margin-top: 20px; margin-bottom: 12px; @@ -984,6 +1461,32 @@ body { font-size: 1rem; } +body.dark-mode .info-tab-pane h5 { + color: #d1d5db; +} + +.info-tab-pane p { + color: #6b7280; + line-height: 1.6; +} + +body.dark-mode .info-tab-pane p { + color: #9ca3af; +} + +.info-tab-pane a { + color: #3b82f6; + text-decoration: none; +} + +.info-tab-pane a:hover { + text-decoration: underline; +} + +body.dark-mode .info-tab-pane a { + color: #60a5fa; +} + .info-tab-pane p { margin-bottom: 12px; line-height: 1.6;