Implement comprehensive theme system with calendar view support

- Add 8 attractive themes (Default, Ocean, Forest, Sunset, Purple, Dark, Rose, Mint)
- Extend theme system to calendar header, month view, and week view components
- Add dynamic theme-aware event color palettes that change with selected theme
- Implement CSS custom properties for consistent theming across all components
- Add localStorage persistence for user theme preferences
- Create theme-aware calendar styling including day states, headers, and grid lines
- Optimize dark theme with proper contrast and readability improvements
- Add reactive event color system that updates when themes change

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Connor Johnstone
2025-08-29 16:42:25 -04:00
parent 81805289e4
commit 4af4aafd98
11 changed files with 804 additions and 107 deletions

View File

@@ -383,7 +383,7 @@ body {
/* Calendar Component */
.calendar {
background: white;
background: var(--calendar-bg, white);
border-radius: 12px;
box-shadow: 0 4px 16px rgba(0,0,0,0.1);
overflow: hidden;
@@ -397,8 +397,8 @@ body {
align-items: center;
justify-content: space-between;
padding: 1.5rem 2rem;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
background: var(--header-bg, linear-gradient(135deg, #667eea 0%, #764ba2 100%));
color: var(--header-text, white);
}
.month-year {
@@ -486,7 +486,7 @@ body {
grid-template-columns: repeat(7, 1fr);
grid-template-rows: auto repeat(6, 1fr);
flex: 1;
background: white;
background: var(--calendar-bg, white);
gap: 0;
}
@@ -495,41 +495,42 @@ body {
display: flex;
flex-direction: column;
height: 100%;
background: white;
background: var(--calendar-bg, white);
}
/* Week Header */
.week-header {
display: grid;
grid-template-columns: 80px repeat(7, 1fr);
background: #f8f9fa;
border-bottom: 2px solid #e9ecef;
background: var(--weekday-header-bg, #f8f9fa);
border-bottom: 2px solid var(--time-label-border, #e9ecef);
position: sticky;
top: 0;
z-index: 10;
}
.time-gutter {
background: #f8f9fa;
border-right: 1px solid #e9ecef;
background: var(--time-label-bg, #f8f9fa);
border-right: 1px solid var(--time-label-border, #e9ecef);
}
.week-day-header {
padding: 1rem;
text-align: center;
border-right: 1px solid #e9ecef;
background: #f8f9fa;
border-right: 1px solid var(--time-label-border, #e9ecef);
background: var(--weekday-header-bg, #f8f9fa);
color: var(--weekday-header-text, inherit);
}
.week-day-header.today {
background: #e3f2fd;
color: #1976d2;
background: var(--calendar-today-bg, #e3f2fd);
color: var(--calendar-today-text, #1976d2);
}
.weekday-name {
font-size: 0.9rem;
font-weight: 600;
color: #666;
color: var(--weekday-header-text, #666);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 0.25rem;
@@ -541,7 +542,7 @@ body {
}
.week-day-header.today .weekday-name {
color: #1976d2;
color: var(--calendar-today-text, #1976d2);
}
/* Week Content */
@@ -559,8 +560,8 @@ body {
/* Time Labels */
.time-labels {
background: #f8f9fa;
border-right: 1px solid #e9ecef;
background: var(--time-label-bg, #f8f9fa);
border-right: 1px solid var(--time-label-border, #e9ecef);
position: sticky;
left: 0;
z-index: 5;
@@ -573,8 +574,8 @@ body {
justify-content: center;
padding-top: 0.5rem;
font-size: 0.75rem;
color: #666;
border-bottom: 1px solid #f0f0f0;
color: var(--time-label-text, #666);
border-bottom: 1px solid var(--calendar-border, #f0f0f0);
font-weight: 500;
}
@@ -593,7 +594,7 @@ body {
.week-day-column {
position: relative;
border-right: 1px solid #e9ecef;
border-right: 1px solid var(--time-label-border, #e9ecef);
min-height: 1500px; /* 25 time labels × 60px = 1500px total */
}
@@ -602,20 +603,20 @@ body {
}
.week-day-column.today {
background: #fafffe;
background: var(--calendar-day-hover, #fafffe);
}
/* Time Slots */
.time-slot {
height: 60px;
border-bottom: 1px solid #f0f0f0;
border-bottom: 1px solid var(--calendar-border, #f0f0f0);
position: relative;
pointer-events: none; /* Don't capture mouse events */
}
.time-slot-half {
height: 30px;
border-bottom: 1px dotted #f5f5f5;
border-bottom: 1px dotted var(--calendar-border, #f5f5f5);
pointer-events: none; /* Don't capture mouse events */
}
@@ -839,7 +840,7 @@ body {
grid-template-columns: repeat(7, 1fr);
grid-template-rows: auto 1fr;
flex: 1;
background: white;
background: var(--calendar-bg, white);
}
.week-view .calendar-day {
@@ -859,7 +860,7 @@ body {
}
.calendar-day {
border: 1px solid #f0f0f0;
border: 1px solid var(--calendar-border, #f0f0f0);
padding: 0.75rem;
display: flex;
flex-direction: column;
@@ -867,52 +868,53 @@ body {
transition: background-color 0.2s;
position: relative;
overflow: hidden;
background: var(--calendar-day-bg, white);
}
.calendar-day:hover {
background-color: #f8f9ff;
background-color: var(--calendar-day-hover, #f8f9ff);
}
.calendar-day.current-month {
background: white;
background: var(--calendar-day-bg, white);
}
.calendar-day.prev-month,
.calendar-day.next-month {
background: #fafafa;
color: #ccc;
background: var(--calendar-day-prev-next, #fafafa);
color: var(--calendar-day-prev-next-text, #ccc);
}
.calendar-day.today {
background: #e3f2fd;
border: 2px solid #2196f3;
background: var(--calendar-today-bg, #e3f2fd);
border: 2px solid var(--calendar-today-border, #2196f3);
}
.calendar-day.has-events {
background: #fff3e0;
background: var(--calendar-has-events-bg, #fff3e0);
}
.calendar-day.today.has-events {
background: #e1f5fe;
background: var(--calendar-today-bg, #e1f5fe);
}
.calendar-day.selected {
background: #e8f5e8;
border: 2px solid #4caf50;
background: var(--calendar-selected-bg, #e8f5e8);
border: 2px solid var(--calendar-selected-border, #4caf50);
box-shadow: 0 0 8px rgba(76, 175, 80, 0.3);
}
.calendar-day.selected.has-events {
background: #f1f8e9;
background: var(--calendar-selected-bg, #f1f8e9);
}
.calendar-day.selected.today {
background: #e0f2f1;
border: 2px solid #4caf50;
background: var(--calendar-selected-bg, #e0f2f1);
border: 2px solid var(--calendar-selected-border, #4caf50);
}
.calendar-day.selected .day-number {
color: #2e7d32;
color: var(--calendar-selected-text, #2e7d32);
font-weight: 700;
}
@@ -923,7 +925,7 @@ body {
}
.calendar-day.today .day-number {
color: #1976d2;
color: var(--calendar-today-text, #1976d2);
}
.day-events {
@@ -1896,4 +1898,376 @@ body {
.recurring-option .option-description {
font-size: 0.8rem;
}
}
/* Theme Selector Styles */
.theme-selector {
margin-bottom: 1rem;
}
.theme-selector-dropdown {
width: 100%;
padding: 0.5rem;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 6px;
color: white;
font-size: 0.85rem;
cursor: pointer;
transition: all 0.2s ease;
}
.theme-selector-dropdown:hover {
background: rgba(255, 255, 255, 0.15);
border-color: rgba(255, 255, 255, 0.3);
}
.theme-selector-dropdown:focus {
outline: none;
background: rgba(255, 255, 255, 0.2);
border-color: rgba(255, 255, 255, 0.4);
}
.theme-selector-dropdown option {
background: #333;
color: white;
padding: 0.5rem;
}
/* Theme Definitions */
:root {
/* Default Theme */
--primary-gradient: linear-gradient(180deg, #667eea 0%, #764ba2 100%);
--primary-bg: #f8f9fa;
--primary-text: #333;
--sidebar-bg: linear-gradient(180deg, #667eea 0%, #764ba2 100%);
--sidebar-text: white;
--header-bg: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
--header-text: white;
--card-bg: white;
--border-color: #e9ecef;
--accent-color: #667eea;
--calendar-bg: white;
--calendar-border: #f0f0f0;
--calendar-day-bg: white;
--calendar-day-hover: #f8f9ff;
--calendar-day-prev-next: #fafafa;
--calendar-day-prev-next-text: #ccc;
--calendar-today-bg: #e3f2fd;
--calendar-today-border: #2196f3;
--calendar-today-text: #1976d2;
--calendar-selected-bg: #e8f5e8;
--calendar-selected-border: #4caf50;
--calendar-selected-text: #2e7d32;
--calendar-has-events-bg: #fff3e0;
--weekday-header-bg: #f8f9fa;
--weekday-header-text: #666;
--time-label-bg: #f8f9fa;
--time-label-text: #666;
--time-label-border: #e9ecef;
--event-colors: #3B82F6, #10B981, #F59E0B, #EF4444, #8B5CF6, #06B6D4, #84CC16, #F97316, #EC4899, #6366F1, #14B8A6, #F3B806, #8B5A2B, #6B7280, #DC2626, #7C3AED;
}
/* Ocean Theme */
[data-theme="ocean"] {
--primary-gradient: linear-gradient(180deg, #2196F3 0%, #0277BD 100%);
--primary-bg: #e3f2fd;
--primary-text: #0d47a1;
--sidebar-bg: linear-gradient(180deg, #2196F3 0%, #0277BD 100%);
--sidebar-text: white;
--header-bg: linear-gradient(135deg, #2196F3 0%, #0277BD 100%);
--header-text: white;
--card-bg: #ffffff;
--border-color: #bbdefb;
--accent-color: #2196F3;
--calendar-bg: #ffffff;
--calendar-border: #bbdefb;
--calendar-day-bg: #ffffff;
--calendar-day-hover: #e1f5fe;
--calendar-day-prev-next: #f3f8ff;
--calendar-day-prev-next-text: #90caf9;
--calendar-today-bg: #b3e5fc;
--calendar-today-border: #0277BD;
--calendar-today-text: #01579b;
--calendar-selected-bg: #e0f7fa;
--calendar-selected-border: #00acc1;
--calendar-selected-text: #00695c;
--calendar-has-events-bg: #fff8e1;
--weekday-header-bg: #e3f2fd;
--weekday-header-text: #0d47a1;
--time-label-bg: #e3f2fd;
--time-label-text: #0d47a1;
--time-label-border: #bbdefb;
--event-colors: #2196F3, #03DAC6, #FF9800, #F44336, #9C27B0, #00BCD4, #8BC34A, #FF5722, #E91E63, #3F51B5, #009688, #FFC107, #607D8B, #795548, #E53935, #673AB7;
}
[data-theme="ocean"] body {
background-color: var(--primary-bg);
color: var(--primary-text);
}
[data-theme="ocean"] .app-sidebar {
background: var(--sidebar-bg);
}
/* Forest Theme */
[data-theme="forest"] {
--primary-gradient: linear-gradient(180deg, #4CAF50 0%, #2E7D32 100%);
--primary-bg: #e8f5e8;
--primary-text: #1b5e20;
--sidebar-bg: linear-gradient(180deg, #4CAF50 0%, #2E7D32 100%);
--sidebar-text: white;
--header-bg: linear-gradient(135deg, #4CAF50 0%, #2E7D32 100%);
--header-text: white;
--card-bg: #ffffff;
--border-color: #c8e6c9;
--accent-color: #4CAF50;
--calendar-bg: #ffffff;
--calendar-border: #c8e6c9;
--calendar-day-bg: #ffffff;
--calendar-day-hover: #f1f8e9;
--calendar-day-prev-next: #f9fbe7;
--calendar-day-prev-next-text: #a5d6a7;
--calendar-today-bg: #c8e6c9;
--calendar-today-border: #2E7D32;
--calendar-today-text: #1b5e20;
--calendar-selected-bg: #e8f5e8;
--calendar-selected-border: #388e3c;
--calendar-selected-text: #2e7d32;
--calendar-has-events-bg: #fff3e0;
--weekday-header-bg: #e8f5e8;
--weekday-header-text: #1b5e20;
--time-label-bg: #e8f5e8;
--time-label-text: #1b5e20;
--time-label-border: #c8e6c9;
--event-colors: #4CAF50, #8BC34A, #FF9800, #FF5722, #9C27B0, #03DAC6, #CDDC39, #FF6F00, #E91E63, #3F51B5, #009688, #FFC107, #795548, #607D8B, #F44336, #673AB7;
}
[data-theme="forest"] body {
background-color: var(--primary-bg);
color: var(--primary-text);
}
[data-theme="forest"] .app-sidebar {
background: var(--sidebar-bg);
}
/* Sunset Theme */
[data-theme="sunset"] {
--primary-gradient: linear-gradient(180deg, #FF9800 0%, #F57C00 100%);
--primary-bg: #fff3e0;
--primary-text: #e65100;
--sidebar-bg: linear-gradient(180deg, #FF9800 0%, #F57C00 100%);
--sidebar-text: white;
--header-bg: linear-gradient(135deg, #FF9800 0%, #F57C00 100%);
--header-text: white;
--card-bg: #ffffff;
--border-color: #ffcc02;
--accent-color: #FF9800;
--calendar-bg: #ffffff;
--calendar-border: #ffe0b2;
--calendar-day-bg: #ffffff;
--calendar-day-hover: #fff8e1;
--calendar-day-prev-next: #fffde7;
--calendar-day-prev-next-text: #ffcc02;
--calendar-today-bg: #ffe0b2;
--calendar-today-border: #F57C00;
--calendar-today-text: #e65100;
--calendar-selected-bg: #fff3e0;
--calendar-selected-border: #ff8f00;
--calendar-selected-text: #ff6f00;
--calendar-has-events-bg: #f3e5f5;
--weekday-header-bg: #fff3e0;
--weekday-header-text: #e65100;
--time-label-bg: #fff3e0;
--time-label-text: #e65100;
--time-label-border: #ffe0b2;
--event-colors: #FF9800, #FF5722, #F44336, #E91E63, #9C27B0, #673AB7, #3F51B5, #2196F3, #03DAC6, #009688, #4CAF50, #8BC34A, #CDDC39, #FFC107, #FF6F00, #795548;
}
[data-theme="sunset"] body {
background-color: var(--primary-bg);
color: var(--primary-text);
}
[data-theme="sunset"] .app-sidebar {
background: var(--sidebar-bg);
}
/* Purple Theme */
[data-theme="purple"] {
--primary-gradient: linear-gradient(180deg, #9C27B0 0%, #6A1B9A 100%);
--primary-bg: #f3e5f5;
--primary-text: #4a148c;
--sidebar-bg: linear-gradient(180deg, #9C27B0 0%, #6A1B9A 100%);
--sidebar-text: white;
--header-bg: linear-gradient(135deg, #9C27B0 0%, #6A1B9A 100%);
--header-text: white;
--card-bg: #ffffff;
--border-color: #ce93d8;
--accent-color: #9C27B0;
--calendar-bg: #ffffff;
--calendar-border: #ce93d8;
--calendar-day-bg: #ffffff;
--calendar-day-hover: #f8e9fc;
--calendar-day-prev-next: #fce4ec;
--calendar-day-prev-next-text: #ce93d8;
--calendar-today-bg: #e1bee7;
--calendar-today-border: #6A1B9A;
--calendar-today-text: #4a148c;
--calendar-selected-bg: #f3e5f5;
--calendar-selected-border: #8e24aa;
--calendar-selected-text: #6a1b9a;
--calendar-has-events-bg: #fff3e0;
--weekday-header-bg: #f3e5f5;
--weekday-header-text: #4a148c;
--time-label-bg: #f3e5f5;
--time-label-text: #4a148c;
--time-label-border: #ce93d8;
--event-colors: #9C27B0, #673AB7, #3F51B5, #2196F3, #03DAC6, #009688, #4CAF50, #8BC34A, #CDDC39, #FFC107, #FF9800, #FF5722, #F44336, #E91E63, #795548, #607D8B;
}
[data-theme="purple"] body {
background-color: var(--primary-bg);
color: var(--primary-text);
}
[data-theme="purple"] .app-sidebar {
background: var(--sidebar-bg);
}
/* Dark Theme */
[data-theme="dark"] {
--primary-gradient: linear-gradient(180deg, #424242 0%, #212121 100%);
--primary-bg: #121212;
--primary-text: #ffffff;
--sidebar-bg: linear-gradient(180deg, #424242 0%, #212121 100%);
--sidebar-text: white;
--header-bg: linear-gradient(135deg, #424242 0%, #212121 100%);
--header-text: white;
--card-bg: #1e1e1e;
--border-color: #333333;
--accent-color: #666666;
--calendar-bg: #1f1f1f;
--calendar-border: #333333;
--calendar-day-bg: #1f1f1f;
--calendar-day-hover: #2a2a2a;
--calendar-day-prev-next: #1a1a1a;
--calendar-day-prev-next-text: #555;
--calendar-today-bg: #2d2d2d;
--calendar-today-border: #bb86fc;
--calendar-today-text: #bb86fc;
--calendar-selected-bg: #2a2a2a;
--calendar-selected-border: #bb86fc;
--calendar-selected-text: #bb86fc;
--calendar-has-events-bg: #272727;
--weekday-header-bg: #1a1a1a;
--weekday-header-text: #e0e0e0;
--time-label-bg: #1a1a1a;
--time-label-text: #e0e0e0;
--time-label-border: #333333;
--event-colors: #bb86fc, #03dac6, #cf6679, #ff9800, #4caf50, #2196f3, #9c27b0, #f44336, #795548, #607d8b, #e91e63, #3f51b5, #009688, #8bc34a, #ffc107, #ff5722;
}
[data-theme="dark"] body {
background-color: var(--primary-bg);
color: var(--primary-text);
}
[data-theme="dark"] .app-sidebar {
background: var(--sidebar-bg);
}
[data-theme="dark"] .app-main {
background-color: var(--primary-bg);
}
[data-theme="dark"] .calendar-day {
background: var(--card-bg);
border-color: var(--border-color);
color: var(--primary-text);
}
/* Rose Theme */
[data-theme="rose"] {
--primary-gradient: linear-gradient(180deg, #E91E63 0%, #AD1457 100%);
--primary-bg: #fce4ec;
--primary-text: #880e4f;
--sidebar-bg: linear-gradient(180deg, #E91E63 0%, #AD1457 100%);
--sidebar-text: white;
--header-bg: linear-gradient(135deg, #E91E63 0%, #AD1457 100%);
--header-text: white;
--card-bg: #ffffff;
--border-color: #f8bbd9;
--accent-color: #E91E63;
--calendar-bg: #ffffff;
--calendar-border: #f8bbd9;
--calendar-day-bg: #ffffff;
--calendar-day-hover: #fdf2f8;
--calendar-day-prev-next: #fef7ff;
--calendar-day-prev-next-text: #f8bbd9;
--calendar-today-bg: #f48fb1;
--calendar-today-border: #AD1457;
--calendar-today-text: #880e4f;
--calendar-selected-bg: #fce4ec;
--calendar-selected-border: #c2185b;
--calendar-selected-text: #ad1457;
--calendar-has-events-bg: #fff3e0;
--weekday-header-bg: #fce4ec;
--weekday-header-text: #880e4f;
--time-label-bg: #fce4ec;
--time-label-text: #880e4f;
--time-label-border: #f8bbd9;
--event-colors: #E91E63, #9C27B0, #673AB7, #3F51B5, #2196F3, #03DAC6, #009688, #4CAF50, #8BC34A, #CDDC39, #FFC107, #FF9800, #FF5722, #F44336, #795548, #607D8B;
}
[data-theme="rose"] body {
background-color: var(--primary-bg);
color: var(--primary-text);
}
[data-theme="rose"] .app-sidebar {
background: var(--sidebar-bg);
}
/* Mint Theme */
[data-theme="mint"] {
--primary-gradient: linear-gradient(180deg, #26A69A 0%, #00695C 100%);
--primary-bg: #e0f2f1;
--primary-text: #004d40;
--sidebar-bg: linear-gradient(180deg, #26A69A 0%, #00695C 100%);
--sidebar-text: white;
--header-bg: linear-gradient(135deg, #26A69A 0%, #00695C 100%);
--header-text: white;
--card-bg: #ffffff;
--border-color: #b2dfdb;
--accent-color: #26A69A;
--calendar-bg: #ffffff;
--calendar-border: #b2dfdb;
--calendar-day-bg: #ffffff;
--calendar-day-hover: #f0fdfc;
--calendar-day-prev-next: #f7ffff;
--calendar-day-prev-next-text: #b2dfdb;
--calendar-today-bg: #b2dfdb;
--calendar-today-border: #00695C;
--calendar-today-text: #004d40;
--calendar-selected-bg: #e0f2f1;
--calendar-selected-border: #00897b;
--calendar-selected-text: #00695c;
--calendar-has-events-bg: #fff3e0;
--weekday-header-bg: #e0f2f1;
--weekday-header-text: #004d40;
--time-label-bg: #e0f2f1;
--time-label-text: #004d40;
--time-label-border: #b2dfdb;
--event-colors: #26A69A, #009688, #4CAF50, #8BC34A, #CDDC39, #FFC107, #FF9800, #FF5722, #F44336, #E91E63, #9C27B0, #673AB7, #3F51B5, #2196F3, #795548, #607D8B;
}
[data-theme="mint"] body {
background-color: var(--primary-bg);
color: var(--primary-text);
}
[data-theme="mint"] .app-sidebar {
background: var(--sidebar-bg);
}