diff --git a/static/css/base-styles.css b/static/css/base-styles.css index 3a809f1..a318456 100644 --- a/static/css/base-styles.css +++ b/static/css/base-styles.css @@ -5,8 +5,8 @@ --font-sans: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; --font-mono: 'JetBrains Mono', SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - /* Light Theme - Verbesserte Farben */ - --bg-primary-light: #f9fafb; + /* Light Theme */ + --bg-primary-light: #f8fafc; --bg-secondary-light: #f1f5f9; --bg-tertiary-light: #e2e8f0; --text-primary-light: #1e293b; @@ -14,9 +14,9 @@ --accent-primary-light: #7c3aed; --accent-secondary-light: #8b5cf6; --accent-tertiary-light: #a78bfa; - --border-light: #e5e7eb; - --shadow-light: 0 4px 10px -1px rgba(0, 0, 0, 0.08), 0 2px 5px -1px rgba(0, 0, 0, 0.04); - --glow-light: 0 0 20px rgba(139, 92, 246, 0.3); + --border-light: #e2e8f0; + --shadow-light: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + --glow-light: 0 0 15px rgba(139, 92, 246, 0.3); /* Dark Theme */ --bg-primary-dark: #0a0e19; @@ -38,24 +38,18 @@ /* Light mode optimierte Farben */ --light-bg: #f9fafb; - --light-bg-gradient: linear-gradient(135deg, #f9fafb, #f3f4f6); --light-text: #1e293b; --light-heading: #0f172a; --light-primary: #7c3aed; --light-primary-hover: #6d28d9; - --light-primary-gradient: linear-gradient(135deg, #8b5cf6, #6d28d9); --light-secondary: #6b7280; --light-border: #e5e7eb; --light-card-bg: rgba(255, 255, 255, 0.92); - --light-card-glass: rgba(255, 255, 255, 0.85); --light-navbar-bg: rgba(255, 255, 255, 0.92); --light-input-bg: #ffffff; --light-input-border: #d1d5db; --light-input-focus: #3b82f6; - --light-shadow: 0 4px 10px -1px rgba(0, 0, 0, 0.08), 0 2px 5px -1px rgba(0, 0, 0, 0.04); - --light-shadow-lg: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 5px 10px -5px rgba(0, 0, 0, 0.04); - --light-shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); - --light-glow: 0 0 20px rgba(124, 58, 237, 0.2); + --light-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); } /* Base Styles */ @@ -470,33 +464,22 @@ body:not(.dark) h6 { color: var(--light-heading); } -body:not(.dark) h1 { - font-weight: 700; - letter-spacing: -0.025em; -} - -body:not(.dark) h2 { - font-weight: 700; - letter-spacing: -0.015em; -} - -/* Light Mode Links mit verbesserten Hover-Effekten */ +/* Light Mode Links */ body:not(.dark) a { color: var(--light-primary); - transition: all 0.2s ease; } body:not(.dark) a:hover { color: var(--light-primary-hover); } -/* Verbesserte Light Mode Buttons */ +/* Light Mode Buttons */ body:not(.dark) .btn, body:not(.dark) button:not(.toggle) { - background: var(--light-primary-gradient); + background: linear-gradient(135deg, #6d28d9, #5b21b6); color: white; border: none; - box-shadow: 0 2px 6px rgba(91, 33, 182, 0.25); + box-shadow: 0 2px 4px rgba(91, 33, 182, 0.25); border-radius: 8px; padding: 0.625rem 1.25rem; transition: all 0.2s ease; @@ -507,181 +490,208 @@ body:not(.dark) button:not(.toggle) { body:not(.dark) .btn:hover, body:not(.dark) button:not(.toggle):hover { - background: linear-gradient(135deg, #8b5cf6, #7c3aed); - transform: translateY(-2px); + background: linear-gradient(135deg, #7c3aed, #6d28d9); + transform: translateY(-1px); box-shadow: 0 4px 12px rgba(109, 40, 217, 0.3); } -/* Optimierter Glasmorphismus im Light Mode */ -body:not(.dark) .glass-effect { - background-color: rgba(255, 255, 255, 0.8); - backdrop-filter: blur(16px); - -webkit-backdrop-filter: blur(16px); - border: 1px solid rgba(255, 255, 255, 0.5); - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); +/* Dark/Light Mode Switch Button */ +.theme-toggle { + position: relative; + width: 48px; + height: 24px; + background: linear-gradient(to right, #7c3aed, #3b82f6); + border-radius: 24px; + padding: 2px; + cursor: pointer; + transition: all 0.3s ease; + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1); } -/* Verbesserte Cards mit schönen Hover-Effekten im Light Mode */ -body:not(.dark) .card { +.theme-toggle::after { + content: ''; + position: absolute; + width: 20px; + height: 20px; + background: white; + border-radius: 50%; + top: 2px; + left: 2px; + transition: all 0.3s ease; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); +} + +.theme-toggle.dark::after { + transform: translateX(24px); +} + +.theme-toggle:hover::after { + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); +} + +/* Light Mode Cards und Panels */ +body:not(.dark) .card, +body:not(.dark) .panel { background-color: var(--light-card-bg); - border: 1px solid rgba(229, 231, 235, 0.7); + border: 1px solid var(--light-border); + border-radius: 0.5rem; + box-shadow: var(--light-shadow); +} + +/* Light Mode Tabelle */ +body:not(.dark) table { + background-color: var(--light-card-bg); + border-collapse: collapse; +} + +body:not(.dark) th { + background-color: var(--light-bg); + color: var(--light-heading); + border-bottom: 1px solid var(--light-border); +} + +body:not(.dark) td { + border-bottom: 1px solid var(--light-border); +} + +/* Light Mode Inputs */ +body:not(.dark) input, +body:not(.dark) textarea, +body:not(.dark) select { + background-color: var(--light-input-bg); + border: 1px solid var(--light-input-border); + color: var(--light-text); + border-radius: 0.375rem; + padding: 0.5rem; +} + +body:not(.dark) input:focus, +body:not(.dark) textarea:focus, +body:not(.dark) select:focus { + border-color: var(--light-input-focus); + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); + outline: none; +} + +/* Navbar im Light Mode verbessern */ +body:not(.dark) nav, +body:not(.dark) .navbar { + background-color: var(--light-navbar-bg); + box-shadow: var(--light-shadow); + border-bottom: 1px solid var(--light-border); +} + +/* Erweiterte Light-Mode-spezifische Stile */ +body:not(.dark) .glass-effect { + background-color: rgba(255, 255, 255, 0.7); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border: 1px solid rgba(209, 213, 219, 0.3); +} + +body:not(.dark) .card { + background-color: rgba(255, 255, 255, 0.85); + border: 1px solid var(--light-border); box-shadow: var(--light-shadow); transition: all 0.3s ease; - border-radius: 12px; } body:not(.dark) .card:hover { - box-shadow: var(--light-shadow-lg); - transform: translateY(-3px); - border-color: rgba(124, 58, 237, 0.2); + box-shadow: 0 8px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + transform: translateY(-2px); } -/* Glasmorphismus-Karten für besondere Elemente */ -body:not(.dark) .glass-card { - background-color: var(--light-card-glass); - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - border: 1px solid rgba(255, 255, 255, 0.7); - box-shadow: var(--light-shadow); - transition: all 0.3s ease; - border-radius: 16px; -} - -body:not(.dark) .glass-card:hover { - box-shadow: var(--light-shadow-lg); - transform: translateY(-3px); - border-color: rgba(124, 58, 237, 0.25); -} - -/* Light Mode Primary Buttons mit besserem Kontrast */ +/* Light Mode Buttons mit verbesserter Lesbarkeit */ body:not(.dark) .btn-primary { - background: var(--light-primary-gradient); + background: linear-gradient(135deg, #6d28d9, #5b21b6); color: white; border: none; transition: all 0.2s ease; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); font-weight: 600; letter-spacing: 0.02em; - box-shadow: 0 3px 6px rgba(91, 33, 182, 0.25); - border-radius: 10px; + box-shadow: 0 2px 4px rgba(91, 33, 182, 0.3); + border-radius: 8px; } body:not(.dark) .btn-primary:hover { - background: linear-gradient(135deg, #8b5cf6, #7c3aed); - box-shadow: 0 6px 15px rgba(109, 40, 217, 0.35); - transform: translateY(-2px); + background: linear-gradient(135deg, #7c3aed, #6d28d9); + box-shadow: 0 4px 12px rgba(109, 40, 217, 0.4), 0 2px 4px rgba(0, 0, 0, 0.1); + transform: translateY(-1px); } -/* Verbesserte sekundäre Buttons */ body:not(.dark) .btn-secondary { background: linear-gradient(135deg, #ffffff, #f9fafb); - color: #374151; - border: 1px solid #e5e7eb; + color: #1f2937; + border: 2px solid #e5e7eb; font-weight: 600; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); - border-radius: 10px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08); + border-radius: 8px; } body:not(.dark) .btn-secondary:hover { - background: linear-gradient(135deg, #f9fafb, #f1f5f9); + background: linear-gradient(135deg, #f9fafb, #f3f4f6); border-color: #d1d5db; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08); - transform: translateY(-2px); - color: var(--light-primary); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12); + transform: translateY(-1px); } -/* Outline Buttons mit verbessertem Kontrast */ body:not(.dark) .btn-outline { background-color: transparent; color: var(--light-primary); border: 1px solid var(--light-primary); - border-radius: 10px; - transition: all 0.2s ease; } body:not(.dark) .btn-outline:hover { - background-color: rgba(124, 58, 237, 0.08); - box-shadow: 0 2px 5px rgba(124, 58, 237, 0.15); - transform: translateY(-1px); + background-color: rgba(124, 58, 237, 0.05); } -/* Verbesserte Formulare im Light Mode */ +/* Light Mode Formulare */ body:not(.dark) input, body:not(.dark) select, body:not(.dark) textarea { background-color: white; border: 1px solid #d1d5db; color: #1f2937; - border-radius: 8px; - transition: all 0.2s ease; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); } body:not(.dark) input:focus, body:not(.dark) select:focus, body:not(.dark) textarea:focus { border-color: var(--light-primary); - box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.15); - outline: none; + box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.2); } -/* Optimierte Navigation im Light Mode */ -body:not(.dark) nav, -body:not(.dark) .navbar { - background-color: rgba(255, 255, 255, 0.85); - backdrop-filter: blur(15px); - -webkit-backdrop-filter: blur(15px); - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); - border-bottom: 1px solid rgba(229, 231, 235, 0.5); -} - -/* Verbesserte Navlinks */ -body:not(.dark) .nav-link { - color: #4b5563; - font-weight: 500; - transition: all 0.2s ease; -} - -body:not(.dark) .nav-link:hover { - color: var(--light-primary); - background-color: rgba(124, 58, 237, 0.08); - transform: translateY(-1px); -} - -body:not(.dark) .nav-link.active { - color: var(--light-primary); - background-color: rgba(124, 58, 237, 0.12); - font-weight: 600; -} - -/* Verbesserte Sidebar */ +/* Light Mode Navigation */ body:not(.dark) .sidebar { - background-color: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); - border-right: 1px solid rgba(229, 231, 235, 0.6); - box-shadow: 2px 0 10px rgba(0, 0, 0, 0.03); + background-color: white; + border-right: 1px solid #e5e7eb; } -/* Verbesserte Tabellen im Light Mode */ +body:not(.dark) .sidebar-link { + color: #4b5563; +} + +body:not(.dark) .sidebar-link:hover { + background-color: #f3f4f6; + color: var(--light-primary); +} + +body:not(.dark) .sidebar-link.active { + background-color: rgba(124, 58, 237, 0.08); + color: var(--light-primary); + font-weight: 500; +} + +/* Light Mode Tabellen */ body:not(.dark) table { border-color: #e5e7eb; - border-radius: 8px; - overflow: hidden; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); } body:not(.dark) th { background-color: #f9fafb; color: #111827; font-weight: 600; - border-bottom: 1px solid #e5e7eb; - padding: 12px 16px; -} - -body:not(.dark) td { - border-bottom: 1px solid #f1f5f9; - padding: 12px 16px; } body:not(.dark) tr:nth-child(even) { @@ -689,160 +699,275 @@ body:not(.dark) tr:nth-child(even) { } body:not(.dark) tr:hover { - background-color: rgba(124, 58, 237, 0.05); + background-color: #f3f4f6; } -/* Verbesserte Benachrichtigungen im Light Mode */ +/* Light Mode Icons */ +body:not(.dark) .icon { + color: #6b7280; +} + +body:not(.dark) .icon-primary { + color: var(--light-primary); +} + +/* Light Mode Alerts/Benachrichtigungen */ body:not(.dark) .alert-info { - background-color: rgba(59, 130, 246, 0.08); + background-color: #eff6ff; border-left: 4px solid #3b82f6; color: #1e40af; - border-radius: 8px; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); } body:not(.dark) .alert-success { - background-color: rgba(16, 185, 129, 0.08); + background-color: #ecfdf5; border-left: 4px solid #10b981; color: #065f46; - border-radius: 8px; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); } body:not(.dark) .alert-warning { - background-color: rgba(245, 158, 11, 0.08); + background-color: #fffbeb; border-left: 4px solid #f59e0b; color: #92400e; - border-radius: 8px; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); } body:not(.dark) .alert-error { - background-color: rgba(239, 68, 68, 0.08); + background-color: #fef2f2; border-left: 4px solid #ef4444; color: #b91c1c; - border-radius: 8px; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); } -/* Verbesserte Hintergrundeffekte für das Netzwerk im Light Mode */ -body:not(.dark) .network-background { - opacity: 0.3; +/* Light Mode Badge */ +body:not(.dark) .badge { + background-color: #e5e7eb; + color: #374151; } -body:not(.dark) .network-background .node { - fill: rgba(124, 58, 237, 0.5); +body:not(.dark) .badge-primary { + background-color: rgba(124, 58, 237, 0.1); + color: var(--light-primary); } -body:not(.dark) .network-background .link { - stroke: rgba(124, 58, 237, 0.2); -} - -/* Verbesserte Mindmap-Darstellung im Light Mode */ +/* Light Mode Mindmap spezifisch */ body:not(.dark) #cy { - background-color: rgba(255, 255, 255, 0.6); - border: 1px solid rgba(229, 231, 235, 0.7); - border-radius: 16px; - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05); + background-color: rgba(255, 255, 255, 0.7); + border: 1px solid #e5e7eb; } body:not(.dark) .node { border: 2px solid white; - box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1); - transition: all 0.2s ease; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } body:not(.dark) .node:hover, body:not(.dark) .node.selected { - box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.3), 0 5px 10px rgba(0, 0, 0, 0.1); - transform: scale(1.05); + box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.5), 0 4px 8px rgba(0, 0, 0, 0.1); } body:not(.dark) .edge { - opacity: 0.6; - transition: all 0.2s ease; + opacity: 0.7; } body:not(.dark) .edge:hover, body:not(.dark) .edge.selected { opacity: 1; - stroke-width: 2.5; } -/* Verbesserte Benutzeroberfläche für Gedanken-Karten */ -body:not(.dark) .thought-item { - background: white !important; - border: 1px solid rgba(229, 231, 235, 0.7) !important; - border-radius: 12px; - box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05); - transition: all 0.3s ease; -} - -body:not(.dark) .thought-item:hover { - box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08); - transform: translateY(-4px); - border: 1px solid rgba(124, 58, 237, 0.3) !important; -} - -/* Optimierte Pagination */ -body:not(.dark) .pagination { - display: flex; - gap: 0.5rem; -} - -body:not(.dark) .pagination-item { - border-radius: 8px; - padding: 0.5rem 0.75rem; - color: #4b5563; - border: 1px solid #e5e7eb; - transition: all 0.2s ease; -} - -body:not(.dark) .pagination-item:hover { - background-color: rgba(124, 58, 237, 0.08); - color: var(--light-primary); - border-color: rgba(124, 58, 237, 0.2); -} - -body:not(.dark) .pagination-item.active { - background-color: var(--light-primary); - color: white; - border-color: var(--light-primary); -} - -/* Light Mode für KI-Chat-Komponente */ -body:not(.dark) .ai-assistant-container { - background-color: rgba(255, 255, 255, 0.9); - border: 1px solid rgba(229, 231, 235, 0.7); - border-radius: 16px; - box-shadow: 0 10px 25px rgba(0, 0, 0, 0.08); -} - -body:not(.dark) .ai-assistant-header { - border-bottom: 1px solid rgba(229, 231, 235, 0.7); - background: linear-gradient(to right, rgba(124, 58, 237, 0.08), rgba(79, 70, 229, 0.08)); -} - -body:not(.dark) .ai-message { - background-color: rgba(124, 58, 237, 0.08); - border-radius: 12px 12px 12px 0; -} - -body:not(.dark) .user-message { - background-color: rgba(79, 70, 229, 0.15); - color: #1e293b; - border-radius: 12px 12px 0 12px; -} - -/* Light Mode für Footer */ +/* Footer im Light Mode */ body:not(.dark) footer { - background-color: rgba(249, 250, 251, 0.8); - backdrop-filter: blur(15px); - -webkit-backdrop-filter: blur(15px); - border-top: 1px solid rgba(229, 231, 235, 0.5); + background-color: rgba(249, 250, 251, 0.7); + border-top: 1px solid #e5e7eb; } -/* Print-Stile unverändert lassen */ +/* Alpine.js Transitions im Light Mode */ +body:not(.dark) [x-cloak] { + display: none !important; +} + +/* Suchfeldstyling im Light Mode */ +body:not(.dark) .search-container input { + background-color: white; + border: 1px solid #d1d5db; + color: #1f2937; +} + +body:not(.dark) .search-container input:focus { + border-color: var(--light-primary); + box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.2); +} + +body:not(.dark) .search-results { + background-color: white; + border: 1px solid #e5e7eb; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); +} + +body:not(.dark) .search-result-item:hover { + background-color: #f3f4f6; +} + +/* Profile und Benutzermenü im Light Mode */ +body:not(.dark) .avatar { + border: 2px solid white; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); +} + +body:not(.dark) .user-dropdown { + background-color: white; + border: 1px solid #e5e7eb; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); +} + +body:not(.dark) .user-dropdown-item:hover { + background-color: #f3f4f6; +} + +/* Medienabfragen für Responsivität */ +@media (max-width: 640px) { + /* Optimierungen für Smartphones */ + body { + padding-left: 0; + padding-right: 0; + } + + .container { + padding-left: 1rem; + padding-right: 1rem; + } + + .hero-heading { + font-size: 2rem; + } + + .section-heading { + font-size: 1.75rem; + } + + .card, .panel, .glass-card { + padding: 1rem; + border-radius: 10px; + } + + .navbar { + padding: 0.75rem 1rem; + } + + /* Optimierte Touch-Ziele für mobile Geräte */ + button, .btn, .nav-link, .menu-item { + min-height: 44px; + min-width: 44px; + display: flex; + align-items: center; + justify-content: center; + } + + /* Verbesserte Lesbarkeit auf kleinen Bildschirmen */ + p, li, input, textarea, button, .text-sm { + font-size: 1rem; + line-height: 1.5; + } + + /* Anpassungen für Tabellen auf kleinen Bildschirmen */ + table { + display: block; + overflow-x: auto; + white-space: nowrap; + } + + /* Optimierte Formulare */ + input, select, textarea { + font-size: 16px; /* Verhindert iOS-Zoom bei Fokus */ + width: 100%; + } + + /* Verbesserter Abstand für Touch-Targets */ + nav a, nav button, .menu-item { + margin: 0.25rem 0; + padding: 0.75rem; + } +} + +@media (min-width: 641px) and (max-width: 1024px) { + /* Optimierungen für Tablets */ + .container { + padding-left: 1.5rem; + padding-right: 1.5rem; + } + + /* Zweispaltige Layouts für mittlere Bildschirme */ + .grid-cols-1 { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 1.5rem; + } + + /* Optimierte Navigationsleiste */ + .navbar { + padding: 0.75rem 1.5rem; + } +} + +@media (min-width: 1025px) { + /* Optimierungen für Desktop */ + .container { + padding-left: 2rem; + padding-right: 2rem; + max-width: 1280px; + margin: 0 auto; + } + + /* Mehrspaltige Layouts für große Bildschirme */ + .grid-cols-1 { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 2rem; + } + + /* Hover-Effekte nur auf Desktop-Geräten */ + .card:hover, .panel:hover, .glass-card:hover { + transform: translateY(-5px); + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.15), 0 10px 10px -5px rgba(0, 0, 0, 0.1); + transition: transform 0.3s ease, box-shadow 0.3s ease; + } + + /* Desktop-spezifische Animationen */ + .animate-hover { + transition: all 0.3s ease; + } + + .animate-hover:hover { + transform: translateY(-3px); + box-shadow: var(--shadow-lg); + } +} + +/* Responsive design improvements */ +.responsive-grid { + display: grid; + gap: 1rem; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); +} + +.responsive-flex { + display: flex; + flex-wrap: wrap; + gap: 1rem; +} + +.responsive-flex > * { + flex: 1 1 280px; +} + +/* Accessibility improvements */ +.focus-visible:focus-visible { + outline: 2px solid var(--accent-primary-light); + outline-offset: 2px; +} + +body.dark .focus-visible:focus-visible { + outline: 2px solid var(--accent-primary-dark); +} + +/* Print styles */ @media print { body { background: white !important; diff --git a/static/css/neural-network-background.css b/static/css/neural-network-background.css index 9e76e9f..f5c6b76 100644 --- a/static/css/neural-network-background.css +++ b/static/css/neural-network-background.css @@ -103,50 +103,4 @@ body.dark footer { body:not(.dark) footer { background-color: rgba(249, 250, 251, 0.92) !important; border-top: 1px solid rgba(220, 220, 220, 0.8) !important; -} - -/* Neural Network Background für Dark & Light Mode */ -.neural-network-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - pointer-events: none; - overflow: hidden; - opacity: 0.8; - transition: opacity 0.5s ease; -} - -.neural-network-bg { - width: 100%; - height: 100%; -} - -/* Dark Mode Netzwerk-Hintergrund */ -.dark .neural-network-container { - opacity: 0.5; -} - -.dark .neural-network-bg .node { - fill: rgba(139, 92, 246, 0.4); -} - -.dark .neural-network-bg .link { - stroke: rgba(139, 92, 246, 0.15); -} - -/* Light Mode Netzwerk-Hintergrund */ -body:not(.dark) .neural-network-container { - opacity: 0.25; -} - -body:not(.dark) .neural-network-bg .node { - fill: rgba(124, 58, 237, 0.35); -} - -body:not(.dark) .neural-network-bg .link { - stroke: rgba(124, 58, 237, 0.15); - stroke-width: 1.25; } \ No newline at end of file diff --git a/static/js/theme-toggle.js b/static/js/theme-toggle.js deleted file mode 100644 index 9c5a1e6..0000000 --- a/static/js/theme-toggle.js +++ /dev/null @@ -1,191 +0,0 @@ -/** - * Systades Theme Toggle - Verbessertes Dark/Light Mode Switching - * - * Dieses Skript verwaltet die Theme-Umschaltung zwischen Light und Dark Mode - * mit sanften Übergängen und persistenter Speicherung der Benutzereinstellung. - */ - -document.addEventListener('DOMContentLoaded', () => { - // Initialisiere den Theme-Modus basierend auf gespeicherter Einstellung - initializeTheme(); - - // Führe eine Animation beim Umschalten der Themes aus - setupThemeTransition(); -}); - -/** - * Initialisiere das Theme basierend auf der gespeicherten Benutzereinstellung. - * Wenn keine Einstellung gefunden wird, verwende die Systemeinstellung. - */ -function initializeTheme() { - // Prüfe zuerst die gespeicherte Benutzereinstellung - const storedTheme = localStorage.getItem('darkMode'); - - if (storedTheme) { - // Verwende die gespeicherte Einstellung - const isDarkMode = storedTheme === 'dark'; - applyTheme(isDarkMode); - updateAlpineJsState(isDarkMode); - } else { - // Wenn keine Einstellung gefunden wurde, prüfe die Systemeinstellung - const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches; - applyTheme(prefersDarkMode); - updateAlpineJsState(prefersDarkMode); - - // Speichere die initiale Einstellung - localStorage.setItem('darkMode', prefersDarkMode ? 'dark' : 'light'); - } -} - -/** - * Wendet das ausgewählte Theme auf die Seite an - * @param {boolean} isDarkMode - Ob der Dark Mode aktiviert werden soll - */ -function applyTheme(isDarkMode) { - // Toggle der 'dark' Klasse auf dem HTML-Element - document.documentElement.classList.toggle('dark', isDarkMode); - - // Meta-Theme-Color für mobile Browser aktualisieren - const metaThemeColor = document.querySelector('meta[name="theme-color"]'); - if (metaThemeColor) { - metaThemeColor.setAttribute( - 'content', - isDarkMode ? '#111827' : '#f9fafb' - ); - } - - // Zusätzliche Stile für sanfte Übergänge - document.body.style.transition = 'background-color 0.5s ease, color 0.3s ease'; -} - -/** - * Aktualisiert den Dark Mode Status in Alpine.js - * @param {boolean} isDarkMode - Ob der Dark Mode aktiviert ist - */ -function updateAlpineJsState(isDarkMode) { - // Wenn Alpine.js verfügbar ist, aktualisiere den State - if (window.Alpine) { - // Finde alle Alpine Components, die ein darkMode Property haben - document.querySelectorAll('[x-data]').forEach(el => { - const alpineComponent = Alpine.$data(el); - if (alpineComponent && 'darkMode' in alpineComponent) { - alpineComponent.darkMode = isDarkMode; - } - }); - } -} - -/** - * Richte Event-Listener und Animationen für Themeübergänge ein - */ -function setupThemeTransition() { - // Animationseffekt für Themenwechsel - const createRippleEffect = (isDarkMode) => { - // Entferne bestehende Ripple-Elemente - const existingRipples = document.querySelectorAll('.theme-transition-ripple'); - existingRipples.forEach(ripple => ripple.remove()); - - // Erstelle neues Ripple-Element - const ripple = document.createElement('div'); - ripple.classList.add('theme-transition-ripple'); - - // Positioniere das Ripple-Element in der oberen rechten Ecke (wo der Toggle-Button ist) - ripple.style.position = 'fixed'; - ripple.style.top = '60px'; - ripple.style.right = '80px'; - ripple.style.width = '10px'; - ripple.style.height = '10px'; - ripple.style.borderRadius = '50%'; - ripple.style.backgroundColor = isDarkMode ? '#111827' : '#f9fafb'; - ripple.style.transform = 'scale(0)'; - ripple.style.transition = 'transform 1.2s ease-out'; - ripple.style.zIndex = '9999'; - ripple.style.pointerEvents = 'none'; - - // Füge das Ripple-Element zum Body hinzu - document.body.appendChild(ripple); - - // Trigger Animation - setTimeout(() => { - // Berechne die Größe, um den gesamten Bildschirm abzudecken - const maxDimension = Math.max(window.innerWidth, window.innerHeight) * 2.5; - ripple.style.transform = `scale(${maxDimension})`; - - // Entferne das Element nach Abschluss der Animation - setTimeout(() => { - ripple.remove(); - }, 1000); - }, 50); - }; - - // Event-Listener für den Theme-Toggle-Button - const themeToggleButtons = document.querySelectorAll('[data-toggle-theme]'); - themeToggleButtons.forEach(button => { - button.addEventListener('click', () => { - const isDarkMode = document.documentElement.classList.contains('dark'); - const newMode = !isDarkMode; - - // Erstelle den Ripple-Effekt - createRippleEffect(newMode); - - // Wende das neue Theme an - applyTheme(newMode); - - // Aktualisiere Alpine.js State - updateAlpineJsState(newMode); - - // Speichere die Einstellung - localStorage.setItem('darkMode', newMode ? 'dark' : 'light'); - }); - }); - - // Füge CSS für den Ripple-Effekt hinzu - const style = document.createElement('style'); - style.textContent = ` - .theme-transition-ripple { - position: fixed; - border-radius: 50%; - z-index: 9999; - pointer-events: none; - transition: transform 1.2s cubic-bezier(0.22, 1, 0.36, 1); - } - `; - document.head.appendChild(style); -} - -/** - * Öffentliche API für das Theme-Management - */ -window.ThemeManager = { - /** - * Schaltet zwischen Light und Dark Mode um - */ - toggleDarkMode() { - const isDarkMode = document.documentElement.classList.contains('dark'); - const newMode = !isDarkMode; - - // Wende das neue Theme an - applyTheme(newMode); - - // Aktualisiere Alpine.js State - updateAlpineJsState(newMode); - - // Speichere die Einstellung - localStorage.setItem('darkMode', newMode ? 'dark' : 'light'); - }, - - /** - * Setzt das Theme auf einen bestimmten Modus - * @param {boolean} isDarkMode - Ob der Dark Mode aktiviert werden soll - */ - setDarkMode(isDarkMode) { - // Wende das gewünschte Theme an - applyTheme(isDarkMode); - - // Aktualisiere Alpine.js State - updateAlpineJsState(isDarkMode); - - // Speichere die Einstellung - localStorage.setItem('darkMode', isDarkMode ? 'dark' : 'light'); - } -}; \ No newline at end of file diff --git a/static/neural-network-background.js b/static/neural-network-background.js index e89531b..01e7b09 100644 --- a/static/neural-network-background.js +++ b/static/neural-network-background.js @@ -51,11 +51,11 @@ class NeuralNetworkBackground { flowColor: '#b47fea' }, light: { - background: '#f9fafb', - nodeColor: '#8b5cf6', - nodePulse: '#7c3aed', - connectionColor: '#c4b5fd', - flowColor: '#6d28d9' + background: '#f8f9fc', + nodeColor: '#8c6db5', + nodePulse: '#b094dd', + connectionColor: '#9882bd', + flowColor: '#7d5bb5' } }; @@ -272,7 +272,7 @@ class NeuralNetworkBackground { connection.flowProgress = 0; connection.flowStart = now; connection.flowDuration = this.config.flowDuration[0] + - Math.random() * (this.config.flowDuration[1] - this.config.flowDuration[0]); + Math.random() * (this.config.flowDuration[1] - this.config.flowDuration[0]); this.activeConnections.add(connection.id); } @@ -361,9 +361,9 @@ class NeuralNetworkBackground { // Wenn pulsierend, füge einen Glow-Effekt hinzu if (isPulsing) { this.ctx.globalAlpha = 0.5 * (1 - pulseProgress); - this.ctx.beginPath(); + this.ctx.beginPath(); this.ctx.arc(node.x, node.y, node.size + 5 * pulseProgress, 0, Math.PI * 2); - this.ctx.fill(); + this.ctx.fill(); } } diff --git a/templates/base.html b/templates/base.html index 84e1d9e..353c47c 100644 --- a/templates/base.html +++ b/templates/base.html @@ -136,7 +136,7 @@ --accent-primary:#7c3aed; --accent-secondary:#8b5cf6; --glow-effect:0 0 8px rgba(139,92,246,.08); - background-image: linear-gradient(135deg, rgba(248, 250, 252, 0.9), rgba(241, 245, 249, 0.9)); + background-image: linear-gradient(to bottom right, rgba(248, 250, 252, 0.8), rgba(241, 245, 249, 0.8)); background-attachment: fixed; } /* Dark‑Mode */ @@ -161,115 +161,42 @@ background:linear-gradient(135deg,var(--accent-primary),var(--accent-secondary)); -webkit-background-clip:text; background-clip:text; color:transparent; text-shadow:none; } - .glass-morphism { - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - transition: all 0.3s ease; - } - .glass-navbar { - @apply glass-morphism border backdrop-blur-xl; - } - body:not(.dark) .glass-navbar { - background-color:rgba(255,255,255,.85); - border-color:rgba(0,0,0,.05); - box-shadow: 0 2px 10px rgba(0,0,0,.05); - } - .dark .glass-navbar { - background-color:rgba(10,14,25,.8); - border-color:rgba(255,255,255,.05); - } + .glass-morphism { backdrop-filter: blur(10px); } + .glass-navbar { @apply glass-morphism border backdrop-blur-xl; } + .light .glass-navbar { background-color:rgba(255,255,255,.8); border-color:rgba(0,0,0,.05); } + .dark .glass-navbar { background-color:rgba(10,14,25,.8); border-color:rgba(255,255,255,.05); } /* Light-Mode spezifische Stile */ body:not(.dark) { background-color: var(--bg-primary); color: var(--text-primary); - background-image: linear-gradient(135deg, rgba(249, 250, 251, 0.92), rgba(243, 244, 246, 0.92)); } - body:not(.dark) .nav-link { + .nav-link-light { color: var(--text-secondary); transition: all 0.3s ease; - border-radius: 0.5rem; - font-weight: 500; - padding: 0.5rem 0.75rem; } - body:not(.dark) .nav-link:hover { + .nav-link-light:hover { color: var(--text-primary); - background-color: rgba(124, 58, 237, 0.08); - transform: translateY(-1px); - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.03); + background-color: rgba(126, 34, 206, 0.1); } - body:not(.dark) .nav-link-active, - body:not(.dark) .nav-link-light-active { + .nav-link-light-active { color: var(--accent-primary); - background-color: rgba(124, 58, 237, 0.12); - font-weight: 600; + background-color: rgba(126, 34, 206, 0.15); + font-weight: 500; } /* Kartendesign im Light-Mode */ body:not(.dark) .card { - background-color: rgba(255, 255, 255, 0.9); - border: 1px solid rgba(229, 231, 235, 0.6); - box-shadow: 0 4px 15px -1px rgba(0, 0, 0, 0.05), 0 2px 8px -1px rgba(0, 0, 0, 0.03); - border-radius: 12px; - transition: all 0.3s ease; + background-color: white; + border: 1px solid #e5e7eb; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); } body:not(.dark) .card:hover { - box-shadow: 0 10px 20px -3px rgba(0, 0, 0, 0.08), 0 4px 10px -2px rgba(0, 0, 0, 0.05); - transform: translateY(-3px); - border-color: rgba(124, 58, 237, 0.2); - } - - body:not(.dark) .glass-card { - background-color: rgba(255, 255, 255, 0.85); - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - border: 1px solid rgba(255, 255, 255, 0.7); - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); - border-radius: 16px; - transition: all 0.3s ease; - } - - body:not(.dark) .glass-card:hover { - box-shadow: 0 10px 25px rgba(0, 0, 0, 0.08); - transform: translateY(-3px); - border-color: rgba(124, 58, 237, 0.25); - } - - /* Verbesserte Buttons im Light Mode */ - body:not(.dark) .btn { - background: linear-gradient(135deg, #8b5cf6, #6d28d9); - color: white; - border: none; - box-shadow: 0 3px 6px rgba(91, 33, 182, 0.25); - border-radius: 10px; - padding: 0.625rem 1.25rem; - font-weight: 600; - transition: all 0.2s ease; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); - } - - body:not(.dark) .btn:hover { - background: linear-gradient(135deg, #9f7afa, #7c3aed); - transform: translateY(-2px); - box-shadow: 0 6px 15px rgba(109, 40, 217, 0.3); - } - - /* Light Mode Netzwerk-Hintergrund */ - body:not(.dark) .network-background { - opacity: 0.3; - } - - body:not(.dark) .network-background .node { - fill: rgba(124, 58, 237, 0.5); - } - - body:not(.dark) .network-background .link { - stroke: rgba(124, 58, 237, 0.2); - stroke-width: 1.5; + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); } @@ -397,53 +324,12 @@