diff --git a/frontend/src/App.css b/frontend/src/App.css index 8e7f6b3..b123fa6 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -14,6 +14,23 @@ body { align-items: center; justify-content: center; min-height: 100vh; - font-size: 1.5rem; - color: #667eea; + gap: 0.75rem; + font-size: var(--text-lg); + color: var(--color-text-secondary); +} + +.loading::before { + content: ''; + width: 18px; + height: 18px; + border-radius: 999px; + border: 2px solid rgba(var(--color-accent-rgb), 0.22); + border-top-color: var(--color-accent); + animation: app-spin 0.85s linear infinite; +} + +@keyframes app-spin { + to { + transform: rotate(360deg); + } } diff --git a/frontend/src/contexts/ThemeContext.tsx b/frontend/src/contexts/ThemeContext.tsx index 5754dcc..d1bff85 100644 --- a/frontend/src/contexts/ThemeContext.tsx +++ b/frontend/src/contexts/ThemeContext.tsx @@ -79,6 +79,23 @@ const ACCENT_COLORS: Record c + c).join('') : hex; + const value = Number.parseInt(fullHex, 16); + if (Number.isNaN(value)) return null; + + const r = (value >> 16) & 255; + const g = (value >> 8) & 255; + const b = value & 255; + return `${r}, ${g}, ${b}`; +} + const BORDER_RADII: Record = { small: { sm: '2px', md: '4px', lg: '6px' }, medium: { sm: '4px', md: '6px', lg: '8px' }, @@ -480,6 +497,10 @@ export function ThemeProvider({ children }: { children: ReactNode }) { const hover = (theme === 'dark' && colors.darkHover) ? colors.darkHover : colors.hover; root.style.setProperty('--color-accent', main); root.style.setProperty('--color-accent-hover', hover); + const rgb = hexToRgbString(main); + if (rgb) { + root.style.setProperty('--color-accent-rgb', rgb); + } }, [accentColor, theme]); useEffect(() => { diff --git a/frontend/src/styles/AdminPanel.css b/frontend/src/styles/AdminPanel.css index b9ce10e..8a11432 100644 --- a/frontend/src/styles/AdminPanel.css +++ b/frontend/src/styles/AdminPanel.css @@ -75,19 +75,26 @@ align-items: center; gap: 0.5rem; padding: var(--btn-padding-md); - background: var(--color-accent); + background: linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-hover) 100%); color: white; border: none; border-radius: var(--radius-md); font-weight: 600; font-size: var(--btn-font-size); cursor: pointer; - transition: all 0.2s ease; + transition: transform var(--transition-base), box-shadow var(--transition-base), filter var(--transition-base); + box-shadow: var(--shadow-md); } .btn-primary:hover { - background: var(--color-accent-hover); - opacity: 0.95; + filter: brightness(1.03); + transform: translateY(-1px); + box-shadow: var(--shadow-lg); +} + +.btn-primary:active { + transform: translateY(0); + box-shadow: var(--shadow-md); } .btn-primary .material-symbols-outlined { @@ -118,6 +125,12 @@ min-width: 260px; } +.admin-panel-root .input-group:focus-within, +.users-root .input-group:focus-within { + border-color: rgba(var(--color-accent-rgb), 0.35); + box-shadow: var(--shadow-ring); +} + .admin-panel-root .input-group input, .users-root .input-group input { border: none; @@ -137,12 +150,20 @@ .admin-panel-root .users-card, .users-root .users-card { background: var(--color-bg-card); - border: 1px solid var(--color-border); + border: 1px solid var(--color-card-outline); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); overflow: hidden; } +@supports (color: color-mix(in srgb, black, transparent)) { + .admin-panel-root .users-card, + .users-root .users-card { + background: color-mix(in srgb, var(--color-bg-card) 88%, transparent); + backdrop-filter: blur(14px) saturate(1.1); + } +} + /* Table wrapper for horizontal scroll */ .admin-panel-root .users-table-wrapper, .users-root .users-table-wrapper { @@ -172,7 +193,7 @@ /* Users Settings Card */ .users-setting-card { background: var(--color-bg-card); - border: 1px solid var(--color-border); + border: 1px solid var(--color-card-outline); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: var(--space-6); @@ -197,7 +218,7 @@ width: 48px; height: 48px; background: var(--color-bg-elevated); - border: 1px solid var(--color-border); + border: 1px solid var(--color-card-outline); border-radius: var(--radius-md); flex-shrink: 0; } @@ -2356,4 +2377,4 @@ [data-theme='dark'][data-accent='auto'] .users-modal .toggle-inline input:checked+.toggle-slider-sm::before { background: #111827; -} \ No newline at end of file +} diff --git a/frontend/src/styles/Dashboard.css b/frontend/src/styles/Dashboard.css index f6c8f8c..66e0a66 100644 --- a/frontend/src/styles/Dashboard.css +++ b/frontend/src/styles/Dashboard.css @@ -8,7 +8,7 @@ .stats-grid { display: grid; grid-template-columns: repeat(3, 1fr); - gap: 1.5rem; + gap: var(--section-gap); width: 100%; } @@ -17,21 +17,42 @@ background: var(--color-bg-card); padding: 1.5rem; border-radius: var(--radius-lg); + border: 1px solid var(--color-card-outline); box-shadow: var(--shadow-sm); - transition: transform 0.2s, box-shadow 0.2s; + transition: transform var(--transition-base), box-shadow var(--transition-base), border-color var(--transition-base); +} + +@supports (color: color-mix(in srgb, black, transparent)) { + .stat-card { + background: color-mix(in srgb, var(--color-bg-card) 88%, transparent); + backdrop-filter: blur(14px) saturate(1.1); + } } .stat-card:hover { - transform: translateY(-2px); + transform: translateY(-3px); box-shadow: var(--shadow-md); + border-color: rgba(var(--color-accent-rgb), 0.25); } .stat-card h3 { margin-top: 0; color: var(--color-text-primary); - border-bottom: 2px solid var(--color-accent); - padding-bottom: 0.5rem; - font-size: 1.25rem; + border-bottom: 1px solid var(--color-card-outline); + padding-bottom: 0.75rem; + font-size: 1.15rem; + display: flex; + align-items: center; + gap: 0.6rem; +} + +.stat-card h3::before { + content: ''; + width: 10px; + height: 10px; + border-radius: 999px; + background: var(--color-accent); + box-shadow: 0 0 0 4px rgba(var(--color-accent-rgb), 0.14); } .stat-card p { @@ -43,8 +64,8 @@ /* Admin Card Variant */ .admin-card { - border: 2px solid var(--color-accent); - background: var(--color-bg-elevated); + border: 1px solid rgba(var(--color-accent-rgb), 0.35); + background: rgba(var(--color-accent-rgb), 0.05); } /* Status Indicators */ diff --git a/frontend/src/styles/Layout.css b/frontend/src/styles/Layout.css index ca870f1..6941426 100644 --- a/frontend/src/styles/Layout.css +++ b/frontend/src/styles/Layout.css @@ -35,7 +35,7 @@ display: flex; justify-content: center; padding: 0.75rem var(--page-padding-x); - background: var(--color-bg-main); + background: transparent; } /* Page header slider - rounded pill style (like admin panel) */ @@ -44,12 +44,20 @@ display: inline-flex; align-items: center; background: var(--color-bg-elevated); - border: 1px solid var(--color-border); + border: 1px solid var(--color-card-outline); border-radius: var(--radius-xl); padding: 4px; gap: 4px; - box-shadow: var(--shadow-sm); + box-shadow: var(--shadow-md); max-width: 100%; + backdrop-filter: blur(14px) saturate(1.15); +} + +@supports (color: color-mix(in srgb, black, white)) { + .page-tabs-slider, + .admin-tabs-slider { + background: color-mix(in srgb, var(--color-bg-elevated) 78%, transparent); + } } /* Page title section inside slider */ @@ -133,14 +141,15 @@ .page-tab-btn:hover:not(.active), .admin-tab-btn:hover:not(.active) { color: var(--color-text-primary); - background: rgba(var(--color-accent-rgb), 0.1); + background: rgba(var(--color-accent-rgb), 0.10); } .page-tab-btn.active, .admin-tab-btn.active { - background: var(--color-accent); + background: linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-hover) 100%); color: white; box-shadow: 0 2px 8px rgba(var(--color-accent-rgb), 0.3); + transform: translateY(-1px); } .page-subtitle { @@ -445,4 +454,4 @@ [data-theme='dark'][data-accent='auto'] .page-tab-btn.active:focus-visible, [data-theme='dark'][data-accent='auto'] .admin-tab-btn.active:focus-visible { box-shadow: 0 0 25px 4px rgba(229, 231, 235, 0.5); -} \ No newline at end of file +} diff --git a/frontend/src/styles/Login.css b/frontend/src/styles/Login.css index a7299ae..8e52f9d 100644 --- a/frontend/src/styles/Login.css +++ b/frontend/src/styles/Login.css @@ -3,7 +3,7 @@ display: flex; align-items: center; justify-content: center; - background: var(--color-bg-main); + background: transparent; padding: 1rem; } @@ -11,10 +11,17 @@ background: var(--color-bg-card); padding: 2rem; border-radius: var(--radius-lg); - box-shadow: var(--shadow-lg); + box-shadow: var(--shadow-xl); width: 100%; max-width: 450px; - border: 1px solid var(--color-border); + border: 1px solid var(--color-card-outline); +} + +@supports (color: color-mix(in srgb, black, transparent)) { + .login-card { + background: color-mix(in srgb, var(--color-bg-card) 86%, transparent); + backdrop-filter: blur(18px) saturate(1.15); + } } /* Mobile responsiveness */ @@ -90,38 +97,49 @@ .form-group input { width: 100%; - padding: 0.75rem; + height: var(--height-input); + padding: 0 0.875rem; border: 1px solid var(--color-border); - border-radius: var(--radius-sm); - font-size: 1rem; + border-radius: var(--radius-md); + font-size: 0.95rem; background: var(--color-bg-card); color: var(--color-text-primary); - transition: border-color 0.3s; + transition: border-color var(--transition-base), box-shadow var(--transition-base), background-color var(--transition-base); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.06); } .form-group input:focus { outline: none; - border-color: var(--color-accent); + border-color: rgba(var(--color-accent-rgb), 0.55); + box-shadow: var(--shadow-ring); } -.btn-primary { +.login-container .btn-primary { width: 100%; padding: 0.75rem; - background: var(--color-accent); + background: linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-hover) 100%); color: white; border: none; border-radius: var(--radius-md); font-size: 1rem; font-weight: 600; cursor: pointer; - transition: background 0.3s; + transition: transform var(--transition-base), box-shadow var(--transition-base), filter var(--transition-base); display: flex; align-items: center; justify-content: center; + box-shadow: var(--shadow-md); } -.btn-primary:hover { - background: var(--color-accent-hover); +.login-container .btn-primary:hover { + filter: brightness(1.03); + transform: translateY(-1px); + box-shadow: var(--shadow-lg); +} + +.login-container .btn-primary:active { + transform: translateY(0); + box-shadow: var(--shadow-md); } .login-footer { @@ -134,17 +152,19 @@ gap: 1rem; } -.btn-link { +.login-container .btn-link { background: none; border: none; color: var(--color-accent); cursor: pointer; - text-decoration: underline; + text-decoration: none; font-size: 0.95rem; + font-weight: 600; } -.btn-link:hover { +.login-container .btn-link:hover { color: var(--color-accent-hover); + text-decoration: underline; } .footer-actions { diff --git a/frontend/src/styles/SettingsPage.css b/frontend/src/styles/SettingsPage.css index 0ebfeac..6d270fb 100644 --- a/frontend/src/styles/SettingsPage.css +++ b/frontend/src/styles/SettingsPage.css @@ -20,13 +20,20 @@ /* Settings Sections */ .settings-section-modern { background: var(--color-bg-card); - border: 1px solid var(--color-border); + border: 1px solid var(--color-card-outline); border-radius: var(--radius-lg); padding: 2rem; box-shadow: var(--shadow-sm); margin-bottom: 1.5rem; } +@supports (color: color-mix(in srgb, black, transparent)) { + .settings-section-modern { + background: color-mix(in srgb, var(--color-bg-card) 88%, transparent); + backdrop-filter: blur(14px) saturate(1.1); + } +} + .settings-section-modern:last-child { margin-bottom: 0; } @@ -39,7 +46,7 @@ align-items: center; gap: 2rem; padding: 1.5rem 0; - border-bottom: 1px solid var(--color-border); + border-bottom: 1px solid var(--color-card-outline); } .setting-item-modern:last-child { @@ -78,6 +85,7 @@ width: 48px; height: 48px; background: var(--color-bg-elevated); + border: 1px solid var(--color-card-outline); border-radius: var(--radius-md); color: var(--color-accent); flex-shrink: 0; @@ -89,7 +97,7 @@ .select-modern { padding: 0.5rem 2rem 0.5rem 1rem; - border: 1px solid var(--color-border); + border: 1px solid var(--color-card-outline); border-radius: var(--radius-md); background-color: var(--color-bg-elevated); color: var(--color-text-primary); @@ -104,8 +112,8 @@ .select-modern:focus { outline: none; - border-color: var(--color-accent); - box-shadow: 0 0 0 2px rgba(var(--color-accent-rgb), 0.2); + border-color: rgba(var(--color-accent-rgb), 0.45); + box-shadow: var(--shadow-ring); } /* Modern Toggle */ @@ -172,4 +180,4 @@ align-items: flex-start; gap: 1rem; } -} \ No newline at end of file +} diff --git a/frontend/src/styles/Sidebar.css b/frontend/src/styles/Sidebar.css index 7ce0361..e9529ee 100644 --- a/frontend/src/styles/Sidebar.css +++ b/frontend/src/styles/Sidebar.css @@ -25,6 +25,19 @@ /* Subtle border */ } +@supports (color: color-mix(in srgb, black, transparent)) { + .sidebar { + background: color-mix(in srgb, var(--color-bg-sidebar) 88%, transparent); + } + + /* Avoid backdrop-filter on collapsed sidebar: it can break fixed-position dropdowns */ + .sidebar:not(.collapsed), + .sidebar.dynamic.collapsed.expanded-force, + .sidebar.open { + backdrop-filter: blur(18px) saturate(1.15); + } +} + .sidebar.clickable { cursor: pointer; } @@ -204,7 +217,7 @@ .sidebar-header { padding: 1rem; - border-bottom: 1px solid rgba(255, 255, 255, 0.1); + border-bottom: 1px solid var(--color-sidebar-border); height: 70px; display: flex; align-items: center; @@ -313,7 +326,7 @@ .nav-section-bottom { margin-top: 0.75rem; padding-top: 0.75rem; - border-top: 1px solid rgba(255, 255, 255, 0.1); + border-top: 1px solid var(--color-sidebar-border); } .nav-section-title { @@ -350,8 +363,12 @@ /* Ensure no gap affects centering */ } +.sidebar.collapsed .nav-item.active::before { + display: none; +} + .nav-item:hover { - background: rgba(255, 255, 255, 0.1); + background: rgba(var(--color-accent-rgb), 0.10); color: var(--color-text-sidebar) !important; } @@ -361,25 +378,32 @@ } .sidebar:not(.collapsed) .nav-item:hover { - transform: translateX(4px); + transform: translateX(2px); } .nav-item.active { - background: var(--color-accent); - /* Use accent color for active state */ - font-weight: 600; - color: white !important; - box-shadow: var(--shadow-md); + background: rgba(var(--color-accent-rgb), 0.16); + border: 1px solid rgba(var(--color-accent-rgb), 0.22); + font-weight: 650; + color: var(--color-text-sidebar) !important; + box-shadow: none; } .nav-item.active .nav-icon, .nav-item.active .nav-label { - color: white !important; + color: var(--color-text-sidebar) !important; } .nav-item.active::before { - display: none; - /* Remove the side bar indicator */ + content: ''; + position: absolute; + left: 8px; + top: 50%; + transform: translateY(-50%); + width: 3px; + height: 58%; + border-radius: 999px; + background: var(--color-accent); } .nav-icon { @@ -400,7 +424,7 @@ .sidebar-footer { padding: 0.75rem; - border-top: 1px solid rgba(255, 255, 255, 0.1); + border-top: 1px solid var(--color-sidebar-border); flex-shrink: 0; display: flex; flex-direction: column; @@ -423,7 +447,7 @@ gap: 0.75rem; padding: 0.75rem; background: transparent; - border: none; + border: 1px solid transparent; border-radius: var(--radius-md); color: var(--color-text-sidebar); cursor: pointer; @@ -434,7 +458,8 @@ } .view-mode-toggle:hover { - background: rgba(255, 255, 255, 0.1); + background: rgba(var(--color-accent-rgb), 0.10); + border-color: rgba(var(--color-accent-rgb), 0.18); color: var(--color-text-sidebar) !important; } @@ -450,13 +475,13 @@ } .view-mode-toggle.user-mode { - background: rgba(var(--color-accent-rgb), 0.2); - border-color: rgba(var(--color-accent-rgb), 0.3); + background: rgba(var(--color-accent-rgb), 0.16); + border-color: rgba(var(--color-accent-rgb), 0.22); } .view-mode-toggle.user-mode:hover { - background: rgba(var(--color-accent-rgb), 0.3); - border-color: rgba(var(--color-accent-rgb), 0.4); + background: rgba(var(--color-accent-rgb), 0.20); + border-color: rgba(var(--color-accent-rgb), 0.28); } .sidebar.collapsed .view-mode-toggle { @@ -468,7 +493,8 @@ .user-info-compact { padding: 0.5rem; - background: rgba(255, 255, 255, 0.1); + background: rgba(255, 255, 255, 0.06); + border: 1px solid var(--color-sidebar-border); border-radius: var(--radius-md); margin: 0; transition: padding 0.3s ease; @@ -516,7 +542,7 @@ margin: 0; font-size: 0.85rem; font-weight: 700; - background: rgba(255, 255, 255, 0.3); + background: rgba(var(--color-accent-rgb), 0.25); border-radius: 50%; flex-shrink: 0; color: var(--color-text-sidebar); @@ -669,10 +695,8 @@ left: 0; right: 0; bottom: 0; - background: rgba(0, 0, 0, 0.3); - /* Lighter overlay */ - backdrop-filter: blur(2px); - /* Blur the content behind */ + background: var(--color-overlay); + backdrop-filter: blur(6px); z-index: 1000; visibility: hidden; opacity: 0; @@ -729,7 +753,7 @@ .user-menu-trigger:hover, .user-menu-trigger.active { - background: rgba(255, 255, 255, 0.1); + background: rgba(var(--color-accent-rgb), 0.10); } .sidebar.dynamic.collapsed .user-menu-trigger:hover, @@ -751,7 +775,7 @@ } .sidebar.dynamic.collapsed .user-menu-trigger .user-info-compact:hover { - background: rgba(255, 255, 255, 0.1); + background: rgba(var(--color-accent-rgb), 0.10); } .user-menu-trigger .chevron { @@ -773,14 +797,20 @@ transform: translateX(-50%); transform-origin: bottom center; background: var(--color-bg-card); - border: 1px solid var(--color-border); + border: 1px solid var(--color-card-outline); border-radius: var(--radius-lg); box-shadow: var(--shadow-xl); z-index: 1100; overflow: hidden; animation: slideUpFade 0.25s cubic-bezier(0.4, 0, 0.2, 1); width: 244px; - border-color: var(--color-border); +} + +@supports (color: color-mix(in srgb, black, transparent)) { + .user-menu-dropdown { + background: color-mix(in srgb, var(--color-bg-card) 86%, transparent); + backdrop-filter: blur(16px) saturate(1.15); + } } .sidebar.collapsed .user-menu-dropdown { @@ -842,8 +872,8 @@ font-size: 0.85rem; font-weight: 500; white-space: nowrap; - box-shadow: var(--shadow-lg); - border: 1px solid var(--color-border); + box-shadow: var(--shadow-md); + border: 1px solid var(--color-card-outline); z-index: 1100; pointer-events: none; animation: tooltipFadeIn 0.2s ease forwards; @@ -857,7 +887,7 @@ transform: translateY(-50%); border-width: 5px 5px 5px 0; border-style: solid; - border-color: transparent var(--color-border) transparent transparent; + border-color: transparent var(--color-card-outline) transparent transparent; } .sidebar-tooltip::after { @@ -956,7 +986,7 @@ } .user-menu-item:hover { - background: var(--color-bg-elevated); + background: rgba(var(--color-accent-rgb), 0.08); color: var(--color-accent); } @@ -1032,4 +1062,4 @@ [data-theme='dark'][data-accent='auto'] .nav-item.active .nav-icon, [data-theme='dark'][data-accent='auto'] .nav-item.active .nav-label { color: #111827 !important; -} \ No newline at end of file +} diff --git a/frontend/src/styles/ThemeSettings.css b/frontend/src/styles/ThemeSettings.css index 6fccdd0..fe2d86c 100644 --- a/frontend/src/styles/ThemeSettings.css +++ b/frontend/src/styles/ThemeSettings.css @@ -564,28 +564,29 @@ } /* Button Styles for Preview */ -.btn-primary { +.theme-settings-root .btn-primary { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.65rem 1.25rem; - background: var(--color-accent); + background: linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-hover) 100%); color: white; border: none; border-radius: var(--radius-md); font-weight: 600; font-size: 0.95rem; cursor: pointer; - transition: all 0.2s ease; + transition: transform var(--transition-base), box-shadow var(--transition-base), filter var(--transition-base); + box-shadow: var(--shadow-md); } -.btn-primary:hover { - opacity: 0.9; +.theme-settings-root .btn-primary:hover { + filter: brightness(1.03); transform: translateY(-1px); - box-shadow: 0 4px 12px rgba(var(--color-accent-rgb), 0.3); + box-shadow: var(--shadow-lg); } -.btn-ghost { +.theme-settings-root .btn-ghost { display: inline-flex; align-items: center; gap: 0.5rem; @@ -600,7 +601,7 @@ transition: all 0.2s ease; } -.btn-ghost:hover { +.theme-settings-root .btn-ghost:hover { background: var(--color-bg-elevated); border-color: var(--color-accent); } @@ -1486,4 +1487,4 @@ [data-theme='dark'][data-accent='auto'] .chrome-picker input:focus { border-color: #e5e7eb !important; box-shadow: 0 0 0 3px rgba(229, 231, 235, 0.15) !important; -} \ No newline at end of file +} diff --git a/frontend/src/styles/Users.css b/frontend/src/styles/Users.css index 1f88af9..86a2d30 100644 --- a/frontend/src/styles/Users.css +++ b/frontend/src/styles/Users.css @@ -69,12 +69,19 @@ /* Table */ .users-root .users-card { background: var(--color-bg-card); - border: 1px solid var(--color-border); + border: 1px solid var(--color-card-outline); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); overflow: hidden; } +@supports (color: color-mix(in srgb, black, transparent)) { + .users-root .users-card { + background: color-mix(in srgb, var(--color-bg-card) 88%, transparent); + backdrop-filter: blur(14px) saturate(1.1); + } +} + .users-root .users-table { width: 100%; border-collapse: collapse; @@ -90,7 +97,7 @@ } .users-root .users-table tbody tr:not(:last-child) { - border-bottom: 1px solid var(--color-border); + border-bottom: 1px solid var(--color-card-outline); } .users-root .users-table th { @@ -103,7 +110,7 @@ } .users-root .users-table tbody tr:hover { - background: var(--color-bg-elevated); + background: rgba(var(--color-accent-rgb), 0.05); } /* User Cell */ @@ -156,17 +163,24 @@ align-items: center; gap: 0.35rem; padding: 0.55rem 0.9rem; - background: var(--color-accent); + background: linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-hover) 100%); color: white; border: none; border-radius: var(--radius-md); font-weight: 600; cursor: pointer; - transition: var(--transition); + transition: transform var(--transition-base), box-shadow var(--transition-base), filter var(--transition-base); + box-shadow: var(--shadow-sm); } .users-root .btn-primary:hover { - background: var(--color-accent-hover); + filter: brightness(1.03); + transform: translateY(-1px); + box-shadow: var(--shadow-md); +} + +.users-root .btn-primary:active { + transform: translateY(0); } .users-root .btn-ghost { @@ -175,15 +189,16 @@ gap: 0.35rem; padding: 0.5rem 0.85rem; border-radius: var(--radius-md); - border: 1px solid var(--color-border); - background: var(--color-bg-main); + border: 1px solid var(--color-card-outline); + background: transparent; color: var(--color-text-primary); cursor: pointer; transition: var(--transition); } .users-root .btn-ghost:hover { - background: var(--color-bg-card); + background: rgba(var(--color-accent-rgb), 0.06); + border-color: rgba(var(--color-accent-rgb), 0.18); } .users-root .btn-ghost.danger { @@ -683,4 +698,4 @@ width: 100%; justify-content: space-between; } -} \ No newline at end of file +} diff --git a/frontend/src/styles/theme/colors.css b/frontend/src/styles/theme/colors.css index 0e0fcff..e98bbe6 100644 --- a/frontend/src/styles/theme/colors.css +++ b/frontend/src/styles/theme/colors.css @@ -27,6 +27,11 @@ --color-border: #e5e7eb; --color-border-hover: #d1d5db; + /* Derived tokens */ + --color-overlay: rgba(15, 23, 42, 0.35); + --color-card-outline: rgba(15, 23, 42, 0.06); + --color-focus-ring: rgba(var(--color-accent-rgb), 0.22); + /* Semantic Colors (same for both themes) */ --color-success: #059669; --color-error: #dc2626; @@ -59,9 +64,26 @@ --color-border: #334155; --color-border-hover: #475569; + /* Derived tokens */ + --color-overlay: rgba(0, 0, 0, 0.55); + --color-card-outline: rgba(255, 255, 255, 0.08); + --color-focus-ring: rgba(var(--color-accent-rgb), 0.30); + /* Semantic Colors */ --color-success: #10b981; --color-error: #ef4444; --color-warning: #f59e0b; --color-info: #06b6d4; -} \ No newline at end of file +} + +@supports (color: color-mix(in srgb, black, white)) { + :root { + --color-border-hover: color-mix(in srgb, var(--color-border) 75%, var(--color-text-primary)); + --color-card-outline: color-mix(in srgb, var(--color-border) 60%, transparent); + } + + [data-theme='dark'] { + --color-border-hover: color-mix(in srgb, var(--color-border) 70%, var(--color-text-primary)); + --color-card-outline: color-mix(in srgb, var(--color-border) 55%, transparent); + } +} diff --git a/frontend/src/styles/theme/dimensions.css b/frontend/src/styles/theme/dimensions.css index 673526c..0d9ae83 100644 --- a/frontend/src/styles/theme/dimensions.css +++ b/frontend/src/styles/theme/dimensions.css @@ -32,7 +32,7 @@ --radius-sm: 4px; --radius-md: 6px; --radius-lg: 8px; - --radius-xl: 12px; + --radius-xl: 20px; --radius-full: 9999px; /* Component Heights */ @@ -151,4 +151,4 @@ --breakpoint-mobile: 768px; --breakpoint-tablet: 1024px; --breakpoint-desktop: 1280px; -} \ No newline at end of file +} diff --git a/frontend/src/styles/theme/effects.css b/frontend/src/styles/theme/effects.css index cb96955..c040da6 100644 --- a/frontend/src/styles/theme/effects.css +++ b/frontend/src/styles/theme/effects.css @@ -3,44 +3,45 @@ ========================================== */ :root { - /* Box Shadows */ - --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1); - --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1); - --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1); - --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.15); - --shadow-2xl: 0 25px 50px rgba(0, 0, 0, 0.25); - --shadow-inner: inset 0 2px 4px rgba(0, 0, 0, 0.06); + /* Box Shadows (modern, softer multi-layer) */ + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06), 0 1px 3px rgba(0, 0, 0, 0.08); + --shadow-md: 0 8px 18px rgba(0, 0, 0, 0.08), 0 2px 6px rgba(0, 0, 0, 0.06); + --shadow-lg: 0 18px 36px rgba(0, 0, 0, 0.12), 0 6px 14px rgba(0, 0, 0, 0.06); + --shadow-xl: 0 28px 60px rgba(0, 0, 0, 0.16), 0 12px 24px rgba(0, 0, 0, 0.08); + --shadow-2xl: 0 48px 110px rgba(0, 0, 0, 0.22); + --shadow-inner: inset 0 1px 2px rgba(0, 0, 0, 0.06); + --shadow-ring: 0 0 0 3px rgba(var(--color-accent-rgb), 0.18); /* Transitions */ - --transition-fast: 0.15s ease; - --transition-base: 0.2s ease; - --transition-slow: 0.3s ease; - --transition-slower: 0.5s ease; + --transition-fast: 120ms var(--ease-out); + --transition-base: 180ms var(--ease-out); + --transition-slow: 260ms var(--ease-out); + --transition-slower: 420ms var(--ease-out); /* Transition Properties */ - --transition: all 0.2s ease; - --transition-colors: color 0.2s ease, background-color 0.2s ease, border-color 0.2s ease; - --transition-transform: transform 0.2s ease; - --transition-opacity: opacity 0.2s ease; + --transition: all var(--transition-base); + --transition-colors: color var(--transition-base), background-color var(--transition-base), border-color var(--transition-base); + --transition-transform: transform var(--transition-base); + --transition-opacity: opacity var(--transition-base); /* Animation Durations */ - --duration-fast: 150ms; - --duration-base: 200ms; - --duration-slow: 300ms; - --duration-slower: 500ms; + --duration-fast: 120ms; + --duration-base: 180ms; + --duration-slow: 260ms; + --duration-slower: 420ms; /* Easing Functions */ - --ease-in: cubic-bezier(0.4, 0, 1, 1); - --ease-out: cubic-bezier(0, 0, 0.2, 1); + --ease-in: cubic-bezier(0.32, 0, 0.67, 0); + --ease-out: cubic-bezier(0.16, 1, 0.3, 1); --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); --ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55); } [data-theme='dark'] { - /* Dark Theme - Stronger Shadows */ - --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.5); - --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.5); - --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.5); - --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.6); - --shadow-2xl: 0 25px 50px rgba(0, 0, 0, 0.7); + /* Dark Theme - Deeper Shadows with less haze */ + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.45), 0 1px 3px rgba(0, 0, 0, 0.35); + --shadow-md: 0 10px 22px rgba(0, 0, 0, 0.45), 0 3px 10px rgba(0, 0, 0, 0.35); + --shadow-lg: 0 22px 44px rgba(0, 0, 0, 0.55), 0 8px 18px rgba(0, 0, 0, 0.35); + --shadow-xl: 0 34px 72px rgba(0, 0, 0, 0.65), 0 14px 28px rgba(0, 0, 0, 0.4); + --shadow-2xl: 0 60px 130px rgba(0, 0, 0, 0.75); } diff --git a/frontend/src/styles/theme/index.css b/frontend/src/styles/theme/index.css index 0f9fac3..09e0d0a 100644 --- a/frontend/src/styles/theme/index.css +++ b/frontend/src/styles/theme/index.css @@ -19,6 +19,10 @@ padding: 0; } +html { + color-scheme: light dark; +} + body { margin: 0; min-width: 320px; @@ -31,6 +35,8 @@ body { -moz-osx-font-smoothing: grayscale; user-select: none; -webkit-user-select: none; + overflow-x: hidden; + accent-color: var(--color-accent); } /* Utility for selectable text */ @@ -43,6 +49,23 @@ body { #root { min-height: 100vh; width: 100%; + position: relative; + isolation: isolate; +} + +/* Ambient background glow (subtle, adapts to accent) */ +#root::before { + content: ''; + position: fixed; + inset: -20%; + pointer-events: none; + z-index: -1; + opacity: 0.7; + background: + radial-gradient(40% 30% at 12% 12%, rgba(var(--color-accent-rgb), 0.18) 0%, rgba(var(--color-accent-rgb), 0) 65%), + radial-gradient(35% 28% at 88% 18%, rgba(var(--color-accent-rgb), 0.12) 0%, rgba(var(--color-accent-rgb), 0) 70%), + radial-gradient(45% 35% at 55% 92%, rgba(var(--color-accent-rgb), 0.10) 0%, rgba(var(--color-accent-rgb), 0) 70%); + filter: saturate(1.2); } /* Links */ @@ -71,8 +94,8 @@ button { button:focus, button:focus-visible { - outline: 2px solid var(--color-accent); - outline-offset: 2px; + outline: none; + box-shadow: var(--shadow-ring); } /* Loading state */ @@ -85,6 +108,12 @@ button:focus-visible { color: var(--color-accent); } +/* Text selection */ +::selection { + background: rgba(var(--color-accent-rgb), 0.22); + color: var(--color-text-primary); +} + /* Scrollbar styling */ ::-webkit-scrollbar { width: 10px; @@ -124,4 +153,18 @@ button:focus-visible { /* Loading state */ [data-theme='dark'][data-accent='auto'] .loading { color: #e5e7eb; -} \ No newline at end of file +} + +[data-theme='dark'] #root::before { + opacity: 0.45; + filter: saturate(1.15); +} + +@media (prefers-reduced-motion: reduce) { + * { + animation-duration: 1ms !important; + animation-iteration-count: 1 !important; + transition-duration: 1ms !important; + scroll-behavior: auto !important; + } +}