Skip to content

Commit f7f2b5e

Browse files
authored
Merge pull request #156 from CloudNativeLinz/copilot/add-light-dark-mode-support
Dark mode: fix nav text, team name centering, event/RNG page whites, live chart colour updates, center RNG button, fix button text colour
2 parents b01e63c + bb81446 commit f7f2b5e

9 files changed

Lines changed: 790 additions & 51 deletions

File tree

‎_includes/random-number-generator.html‎

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ <h3 id="result-header" class="result-header"></h3>
122122
padding: 1rem 2rem;
123123
font-size: 1.1rem;
124124
font-weight: 700;
125-
width: 100%;
126125
margin-top: 0.5rem;
127126
text-align: center;
127+
align-self: center;
128128
}
129129

130130
.result-card {
@@ -209,6 +209,67 @@ <h3 id="result-header" class="result-header"></h3>
209209
}
210210
}
211211

212+
/* Dark mode overrides */
213+
[data-theme="dark"] .form-label {
214+
color: #d1d5db;
215+
}
216+
217+
[data-theme="dark"] .form-input {
218+
background: #374151;
219+
border-color: #4b5563;
220+
color: #f9fafb;
221+
}
222+
223+
[data-theme="dark"] .form-input:focus {
224+
background: #1f2937;
225+
border-color: #667eea;
226+
}
227+
228+
[data-theme="dark"] .form-input:hover {
229+
background: #374151;
230+
border-color: #6b7280;
231+
}
232+
233+
[data-theme="dark"] .card.result-card {
234+
background: #1f2937;
235+
border-color: #059669;
236+
}
237+
238+
[data-theme="dark"] .result-header {
239+
color: #34d399;
240+
}
241+
242+
@media (prefers-color-scheme: dark) {
243+
:root:not([data-theme="light"]) .form-label {
244+
color: #d1d5db;
245+
}
246+
247+
:root:not([data-theme="light"]) .form-input {
248+
background: #374151;
249+
border-color: #4b5563;
250+
color: #f9fafb;
251+
}
252+
253+
:root:not([data-theme="light"]) .form-input:focus {
254+
background: #1f2937;
255+
border-color: #667eea;
256+
}
257+
258+
:root:not([data-theme="light"]) .form-input:hover {
259+
background: #374151;
260+
border-color: #6b7280;
261+
}
262+
263+
:root:not([data-theme="light"]) .card.result-card {
264+
background: #1f2937;
265+
border-color: #059669;
266+
}
267+
268+
:root:not([data-theme="light"]) .result-header {
269+
color: #34d399;
270+
}
271+
}
272+
212273
/* Mobile responsive */
213274
@media (max-width: 640px) {
214275
.random-generator-container {

‎_includes/upcoming-events.html‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
{% if event_date >= today %}
2222
<article class="event-card" data-event-id="{{ event.id }}">
2323
<div class="event-banner">
24-
<a href="{{ site.url }}/events/meetup/{{ event.slug }}/">
24+
<a href="{{ "/events/meetup/" | append: event.slug | append: "/" | relative_url }}">
2525
<img src="https://raw.githubusercontent.com/CloudNativeLinz/go-image-generator/main/artifacts/{{ event.id }}.jpg"
2626
alt="{{ event.title }}"
2727
loading="lazy"
@@ -44,7 +44,7 @@
4444

4545
<div class="event-content">
4646
<h3 class="event-title">
47-
<a href="{{ site.url }}/events/meetup/{{ event.slug }}/">{{ event.title }}</a>
47+
<a href="{{ "/events/meetup/" | append: event.slug | append: "/" | relative_url }}">{{ event.title }}</a>
4848
</h3>
4949

5050
{% if event.talks %}
@@ -64,12 +64,12 @@ <h3 class="event-title">
6464
</a>
6565
{% endif %}<br>
6666
{% if talk.file %}
67-
<a href="{{ site.url }}/events/meetup/{{ event.slug }}/">
67+
<a href="{{ "/events/meetup/" | append: event.slug | append: "/" | relative_url }}">
6868
📎 Get the slides
6969
</a>
7070
{% endif %}
7171
{% if talk.recording %}
72-
<a href="{{ site.url }}/events/meetup/{{ event.slug }}/">
72+
<a href="{{ "/events/meetup/" | append: event.slug | append: "/" | relative_url }}">
7373
📺 Watch the recording
7474
</a>
7575
{% endif %}
@@ -102,7 +102,7 @@ <h3 class="event-title">
102102
</span>
103103
{% endif %}
104104

105-
<a class="meta-link" href="{{ site.url }}/events/meetup/{{ event.slug }}/">Event details</a>
105+
<a class="meta-link" href="{{ "/events/meetup/" | append: event.slug | append: "/" | relative_url }}">Event details</a>
106106

107107
{% if event.event_link and event.event_link != "" %}
108108
<a href="{{ event.event_link }}" class="meta-link" target="_blank" rel="noopener">

‎_layouts/default.html‎

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
<html lang="en">
33
<head>
44
<meta charset="utf-8">
5+
<!-- Theme: apply system preference immediately to avoid flash of wrong theme -->
6+
<script>
7+
try {
8+
var initialTheme = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light';
9+
document.documentElement.setAttribute('data-theme', initialTheme);
10+
} catch(e) {}
11+
</script>
512
<title>{% if page.title %}{{ page.title }} – {% endif %}{{ site.name }} – {{ site.description }}</title>
613
{% seo title=false %}
714
{% include meta.html %}
@@ -71,6 +78,7 @@ <h1 class="site-name">{{ site.name }}</h1>
7178
<span class="nav-icon">🤝</span>
7279
<span class="nav-text">Join us!</span>
7380
</a>
81+
<button class="theme-toggle-btn" id="theme-toggle" aria-label="Switch color theme" title="Switch color theme"></button>
7482
</nav>
7583
</div>
7684
</div>
@@ -138,5 +146,78 @@ <h1 class="site-name">{{ site.name }}</h1>
138146
}
139147
});
140148
</script>
149+
<!-- Theme toggle script -->
150+
<script>
151+
(function() {
152+
var STORAGE_KEY = 'theme-preference';
153+
var prefersDarkQuery = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;
154+
155+
var ICONS = {
156+
light: '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>',
157+
dark: '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>'
158+
};
159+
160+
function getStoredTheme() {
161+
try { return localStorage.getItem(STORAGE_KEY); } catch(e) { return null; }
162+
}
163+
164+
function getSystemTheme() {
165+
return (prefersDarkQuery && prefersDarkQuery.matches) ? 'dark' : 'light';
166+
}
167+
168+
function getEffectiveTheme() {
169+
var stored = getStoredTheme();
170+
if (stored === 'dark' || stored === 'light') return stored;
171+
return getSystemTheme();
172+
}
173+
174+
function applyTheme(theme, persist) {
175+
if (persist) {
176+
try { localStorage.setItem(STORAGE_KEY, theme); } catch(e) {}
177+
}
178+
document.documentElement.setAttribute('data-theme', theme);
179+
updateButton(theme);
180+
document.dispatchEvent(new CustomEvent('themechange'));
181+
}
182+
183+
function updateButton(theme) {
184+
var btn = document.getElementById('theme-toggle');
185+
if (btn) {
186+
btn.innerHTML = ICONS[theme];
187+
btn.setAttribute('aria-label', theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode');
188+
btn.setAttribute('title', theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode');
189+
}
190+
}
191+
192+
document.addEventListener('DOMContentLoaded', function() {
193+
// Migrate all existing saved values to system-follow behavior.
194+
var stored = getStoredTheme();
195+
if (stored) {
196+
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
197+
}
198+
199+
applyTheme(getSystemTheme(), false);
200+
201+
var btn = document.getElementById('theme-toggle');
202+
if (btn) {
203+
btn.addEventListener('click', function() {
204+
applyTheme(getEffectiveTheme() === 'dark' ? 'light' : 'dark', false);
205+
});
206+
}
207+
208+
if (prefersDarkQuery) {
209+
var handleSystemThemeChange = function() {
210+
applyTheme(getSystemTheme(), false);
211+
};
212+
213+
if (typeof prefersDarkQuery.addEventListener === 'function') {
214+
prefersDarkQuery.addEventListener('change', handleSystemThemeChange);
215+
} else if (typeof prefersDarkQuery.addListener === 'function') {
216+
prefersDarkQuery.addListener(handleSystemThemeChange);
217+
}
218+
}
219+
});
220+
})();
221+
</script>
141222
</body>
142223
</html>

‎_layouts/event.html‎

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,97 @@
228228
display: none;
229229
}
230230
}
231+
232+
/* Dark mode overrides */
233+
[data-theme="dark"] .event-detail-card {
234+
background: #1f2937;
235+
border-color: #374151;
236+
}
237+
238+
[data-theme="dark"] .event-detail-title {
239+
color: #f9fafb;
240+
}
241+
242+
[data-theme="dark"] .event-meta-section {
243+
border-bottom-color: #374151;
244+
}
245+
246+
[data-theme="dark"] .meta-badge {
247+
background: #374151;
248+
color: #d1d5db;
249+
}
250+
251+
[data-theme="dark"] .talk-card {
252+
background: #111827;
253+
border-color: #374151;
254+
}
255+
256+
[data-theme="dark"] .talk-title {
257+
color: #f9fafb;
258+
}
259+
260+
[data-theme="dark"] .slides-container,
261+
[data-theme="dark"] .video-container {
262+
background: #1f2937;
263+
border-color: #374151;
264+
}
265+
266+
[data-theme="dark"] .slides-container h4,
267+
[data-theme="dark"] .video-container h4 {
268+
color: #d1d5db;
269+
}
270+
271+
[data-theme="dark"] .no-slides-message {
272+
background: rgba(245, 158, 11, 0.1);
273+
border-color: #d97706;
274+
color: #fcd34d;
275+
}
276+
277+
@media (prefers-color-scheme: dark) {
278+
:root:not([data-theme="light"]) .event-detail-card {
279+
background: #1f2937;
280+
border-color: #374151;
281+
}
282+
283+
:root:not([data-theme="light"]) .event-detail-title {
284+
color: #f9fafb;
285+
}
286+
287+
:root:not([data-theme="light"]) .event-meta-section {
288+
border-bottom-color: #374151;
289+
}
290+
291+
:root:not([data-theme="light"]) .meta-badge {
292+
background: #374151;
293+
color: #d1d5db;
294+
}
295+
296+
:root:not([data-theme="light"]) .talk-card {
297+
background: #111827;
298+
border-color: #374151;
299+
}
300+
301+
:root:not([data-theme="light"]) .talk-title {
302+
color: #f9fafb;
303+
}
304+
305+
:root:not([data-theme="light"]) .slides-container,
306+
:root:not([data-theme="light"]) .video-container {
307+
background: #1f2937;
308+
border-color: #374151;
309+
}
310+
311+
:root:not([data-theme="light"]) .slides-container h4,
312+
:root:not([data-theme="light"]) .video-container h4 {
313+
color: #d1d5db;
314+
}
315+
316+
:root:not([data-theme="light"]) .no-slides-message {
317+
background: rgba(245, 158, 11, 0.1);
318+
border-color: #d97706;
319+
color: #fcd34d;
320+
}
321+
}
231322
</style>
232323

233324
{% assign event_date = page.date | date: "%Y-%m-%d" %}

0 commit comments

Comments
 (0)