diff --git a/_includes/random-number-generator.html b/_includes/random-number-generator.html index 44f6345..baf937b 100644 --- a/_includes/random-number-generator.html +++ b/_includes/random-number-generator.html @@ -209,6 +209,67 @@

} } +/* Dark mode overrides */ +[data-theme="dark"] .form-label { + color: #d1d5db; +} + +[data-theme="dark"] .form-input { + background: #374151; + border-color: #4b5563; + color: #f9fafb; +} + +[data-theme="dark"] .form-input:focus { + background: #1f2937; + border-color: #667eea; +} + +[data-theme="dark"] .form-input:hover { + background: #374151; + border-color: #6b7280; +} + +[data-theme="dark"] .card.result-card { + background: #1f2937; + border-color: #059669; +} + +[data-theme="dark"] .result-header { + color: #34d399; +} + +@media (prefers-color-scheme: dark) { + :root:not([data-theme="light"]) .form-label { + color: #d1d5db; + } + + :root:not([data-theme="light"]) .form-input { + background: #374151; + border-color: #4b5563; + color: #f9fafb; + } + + :root:not([data-theme="light"]) .form-input:focus { + background: #1f2937; + border-color: #667eea; + } + + :root:not([data-theme="light"]) .form-input:hover { + background: #374151; + border-color: #6b7280; + } + + :root:not([data-theme="light"]) .card.result-card { + background: #1f2937; + border-color: #059669; + } + + :root:not([data-theme="light"]) .result-header { + color: #34d399; + } +} + /* Mobile responsive */ @media (max-width: 640px) { .random-generator-container { diff --git a/_layouts/default.html b/_layouts/default.html index 735b7be..05d392f 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -2,6 +2,14 @@ + + {% if page.title %}{{ page.title }} – {% endif %}{{ site.name }} – {{ site.description }} {% seo title=false %} {% include meta.html %} @@ -71,6 +79,7 @@

{{ site.name }}

🤝 Join us! + @@ -138,5 +147,60 @@

{{ site.name }}

} }); + + diff --git a/_layouts/event.html b/_layouts/event.html index 7280602..81e2322 100644 --- a/_layouts/event.html +++ b/_layouts/event.html @@ -228,6 +228,97 @@ display: none; } } + + /* Dark mode overrides */ + [data-theme="dark"] .event-detail-card { + background: #1f2937; + border-color: #374151; + } + + [data-theme="dark"] .event-detail-title { + color: #f9fafb; + } + + [data-theme="dark"] .event-meta-section { + border-bottom-color: #374151; + } + + [data-theme="dark"] .meta-badge { + background: #374151; + color: #d1d5db; + } + + [data-theme="dark"] .talk-card { + background: #111827; + border-color: #374151; + } + + [data-theme="dark"] .talk-title { + color: #f9fafb; + } + + [data-theme="dark"] .slides-container, + [data-theme="dark"] .video-container { + background: #1f2937; + border-color: #374151; + } + + [data-theme="dark"] .slides-container h4, + [data-theme="dark"] .video-container h4 { + color: #d1d5db; + } + + [data-theme="dark"] .no-slides-message { + background: rgba(245, 158, 11, 0.1); + border-color: #d97706; + color: #fcd34d; + } + + @media (prefers-color-scheme: dark) { + :root:not([data-theme="light"]) .event-detail-card { + background: #1f2937; + border-color: #374151; + } + + :root:not([data-theme="light"]) .event-detail-title { + color: #f9fafb; + } + + :root:not([data-theme="light"]) .event-meta-section { + border-bottom-color: #374151; + } + + :root:not([data-theme="light"]) .meta-badge { + background: #374151; + color: #d1d5db; + } + + :root:not([data-theme="light"]) .talk-card { + background: #111827; + border-color: #374151; + } + + :root:not([data-theme="light"]) .talk-title { + color: #f9fafb; + } + + :root:not([data-theme="light"]) .slides-container, + :root:not([data-theme="light"]) .video-container { + background: #1f2937; + border-color: #374151; + } + + :root:not([data-theme="light"]) .slides-container h4, + :root:not([data-theme="light"]) .video-container h4 { + color: #d1d5db; + } + + :root:not([data-theme="light"]) .no-slides-message { + background: rgba(245, 158, 11, 0.1); + border-color: #d97706; + color: #fcd34d; + } + } {% assign event_date = page.date | date: "%Y-%m-%d" %} diff --git a/_pages/statistics.md b/_pages/statistics.md index c7afccb..3495031 100644 --- a/_pages/statistics.md +++ b/_pages/statistics.md @@ -229,9 +229,22 @@ document.addEventListener('DOMContentLoaded', function() { Object.values(fallbacks).forEach(fb => fb.style.display = 'block'); } + function getChartColors() { + const attr = document.documentElement.getAttribute('data-theme'); + const dark = attr === 'dark' || (!attr && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches); + return { + tickColor: dark ? 'rgba(209, 213, 219, 0.9)' : 'rgba(75, 85, 99, 0.8)', + gridColor: dark ? 'rgba(75, 85, 99, 0.5)' : 'rgba(229, 231, 235, 0.5)' + }; + } + + const chartInstances = []; + function createCharts() { chartsStatus.style.display = 'none'; + const { tickColor, gridColor } = getChartColors(); + // Generate dynamic data from Jekyll - only include past events const today = new Date(); const eventsData = [ @@ -350,6 +363,7 @@ document.addEventListener('DOMContentLoaded', function() { // Host Organizations Chart const hostCtx = document.getElementById('hostOrganizationsChart'); + let hostChart; if (hostCtx) { // Create gradient for host organizations const hostGradient = hostCtx.getContext('2d').createLinearGradient(0, 0, 0, 400); @@ -362,7 +376,7 @@ document.addEventListener('DOMContentLoaded', function() { hostHoverGradient.addColorStop(0.5, 'rgba(67, 56, 202, 0.95)'); hostHoverGradient.addColorStop(1, 'rgba(79, 70, 229, 0.9)'); - new Chart(hostCtx, { + hostChart = new Chart(hostCtx, { type: 'bar', data: { labels: hostLabels, @@ -403,17 +417,17 @@ document.addEventListener('DOMContentLoaded', function() { beginAtZero: true, ticks: { stepSize: 1, - color: 'rgba(75, 85, 99, 0.8)', + color: tickColor, font: { size: 12 } }, grid: { - color: 'rgba(229, 231, 235, 0.5)', + color: gridColor, drawBorder: false } }, x: { ticks: { - color: 'rgba(75, 85, 99, 0.8)', + color: tickColor, font: { size: 11 }, maxRotation: 45, minRotation: 45 @@ -437,6 +451,7 @@ document.addEventListener('DOMContentLoaded', function() { // Top Speakers Chart const speakersCtx = document.getElementById('topSpeakersChart'); + let speakersChart; if (speakersCtx) { // Create gradient for speakers const speakerGradient = speakersCtx.getContext('2d').createLinearGradient(0, 0, 0, 400); @@ -449,7 +464,7 @@ document.addEventListener('DOMContentLoaded', function() { speakerHoverGradient.addColorStop(0.5, 'rgba(147, 51, 234, 0.95)'); speakerHoverGradient.addColorStop(1, 'rgba(126, 34, 206, 0.9)'); - new Chart(speakersCtx, { + speakersChart = new Chart(speakersCtx, { type: 'bar', data: { labels: speakerLabels, @@ -490,17 +505,17 @@ document.addEventListener('DOMContentLoaded', function() { beginAtZero: true, ticks: { stepSize: 1, - color: 'rgba(75, 85, 99, 0.8)', + color: tickColor, font: { size: 12 } }, grid: { - color: 'rgba(229, 231, 235, 0.5)', + color: gridColor, drawBorder: false } }, x: { ticks: { - color: 'rgba(75, 85, 99, 0.8)', + color: tickColor, font: { size: 11 }, maxRotation: 45, minRotation: 45 @@ -524,8 +539,9 @@ document.addEventListener('DOMContentLoaded', function() { // Participants Trends Chart const participantsCtx = document.getElementById('participantsTrendsChart'); + let participantsChart; if (participantsCtx) { - new Chart(participantsCtx, { + participantsChart = new Chart(participantsCtx, { type: 'line', data: { labels: participantLabels, @@ -546,18 +562,39 @@ document.addEventListener('DOMContentLoaded', function() { scales: { y: { beginAtZero: true, - max: Math.max(...participantValues) + 10 + max: Math.max(...participantValues) + 10, + ticks: { + color: tickColor, + font: { size: 12 } + }, + grid: { + color: gridColor, + drawBorder: false + } }, x: { ticks: { maxRotation: 45, - minRotation: 45 + minRotation: 45, + color: tickColor, + font: { size: 11 } } } } } }); } + chartInstances.push(...[hostChart, speakersChart, participantsChart].filter(Boolean)); } + + document.addEventListener('themechange', function() { + const { tickColor, gridColor } = getChartColors(); + chartInstances.forEach(function(chart) { + if (chart.options.scales?.y?.ticks) chart.options.scales.y.ticks.color = tickColor; + if (chart.options.scales?.y?.grid) chart.options.scales.y.grid.color = gridColor; + if (chart.options.scales?.x?.ticks) chart.options.scales.x.ticks.color = tickColor; + chart.update('none'); + }); + }); }); diff --git a/_pages/team.md b/_pages/team.md index e7f8d15..ac87fbc 100644 --- a/_pages/team.md +++ b/_pages/team.md @@ -144,7 +144,7 @@ permalink: /team/ h3 { margin-bottom: 0.5rem; - text-align: left; + text-align: center; font-size: 1.75rem; &::after { @@ -159,6 +159,7 @@ permalink: /team/ margin-bottom: 1.5rem; text-transform: uppercase; letter-spacing: 0.05em; + text-align: center; } p { @@ -276,5 +277,54 @@ permalink: /team/ } } } + +/* Dark mode overrides */ +[data-theme="dark"] .team-member { + background: #1f2937; + border-color: #374151; +} + +[data-theme="dark"] .team-member .member-info p { + color: #9ca3af; +} + +[data-theme="dark"] .team-member .member-info .member-links a.btn-outline { + color: #818cf8; + border-color: #818cf8; +} + +[data-theme="dark"] .team-member .member-info .member-links a.btn-outline:hover { + background: #818cf8; + color: white; +} + +[data-theme="dark"] .join-team-section .card p { + color: #9ca3af; +} + +@media (prefers-color-scheme: dark) { + :root:not([data-theme="light"]) .team-member { + background: #1f2937; + border-color: #374151; + } + + :root:not([data-theme="light"]) .team-member .member-info p { + color: #9ca3af; + } + + :root:not([data-theme="light"]) .team-member .member-info .member-links a.btn-outline { + color: #818cf8; + border-color: #818cf8; + } + + :root:not([data-theme="light"]) .team-member .member-info .member-links a.btn-outline:hover { + background: #818cf8; + color: white; + } + + :root:not([data-theme="light"]) .join-team-section .card p { + color: #9ca3af; + } +} diff --git a/assets/scripts/generate-random-numbers.js b/assets/scripts/generate-random-numbers.js index 218dac5..78929af 100644 --- a/assets/scripts/generate-random-numbers.js +++ b/assets/scripts/generate-random-numbers.js @@ -2,7 +2,12 @@ function generateRandomNumbers() { const resultCard = document.getElementById('result-card'); const resultHeader = document.getElementById('result-header'); const resultContainer = document.getElementById('result'); - + + // Detect current theme + const attr = document.documentElement.getAttribute('data-theme'); + const isDark = attr === 'dark' || + (!attr && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches); + // Clear previous results resultHeader.innerText = ''; resultContainer.innerHTML = ''; @@ -22,7 +27,7 @@ function generateRandomNumbers() { resultContainer.innerHTML = '

Please check your input values. Make sure minimum < maximum and number of results ≤ range size.

'; resultCard.style.display = 'block'; resultCard.style.border = '2px solid #ef4444'; - resultCard.style.background = 'linear-gradient(135deg, #fef2f2 0%, #fef7f7 100%)'; + resultCard.style.background = isDark ? '#1f2937' : 'linear-gradient(135deg, #fef2f2 0%, #fef7f7 100%)'; return; } @@ -34,9 +39,9 @@ function generateRandomNumbers() { // Show result card immediately resultHeader.innerText = '🎉 Your lucky numbers are:'; - resultHeader.style.color = '#065f46'; + resultHeader.style.color = isDark ? '#34d399' : '#065f46'; resultCard.style.border = '2px solid #10b981'; - resultCard.style.background = 'linear-gradient(135deg, #ecfdf5 0%, #f0fdf4 100%)'; + resultCard.style.background = isDark ? '#1f2937' : 'linear-gradient(135deg, #ecfdf5 0%, #f0fdf4 100%)'; resultCard.style.display = 'block'; // Smooth scroll to results diff --git a/assets/style.scss b/assets/style.scss index 2893aa7..0bab5d8 100644 --- a/assets/style.scss +++ b/assets/style.scss @@ -237,6 +237,42 @@ a:hover { font-size: 1rem; } +/* Theme toggle button */ +.theme-toggle-btn { + background: rgba(255, 255, 255, 0.15); + border: 1px solid rgba(255, 255, 255, 0.35); + border-radius: 0.5rem; + color: rgba(255, 255, 255, 0.9); + cursor: pointer; + padding: 0.5rem; + display: flex; + align-items: center; + justify-content: center; + line-height: 1; + transition: all 0.3s ease; + + svg { + flex-shrink: 0; + display: block; + } + + &:hover { + color: white; + background: rgba(255, 255, 255, 0.25); + border-color: rgba(255, 255, 255, 0.55); + } +} + +@media (max-width: 1024px) { + .theme-toggle-btn { + width: auto; + padding: 0.75rem; + border: 1px solid rgba(255, 255, 255, 0.3); + align-self: center; + margin: 0 auto; + } +} + /* Mobile Menu */ .mobile-menu-btn { display: flex; @@ -1637,3 +1673,329 @@ pre code { background: none; padding: 0; } + +/* ============================================== + DARK MODE + Applied via [data-theme="dark"] on + (set by the toggle button / JS) + and via @media (prefers-color-scheme: dark) + when no manual override is stored. + ============================================== */ + +@mixin dark-theme { + color-scheme: dark; + + body { + color: #e5e7eb; + background-color: #111827; + } + + h1, h2, h3, h4, h5, h6 { + color: #f9fafb; + } + + a { + color: #818cf8; + } + + a:hover { + color: #a5b4fc; + } + + // Cards + .card { + background: #1f2937; + border-color: #374151; + } + + .card-header { + border-bottom-color: #374151; + } + + .card-header h2, + .card-header h3 { + color: #818cf8; + } + + // Statistics + .stat-section { + background: #1f2937; + border-color: #374151; + } + + .chart-title { + color: #f9fafb; + } + + .stats-table th, + .stats-table td { + border-bottom-color: #374151; + } + + .stats-table th { + background-color: #374151; + color: #f9fafb; + } + + .stats-table tbody tr:hover { + background-color: #374151; + } + + .number-cell { + color: #818cf8; + } + + // Events + .event-card { + background: #1f2937; + border-color: #374151; + } + + .event-title a { + color: #f9fafb; + } + + .event-title a:hover { + color: #818cf8; + } + + .event-meta { + color: #9ca3af; + } + + .talk-item { + border-bottom-color: #374151; + } + + .talk-title { + color: #f3f4f6; + } + + .talk-speaker { + color: #9ca3af; + } + + .talk-speaker-name { + color: #d1d5db; + } + + .more-talks { + background: #374151; + } + + .more-talks .talk-title { + color: #9ca3af; + } + + // Footer + .site-footer { + background: #1f2937; + border-top-color: #374151; + } + + .footer-text { + color: #9ca3af; + } + + .footer-social a { + background: rgba(255, 255, 255, 0.1); + border-color: rgba(255, 255, 255, 0.15); + } + + .footer-social a:hover { + background: rgba(255, 255, 255, 0.2); + border-color: rgba(255, 255, 255, 0.25); + } + + // Code + code, + pre, + .highlight { + background: #1f2937; + color: #e5e7eb; + } + + // Team + .member-name { + color: #f9fafb; + } + + .member-bio { + color: #d1d5db; + } + + // Hero + .hero-content h1 { + color: #f9fafb; + } + + // Utility / boxes + .highlight-box, + .cta-box { + background: #1f2937; + } + + .highlight-box h4, + .cta-box h4 { + color: #818cf8; + } + + .small-text { + color: #9ca3af; + } + + // Borders in lists / schedules + .requirements-list li { + border-bottom-color: #374151; + } + + .requirements-list strong { + color: #818cf8; + } + + .schedule .schedule-item { + border-bottom-color: #374151; + } + + .schedule .time { + color: #818cf8; + } + + .meeting-details .detail-item { + border-bottom-color: #374151; + } + + .meeting-details strong { + color: #818cf8; + } + + .tip-item h4 { + color: #818cf8; + } + + .value-item h4 { + color: #818cf8; + } + + // Sponsoring packages + .package-card { + border-color: #374151; + } + + .package-card.featured { + border-color: #818cf8; + } + + .package-header { + border-bottom-color: #374151; + } + + .package-footer { + border-top-color: #374151; + } + + .package-price { + color: #818cf8; + } + + .option { + background: #374151; + } + + .option-divider { + color: #9ca3af; + } + + .benefits-list li::before { + color: #818cf8; + } + + // Alerts / notices + .fallback-note { + background: rgba(14, 165, 233, 0.1); + color: #7dd3fc; + border-left-color: #0ea5e9; + } + + .alert-info { + background-color: rgba(129, 140, 248, 0.15); + border-left-color: #818cf8; + color: #818cf8; + } + + .alert-warning { + background-color: rgba(245, 158, 11, 0.15); + color: #fcd34d; + border-left-color: #f59e0b; + } + + // Carousel + .carousel-btn { + background: rgba(31, 41, 55, 0.95); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); + } + + .carousel-btn svg { + color: #d1d5db; + } + + .carousel-btn:hover { + background: rgba(55, 65, 81, 1); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5); + } + + .carousel-btn:hover svg { + color: #818cf8; + } + + .carousel-btn:disabled:hover { + background: rgba(31, 41, 55, 0.95); + } + + .carousel-btn:disabled:hover svg { + color: #d1d5db; + } + + .carousel-indicator { + background: rgba(255, 255, 255, 0.3); + } + + .carousel-indicator:hover:not(.active) { + background: rgba(255, 255, 255, 0.5); + } + + // Navigation - keep nav links white; header gradient does not change in dark mode + .nav-link { + color: rgba(255, 255, 255, 0.9); + + &:hover { + color: white; + } + + &.current, + &.nav-cta { + color: white; + } + } + + // Meta links + .meta-link { + color: #818cf8; + } + + .meta-link:hover { + color: #a5b4fc; + } +} + +/* --- Apply via data attribute (manual toggle) --- */ +[data-theme="dark"] { + @include dark-theme; +} + +/* --- Apply via OS preference (no manual override set) --- */ +@media (prefers-color-scheme: dark) { + :root:not([data-theme="light"]) { + @include dark-theme; + } +}