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;
+ }
+}