1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<button type="button" class="theme-toggle" data-rustango-theme-toggle aria-label="Toggle theme">
<span data-rustango-theme-icon>🌗</span>
<span data-rustango-theme-label>Auto</span>
</button>
<script nonce="{{ csp_nonce }}">
// Theme toggle — cycles auto → light → dark → auto. Persists choice
// to localStorage so it survives page navigation. Pairs with the
// no-flash <head> script that re-applies the saved value before
// stylesheet evaluation.
(function () {
const STORAGE_KEY = 'rustango-theme';
const ORDER = ['auto', 'light', 'dark'];
const ICONS = { auto: '🌗', light: '☀️', dark: '🌙' };
const LABELS = { auto: 'Auto', light: 'Light', dark: 'Dark' };
const read = () => {
try { return localStorage.getItem(STORAGE_KEY); } catch (e) { return null; }
};
const write = (v) => {
try { localStorage.setItem(STORAGE_KEY, v); } catch (e) { /* private mode */ }
};
const apply = (mode) => {
document.documentElement.dataset.theme = mode;
document.querySelectorAll('[data-rustango-theme-icon]').forEach((el) => {
el.textContent = ICONS[mode] || ICONS.auto;
});
document.querySelectorAll('[data-rustango-theme-label]').forEach((el) => {
el.textContent = LABELS[mode] || LABELS.auto;
});
};
// Sync icon/label with whichever theme the no-flash script picked.
const stored = read();
apply(stored && ORDER.includes(stored) ? stored : (document.documentElement.dataset.theme || 'auto'));
document.addEventListener('click', (e) => {
const btn = e.target.closest('[data-rustango-theme-toggle]');
if (!btn) return;
const cur = read();
const idx = ORDER.indexOf(cur && ORDER.includes(cur) ? cur : 'auto');
const next = ORDER[(idx + 1) % ORDER.length];
write(next);
apply(next);
});
})();
</script>