From 7bca90b17c03c295a24062415b975f30321d635b Mon Sep 17 00:00:00 2001 From: Carsten Graf Date: Mon, 23 Mar 2026 22:36:32 +0100 Subject: [PATCH] Darkmode --- public/css/style.css | 435 ++++++++++++++++++++++++----------- views/footer.ejs | 80 +++++++ views/header.ejs | 14 ++ views/overtime-breakdown.ejs | 116 +++++++--- 4 files changed, 482 insertions(+), 163 deletions(-) diff --git a/public/css/style.css b/public/css/style.css index 041ab63..c44a691 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -4,10 +4,70 @@ box-sizing: border-box; } +:root { + --bg-page: #f5f5f5; + --bg-surface: #ffffff; + --bg-soft: #f8f9fa; + --bg-muted: #ecf0f1; + --bg-primary: #0066ff; + --text-main: #333333; + --text-strong: #2c3e50; + --text-muted: #666666; + --text-soft: #7f8c8d; + --text-inverse: #ffffff; + --border-color: #dddddd; + --border-soft: #e0e0e0; + --primary: #3498db; + --primary-hover: #2980b9; + --success: #27ae60; + --success-hover: #229954; + --danger: #e74c3c; + --danger-hover: #c0392b; + --secondary: #95a5a6; + --secondary-hover: #7f8c8d; + --info: #17a2b8; + --info-hover: #138496; + --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.1); + --shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.2); + --focus-ring: rgba(52, 152, 219, 0.35); + --overlay-surface: rgba(248, 249, 250, 0.92); + --table-hover: #f3f6fa; +} + +[data-theme="dark"] { + --bg-page: #0f172a; + --bg-surface: #111827; + --bg-soft: #1f2937; + --bg-muted: #1a2436; + --bg-primary: #1d4ed8; + --text-main: #e5e7eb; + --text-strong: #f3f4f6; + --text-muted: #cbd5e1; + --text-soft: #94a3b8; + --text-inverse: #ffffff; + --border-color: #334155; + --border-soft: #334155; + --primary: #60a5fa; + --primary-hover: #3b82f6; + --success: #34d399; + --success-hover: #10b981; + --danger: #f87171; + --danger-hover: #ef4444; + --secondary: #64748b; + --secondary-hover: #475569; + --info: #22d3ee; + --info-hover: #06b6d4; + --shadow-sm: 0 8px 24px rgba(0, 0, 0, 0.35); + --shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.5); + --focus-ring: rgba(96, 165, 250, 0.45); + --overlay-surface: rgba(31, 41, 55, 0.9); + --table-hover: #162235; +} + body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; - background-color: #f5f5f5; - color: #333; + background-color: var(--bg-page); + color: var(--text-main); line-height: 1.6; } @@ -24,10 +84,10 @@ body { /* Navbar */ .navbar { - background-color: #0066FF; - color: white; + background-color: var(--bg-primary); + color: var(--text-inverse); padding: 15px 0; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + box-shadow: var(--shadow-sm); } .navbar .container { @@ -87,39 +147,39 @@ body { } .btn-primary { - background-color: #3498db; - color: white; + background-color: var(--primary); + color: var(--text-inverse); } .btn-primary:hover { - background-color: #2980b9; + background-color: var(--primary-hover); } .btn-secondary { - background-color: #95a5a6; - color: white; + background-color: var(--secondary); + color: var(--text-inverse); } .btn-secondary:hover { - background-color: #7f8c8d; + background-color: var(--secondary-hover); } .btn-logout { - background-color: #e74c3c; - color: white; + background-color: var(--danger); + color: var(--text-inverse); } .btn-logout:hover { - background-color: #c0392b; + background-color: var(--danger-hover); } .btn-success { - background-color: #27ae60; - color: white; + background-color: var(--success); + color: var(--text-inverse); } .btn-success:hover { - background-color: #229954; + background-color: var(--success-hover); } .btn-success:disabled, @@ -136,12 +196,12 @@ body { } .btn-danger { - background-color: #e74c3c; - color: white; + background-color: var(--danger); + color: var(--text-inverse); } .btn-danger:hover { - background-color: #c0392b; + background-color: var(--danger-hover); } .btn-sm { @@ -155,27 +215,27 @@ body { justify-content: center; align-items: center; min-height: 100vh; - background: #0066FF; + background: var(--bg-primary); } .login-box { - background: white; + background: var(--bg-surface); padding: 40px; border-radius: 8px; - box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); + box-shadow: var(--shadow-lg); width: 100%; max-width: 400px; } .login-box h1 { text-align: center; - color: #2c3e50; + color: var(--text-strong); margin-bottom: 10px; } .login-box h2 { text-align: center; - color: #7f8c8d; + color: var(--text-soft); font-size: 18px; margin-bottom: 30px; font-weight: normal; @@ -189,7 +249,7 @@ body { .form-group label { display: block; margin-bottom: 5px; - color: #555; + color: var(--text-muted); font-weight: 500; } @@ -198,22 +258,25 @@ body { .form-group textarea { width: 100%; padding: 10px; - border: 1px solid #ddd; + border: 1px solid var(--border-color); border-radius: 4px; font-size: 14px; + background-color: var(--bg-surface); + color: var(--text-main); } .form-group input:focus, .form-group select:focus, .form-group textarea:focus { outline: none; - border-color: #3498db; + border-color: var(--primary); + box-shadow: 0 0 0 3px var(--focus-ring); } .form-help-text { display: block; margin-top: 8px; - color: #666; + color: var(--text-muted); font-size: 13px; font-style: italic; } @@ -225,8 +288,8 @@ body { gap: 12px; margin-top: 8px; padding: 15px; - background-color: #f9f9f9; - border: 1px solid #e0e0e0; + background-color: var(--bg-soft); + border: 1px solid var(--border-soft); border-radius: 6px; } @@ -240,16 +303,16 @@ body { align-items: center; cursor: pointer; padding: 10px 12px; - background-color: white; - border: 2px solid #e0e0e0; + background-color: var(--bg-surface); + border: 2px solid var(--border-soft); border-radius: 6px; transition: all 0.2s ease; user-select: none; } .role-checkbox-label:hover { - border-color: #3498db; - background-color: #f0f8ff; + border-color: var(--primary); + background-color: var(--table-hover); transform: translateY(-1px); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } @@ -264,24 +327,24 @@ body { height: 18px; margin-right: 12px; cursor: pointer; - accent-color: #3498db; + accent-color: var(--primary); flex-shrink: 0; } .role-checkbox-input:checked+.role-checkbox-text { font-weight: 600; - color: #2c3e50; + color: var(--text-strong); } .role-checkbox-label:has(.role-checkbox-input:checked) { - border-color: #3498db; - background-color: #e8f4f8; - box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1); + border-color: var(--primary); + background-color: var(--table-hover); + box-shadow: 0 0 0 3px var(--focus-ring); } .role-checkbox-text { font-size: 14px; - color: #333; + color: var(--text-main); transition: all 0.2s ease; } @@ -314,10 +377,10 @@ body { /* Dashboard */ .dashboard { - background: white; + background: var(--bg-surface); padding: 30px; border-radius: 8px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + box-shadow: var(--shadow-sm); flex: 1; min-width: 0; /* Ermöglicht Flexbox-Shrinking */ @@ -325,10 +388,10 @@ body { /* User Stats Panel */ .user-stats-panel { - background: white; + background: var(--bg-surface); padding: 20px; border-radius: 8px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + box-shadow: var(--shadow-sm); width: 280px; flex-shrink: 0; box-sizing: border-box; @@ -338,7 +401,7 @@ body { .user-stats-panel h3 { margin-top: 0; margin-bottom: 15px; - color: #2c3e50; + color: var(--text-strong); font-size: 18px; font-weight: 600; } @@ -354,20 +417,20 @@ body { /* User Options Panel */ .user-options-panel { - background: white; + background: var(--bg-surface); padding: 20px; border-radius: 8px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + box-shadow: var(--shadow-sm); width: 100%; box-sizing: border-box; } .stat-card { - background: #f8f9fa; + background: var(--bg-soft); padding: 15px; border-radius: 6px; margin-bottom: 12px; - border-left: 4px solid #3498db; + border-left: 4px solid var(--primary); box-sizing: border-box; width: 100%; overflow: hidden; @@ -383,7 +446,7 @@ body { .stat-label { font-size: 12px; - color: #666; + color: var(--text-muted); margin-bottom: 6px; font-weight: 500; } @@ -391,7 +454,7 @@ body { .stat-value { font-size: 24px; font-weight: bold; - color: #2c3e50; + color: var(--text-strong); margin-bottom: 4px; } @@ -416,11 +479,11 @@ body { justify-content: center; font-size: 11px; font-weight: 500; - color: #555; + color: var(--text-muted); text-align: center; padding: 0 8px; pointer-events: none; - background: linear-gradient(to bottom, rgba(248, 249, 250, 0.95), rgba(248, 249, 250, 0.8)); + background: linear-gradient(to bottom, var(--overlay-surface), transparent); opacity: 1; transition: opacity 0.2s ease; } @@ -431,7 +494,7 @@ body { .stat-unit { font-size: 11px; - color: #999; + color: var(--text-soft); } /* Apple-Style Toggle Switch */ @@ -503,7 +566,7 @@ body { .week-selector h2 { flex: 1; text-align: center; - color: #2c3e50; + color: var(--text-strong); } .week-selector-goto { @@ -519,13 +582,13 @@ body { width: 200px; max-width: 100%; padding: 8px 12px; - border: 1px solid #ccc; + border: 1px solid var(--border-color); border-radius: 4px; font-size: 14px; } .go-to-week-error { - color: #dc3545; + color: var(--danger); font-size: 13px; display: none; } @@ -545,17 +608,17 @@ table th, table td { padding: 12px; text-align: left; - border-bottom: 1px solid #ddd; + border-bottom: 1px solid var(--border-color); } table th { - background-color: #f8f9fa; + background-color: var(--bg-soft); font-weight: 600; - color: #555; + color: var(--text-muted); } table tr:hover { - background-color: #f8f9fa; + background-color: var(--table-hover); } table input[type="time"], @@ -563,13 +626,15 @@ table input[type="number"], table input[type="text"] { width: 100%; padding: 8px; - border: 1px solid #ddd; + border: 1px solid var(--border-color); border-radius: 4px; + background-color: var(--bg-surface); + color: var(--text-main); } /* Summary */ .summary { - background-color: #ecf0f1; + background-color: var(--bg-muted); padding: 20px; border-radius: 4px; margin-bottom: 20px; @@ -591,16 +656,16 @@ table input[type="text"] { .actions .help-text { margin-top: 10px; - color: #7f8c8d; + color: var(--text-soft); font-size: 14px; } /* Admin Panel */ .admin-panel { - background: white; + background: var(--bg-surface); padding: 30px; border-radius: 8px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + box-shadow: var(--shadow-sm); width: 100%; } @@ -611,7 +676,7 @@ table input[type="text"] { } .add-user-form { - background-color: #f8f9fa; + background-color: var(--bg-soft); padding: 20px; border-radius: 4px; margin-bottom: 30px; @@ -619,7 +684,7 @@ table input[type="text"] { .add-user-form h3 { margin-bottom: 20px; - color: #2c3e50; + color: var(--text-strong); } /* Role Badges */ @@ -676,7 +741,7 @@ table input[type="text"] { font-size: 12px; font-weight: 500; background-color: #6c757d; - color: white; + color: var(--text-inverse); display: inline-flex; align-items: center; gap: 5px; @@ -707,8 +772,8 @@ table input[type="text"] { border-radius: 12px; font-size: 11px; font-weight: 500; - background-color: #e0e0e0; - color: #7f8c8d; + background-color: var(--border-soft); + color: var(--text-soft); margin-left: 5px; } @@ -720,17 +785,17 @@ table input[type="text"] { /* Verwaltung Panel */ .verwaltung-panel { - background: white; + background: var(--bg-surface); padding: 30px 40px; border-radius: 8px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + box-shadow: var(--shadow-sm); width: 100%; } .empty-state { text-align: center; padding: 40px; - color: #7f8c8d; + color: var(--text-soft); } /* Timesheet Groups */ @@ -742,10 +807,10 @@ table input[type="text"] { } .timesheet-group { - border: 1px solid #e0e0e0; + border: 1px solid var(--border-soft); border-radius: 8px; overflow: hidden; - background-color: #fff; + background-color: var(--bg-surface); } .group-header { @@ -753,13 +818,13 @@ table input[type="text"] { justify-content: space-between; align-items: center; padding: 15px 20px; - background-color: #f8f9fa; - border-bottom: 2px solid #e0e0e0; + background-color: var(--bg-soft); + border-bottom: 2px solid var(--border-soft); cursor: pointer; } .group-header:hover { - background-color: #e9ecef; + background-color: var(--table-hover); } .group-info { @@ -771,17 +836,17 @@ table input[type="text"] { .group-employee { font-size: 16px; - color: #2c3e50; + color: var(--text-strong); } .group-week { font-size: 14px; - color: #555; + color: var(--text-muted); } .group-versions-info { font-size: 12px; - color: #7f8c8d; + color: var(--text-soft); } .version-count { @@ -811,7 +876,7 @@ table input[type="text"] { .versions-container { padding: 0; - background-color: #fff; + background-color: var(--bg-surface); width: 100%; overflow-x: auto; } @@ -829,7 +894,7 @@ table input[type="text"] { } .versions-table tbody tr:hover { - background-color: #f8f9fa; + background-color: var(--table-hover); } /* Timesheet Table */ @@ -844,22 +909,22 @@ table input[type="text"] { .timesheet-table td { padding: 15px 20px; text-align: left; - border-bottom: 1px solid #e0e0e0; + border-bottom: 1px solid var(--border-soft); } .timesheet-table th { - background-color: #f8f9fa; + background-color: var(--bg-soft); font-weight: 600; - color: #2c3e50; + color: var(--text-strong); } .timesheet-table tr:hover { - background-color: #f8f9fa; + background-color: var(--table-hover); } /* PDF Preview */ .pdf-preview-row { - background-color: #f8f9fa; + background-color: var(--bg-soft); } .pdf-preview-row td { @@ -868,7 +933,7 @@ table input[type="text"] { .pdf-preview-container { padding: 20px; - background-color: white; + background-color: var(--bg-surface); border-top: 2px solid #3498db; } @@ -878,12 +943,12 @@ table input[type="text"] { align-items: center; margin-bottom: 15px; padding-bottom: 15px; - border-bottom: 1px solid #e0e0e0; + border-bottom: 1px solid var(--border-soft); } .pdf-preview-header h3 { margin: 0; - color: #2c3e50; + color: var(--text-strong); font-size: 18px; } @@ -891,9 +956,9 @@ table input[type="text"] { position: relative; width: 100%; min-height: 800px; - border: 1px solid #ddd; + border: 1px solid var(--border-color); border-radius: 4px; - background-color: #f5f5f5; + background-color: var(--bg-page); } .pdf-iframe { @@ -901,7 +966,7 @@ table input[type="text"] { height: 800px; border: none; border-radius: 4px; - background-color: white; + background-color: var(--bg-surface); display: block; } @@ -937,17 +1002,17 @@ table input[type="text"] { } .btn-info { - background-color: #17a2b8; - color: white; + background-color: var(--info); + color: var(--text-inverse); } .btn-info:hover { - background-color: #138496; + background-color: var(--info-hover); } /* Utility Classes */ .text-muted { - color: #7f8c8d; + color: var(--text-soft); } /* Überstunden-Farbklassen (global genutzt, z. B. Verwaltung & Auswertung) */ @@ -963,8 +1028,8 @@ table input[type="text"] { /* Activities/Tätigkeiten */ .activities-row { - background-color: #f8f9fa; - border-top: 2px solid #e0e0e0; + background-color: var(--bg-soft); + border-top: 2px solid var(--border-soft); } .activities-cell { @@ -979,7 +1044,7 @@ table input[type="text"] { .activities-header { margin-bottom: 8px; - color: #2c3e50; + color: var(--text-strong); font-size: 14px; } @@ -1004,9 +1069,11 @@ table input[type="text"] { .activity-input, .activity-hours-input { padding: 8px 10px; - border: 1px solid #ddd; + border: 1px solid var(--border-color); border-radius: 4px; font-size: 14px; + background-color: var(--bg-surface); + color: var(--text-main); } .activity-input { @@ -1019,7 +1086,7 @@ table input[type="text"] { .activity-hours-label { font-size: 14px; - color: #555; + color: var(--text-muted); } .activity-hours-hh-input, @@ -1034,10 +1101,12 @@ table input[type="text"] { .activity-project-input { padding: 8px 10px; - border: 1px solid #ddd; + border: 1px solid var(--border-color); border-radius: 4px; font-size: 14px; width: 100%; + background-color: var(--bg-surface); + color: var(--text-main); } /* Floating Overlay für Projektsuche im Dashboard */ @@ -1049,10 +1118,10 @@ table input[type="text"] { max-width: 1100px; overflow-y: auto; overflow-x: hidden; - background: #fff; - border: 1px solid #ccc; + background: var(--bg-surface); + border: 1px solid var(--border-color); border-radius: 8px; - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); + box-shadow: var(--shadow-sm); } .project-search-overlay-inner { @@ -1061,7 +1130,7 @@ table input[type="text"] { .project-search-overlay-status { padding: 8px 0; - color: #666; + color: var(--text-muted); font-size: 14px; } @@ -1074,14 +1143,14 @@ table input[type="text"] { .project-search-overlay-table th { text-align: left; padding: 8px 10px; - border-bottom: 1px solid #ccc; - background: #f5f5f5; + border-bottom: 1px solid var(--border-color); + background: var(--bg-soft); white-space: nowrap; } .project-search-overlay-table td { padding: 8px 10px; - border-bottom: 1px solid #eee; + border-bottom: 1px solid var(--border-soft); } .project-search-overlay-table tbody tr { @@ -1089,13 +1158,13 @@ table input[type="text"] { } .project-search-overlay-table tbody tr:hover { - background: #e8f4fc; + background: var(--table-hover); } .overtime-vacation-controls { margin-top: 15px; padding-top: 15px; - border-top: 1px solid #eee; + border-top: 1px solid var(--border-soft); display: flex; gap: 15px; align-items: center; @@ -1112,9 +1181,11 @@ table input[type="text"] { .overtime-input, .vacation-select { padding: 6px 10px; - border: 1px solid #ddd; + border: 1px solid var(--border-color); border-radius: 4px; font-size: 14px; + background-color: var(--bg-surface); + color: var(--text-main); } .user-field-display { @@ -1127,11 +1198,11 @@ table input[type="text"] { /* Mitarbeiter-Gruppe (Level 1) */ .employee-group { - background-color: white; - border: 1px solid #ddd; + background-color: var(--bg-surface); + border: 1px solid var(--border-color); border-radius: 8px; padding: 25px 30px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + box-shadow: var(--shadow-sm); margin-bottom: 20px; } @@ -1150,7 +1221,7 @@ table input[type="text"] { .employee-name { font-size: 18px; - color: #2c3e50; + color: var(--text-strong); margin-bottom: 10px; } @@ -1170,7 +1241,7 @@ table input[type="text"] { .employee-details { font-size: 14px; - color: #666; + color: var(--text-muted); } .toggle-employee-btn { @@ -1189,13 +1260,13 @@ table input[type="text"] { .weeks-container { margin-top: 20px; padding-left: 25px; - border-left: 3px solid #e0e0e0; + border-left: 3px solid var(--border-soft); width: 100%; } .week-group { - background-color: #f8f9fa; - border: 1px solid #e0e0e0; + background-color: var(--bg-soft); + border: 1px solid var(--border-soft); border-radius: 6px; padding: 20px 25px; margin-bottom: 20px; @@ -1206,7 +1277,7 @@ table input[type="text"] { justify-content: space-between; align-items: flex-start; padding-bottom: 15px; - border-bottom: 1px solid #ddd; + border-bottom: 1px solid var(--border-color); margin-bottom: 15px; } @@ -1216,13 +1287,13 @@ table input[type="text"] { .week-dates { font-size: 16px; - color: #2c3e50; + color: var(--text-strong); margin-bottom: 10px; } .week-versions-info { font-size: 12px; - color: #7f8c8d; + color: var(--text-soft); margin-top: 5px; } @@ -1307,7 +1378,115 @@ input.break-below-legal { .app-footer { text-align: center; padding: 16px; - color: #888; + color: var(--text-soft); font-size: 13px; margin-top: 24px; +} + +.theme-toggle-btn { + border: 1px solid rgba(255, 255, 255, 0.35); + background: rgba(255, 255, 255, 0.12); + color: var(--text-inverse); + padding: 8px 12px; + border-radius: 999px; + cursor: pointer; + font-size: 13px; + line-height: 1; + transition: background-color 0.2s ease, transform 0.2s ease; +} + +.theme-toggle-btn:hover { + background: rgba(255, 255, 255, 0.2); + transform: translateY(-1px); +} + +[data-theme="light"] .theme-toggle-floating { + color: var(--text-main); + border-color: var(--border-color); + background: var(--bg-surface); + box-shadow: var(--shadow-sm); +} + +[data-theme="dark"] .theme-toggle-floating { + color: var(--text-main); + border-color: var(--border-color); + background: var(--bg-surface); + box-shadow: var(--shadow-sm); +} + +.theme-toggle-floating { + position: fixed; + right: 16px; + bottom: 16px; + z-index: 10000; +} + +[data-theme="dark"] .theme-toggle-btn { + border-color: rgba(226, 232, 240, 0.45); + background: rgba(15, 23, 42, 0.25); +} + +[data-theme="dark"] .theme-toggle-btn:hover { + background: rgba(15, 23, 42, 0.45); +} + +/* Globale Dark-Mode-Konsistenz auch für bestehende Inline-Styles */ +[data-theme="dark"] .help-icon { + color: var(--primary) !important; + background: rgba(59, 130, 246, 0.18) !important; +} + +[data-theme="dark"] [style*="background-color: #fff"], +[data-theme="dark"] [style*="background: #fff"], +[data-theme="dark"] [style*="background: white"], +[data-theme="dark"] [style*="background-color: white"] { + background-color: var(--bg-surface) !important; +} + +[data-theme="dark"] [style*="background-color: #f5f5f5"], +[data-theme="dark"] [style*="background: #f5f5f5"], +[data-theme="dark"] [style*="background-color: #f8f9fa"], +[data-theme="dark"] [style*="background: #f8f9fa"] { + background-color: var(--bg-soft) !important; +} + +[data-theme="dark"] [style*="border: 1px solid #dee2e6"], +[data-theme="dark"] [style*="border-top: 1px solid #dee2e6"] { + border-color: var(--border-soft) !important; +} + +[data-theme="dark"] [style*="border: 1px solid #ddd"], +[data-theme="dark"] [style*="border-top: 1px solid #ddd"], +[data-theme="dark"] [style*="border: 1px solid #e0e0e0"], +[data-theme="dark"] [style*="border-top: 1px solid #e0e0e0"] { + border-color: var(--border-color) !important; +} + +[data-theme="dark"] [style*="color: #2c3e50"], +[data-theme="dark"] [style*="color:#2c3e50"], +[data-theme="dark"] [style*="color: #333"] { + color: var(--text-strong) !important; +} + +[data-theme="dark"] [style*="color: #555"], +[data-theme="dark"] [style*="color: #666"], +[data-theme="dark"] [style*="color: #7f8c8d"], +[data-theme="dark"] [style*="color: #888"], +[data-theme="dark"] [style*="color: #999"], +[data-theme="dark"] [style*="color: #aaa"] { + color: var(--text-muted) !important; +} + +[data-theme="dark"] [style*="color: #28a745"] { + color: var(--success) !important; +} + +[data-theme="dark"] [style*="color: #dc3545"] { + color: var(--danger) !important; +} + +[data-theme="dark"] .role-switcher { + background-color: var(--bg-surface) !important; + color: var(--text-main) !important; + border-color: var(--border-color) !important; } \ No newline at end of file diff --git a/views/footer.ejs b/views/footer.ejs index ec8afa7..05d3344 100644 --- a/views/footer.ejs +++ b/views/footer.ejs @@ -1,3 +1,83 @@ + diff --git a/views/header.ejs b/views/header.ejs index 0213b6d..7484f6a 100644 --- a/views/header.ejs +++ b/views/header.ejs @@ -1,5 +1,19 @@ + + + diff --git a/views/overtime-breakdown.ejs b/views/overtime-breakdown.ejs index 0f08d50..dc987b7 100644 --- a/views/overtime-breakdown.ejs +++ b/views/overtime-breakdown.ejs @@ -22,20 +22,20 @@ } .page-title { font-size: 28px; - color: #2c3e50; + color: var(--text-strong); margin: 0; } .overtime-table { width: 100%; border-collapse: collapse; - background: white; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); + background: var(--bg-surface); + box-shadow: var(--shadow-sm); border-radius: 8px; overflow: hidden; } .overtime-table thead { - background-color: #2c3e50; - color: white; + background-color: var(--bg-soft); + color: var(--text-strong); } .overtime-table th { padding: 15px; @@ -44,10 +44,10 @@ } .overtime-table td { padding: 12px 15px; - border-bottom: 1px solid #e0e0e0; + border-bottom: 1px solid var(--border-soft); } .overtime-table tbody tr:hover { - background-color: #f8f9fa; + background-color: var(--table-hover); } .overtime-table tbody tr:last-child td { border-bottom: none; @@ -63,41 +63,41 @@ .loading { text-align: center; padding: 40px; - color: #666; + color: var(--text-muted); } .no-data { text-align: center; padding: 40px; - color: #666; + color: var(--text-muted); } .summary-box { - background: white; + background: var(--bg-surface); padding: 20px; border-radius: 8px; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); + box-shadow: var(--shadow-sm); margin-bottom: 30px; } .summary-box h3 { margin-top: 0; margin-bottom: 15px; - color: #2c3e50; + color: var(--text-strong); } .summary-item { display: flex; justify-content: space-between; padding: 10px 0; - border-bottom: 1px solid #e0e0e0; + border-bottom: 1px solid var(--border-soft); } .summary-item:last-child { border-bottom: none; } .summary-label { font-weight: 500; - color: #555; + color: var(--text-muted); } .summary-value { font-weight: 600; - color: #2c3e50; + color: var(--text-strong); } .summary-value.overtime-positive { color: #27ae60 !important; @@ -107,9 +107,9 @@ } .overtime-chart-container { margin-top: 30px; - background: #ffffff; + background: var(--bg-surface); border-radius: 8px; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); + box-shadow: var(--shadow-sm); padding: 20px; } .overtime-chart-header { @@ -121,11 +121,11 @@ .overtime-chart-title { font-size: 20px; margin: 0; - color: #2c3e50; + color: var(--text-strong); } .overtime-chart-subtitle { font-size: 13px; - color: #777; + color: var(--text-soft); text-align: right; } .overtime-chart-wrapper { @@ -135,15 +135,15 @@ } .weekly-overtime-chart-container { margin-top: 20px; - background: #ffffff; + background: var(--bg-surface); border-radius: 8px; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); + box-shadow: var(--shadow-sm); padding: 20px; } .weekly-overtime-chart-title { font-size: 18px; margin: 0 0 10px 0; - color: #2c3e50; + color: var(--text-strong); } @@ -294,6 +294,15 @@ } // formatHoursMin aus format-hours.js (window.formatHoursMin) + function getThemeChartColors() { + const styles = getComputedStyle(document.documentElement); + return { + textStrong: styles.getPropertyValue('--text-strong').trim() || '#f3f4f6', + textMuted: styles.getPropertyValue('--text-muted').trim() || '#cbd5e1', + borderSoft: styles.getPropertyValue('--border-soft').trim() || '#334155', + surface: styles.getPropertyValue('--bg-surface').trim() || '#111827' + }; + } let overtimeChartInstance = null; let weeklyChartInstance = null; @@ -649,9 +658,17 @@ }, plugins: { legend: { - display: true + display: true, + labels: { + color: getThemeChartColors().textStrong + } }, tooltip: { + backgroundColor: getThemeChartColors().surface, + titleColor: getThemeChartColors().textStrong, + bodyColor: getThemeChartColors().textStrong, + borderColor: getThemeChartColors().borderSoft, + borderWidth: 1, callbacks: { label: function(context) { // Hauptlinie: kumulierte Überstunden @@ -677,22 +694,34 @@ }, scales: { x: { + ticks: { + color: getThemeChartColors().textMuted + }, + grid: { + color: getThemeChartColors().borderSoft + }, title: { display: true, - text: 'Kalenderwoche' + text: 'Kalenderwoche', + color: getThemeChartColors().textMuted } }, y: { - title: { - display: true, - text: 'Überstunden (Stunden)' - }, ticks: { + color: getThemeChartColors().textMuted, callback: function(value) { const v = Number(value) || 0; const sign = v >= 0 ? '+' : ''; return `${sign}${formatHoursMin(v)}`; } + }, + grid: { + color: getThemeChartColors().borderSoft + }, + title: { + display: true, + text: 'Überstunden (Stunden)', + color: getThemeChartColors().textMuted } } } @@ -734,9 +763,17 @@ maintainAspectRatio: false, plugins: { legend: { - display: true + display: true, + labels: { + color: getThemeChartColors().textStrong + } }, tooltip: { + backgroundColor: getThemeChartColors().surface, + titleColor: getThemeChartColors().textStrong, + bodyColor: getThemeChartColors().textStrong, + borderColor: getThemeChartColors().borderSoft, + borderWidth: 1, callbacks: { label: function(context) { const v = context.parsed.y || 0; @@ -748,25 +785,34 @@ }, scales: { x: { + ticks: { + color: getThemeChartColors().textMuted + }, + grid: { + color: getThemeChartColors().borderSoft + }, title: { display: true, - text: 'Kalenderwoche' + text: 'Kalenderwoche', + color: getThemeChartColors().textMuted } }, y: { - title: { - display: true, - text: 'Überstunden je Woche (Stunden)' - }, ticks: { + color: getThemeChartColors().textMuted, callback: function(value) { const v = Number(value) || 0; const sign = v >= 0 ? '+' : '-'; return `${sign}${formatHoursMin(Math.abs(v))}`; } }, + title: { + display: true, + text: 'Überstunden je Woche (Stunden)', + color: getThemeChartColors().textMuted + }, grid: { - zeroLineColor: '#000' + color: getThemeChartColors().borderSoft } } }