This commit is contained in:
@@ -5,9 +5,11 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>Forbidden · druid520</title>
|
<title>Forbidden · druid520</title>
|
||||||
<link rel="stylesheet" href="/style.css">
|
<link rel="stylesheet" href="/style.css">
|
||||||
|
<script src="/theme.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="error">
|
<main class="error">
|
||||||
|
<div class="topbar"><button id="theme-toggle" class="theme-toggle" type="button" hidden>Dark mode</button></div>
|
||||||
<h2>Error 403</h2>
|
<h2>Error 403</h2>
|
||||||
<h1>Forbidden</h1>
|
<h1>Forbidden</h1>
|
||||||
<p>You don't have access to this page.</p>
|
<p>You don't have access to this page.</p>
|
||||||
|
|||||||
@@ -5,9 +5,11 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>Not found · druid520</title>
|
<title>Not found · druid520</title>
|
||||||
<link rel="stylesheet" href="/style.css">
|
<link rel="stylesheet" href="/style.css">
|
||||||
|
<script src="/theme.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="error">
|
<main class="error">
|
||||||
|
<div class="topbar"><button id="theme-toggle" class="theme-toggle" type="button" hidden>Dark mode</button></div>
|
||||||
<h2>Error 404</h2>
|
<h2>Error 404</h2>
|
||||||
<h1>Not found</h1>
|
<h1>Not found</h1>
|
||||||
<p>There's nothing at this address.</p>
|
<p>There's nothing at this address.</p>
|
||||||
|
|||||||
@@ -6,9 +6,11 @@
|
|||||||
<title>druid520</title>
|
<title>druid520</title>
|
||||||
<meta name="description" content="Contact details and public keys for druid520.">
|
<meta name="description" content="Contact details and public keys for druid520.">
|
||||||
<link rel="stylesheet" href="/style.css">
|
<link rel="stylesheet" href="/style.css">
|
||||||
|
<script src="/theme.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
|
<div class="topbar"><button id="theme-toggle" class="theme-toggle" type="button" hidden>Dark mode</button></div>
|
||||||
<h1>druid520</h1>
|
<h1>druid520</h1>
|
||||||
|
|
||||||
<h2>Contact</h2>
|
<h2>Contact</h2>
|
||||||
|
|||||||
@@ -8,8 +8,9 @@
|
|||||||
color-scheme: light dark;
|
color-scheme: light dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dark palette: follows the OS unless the switch pinned a theme (data-theme on <html>). */
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
:root {
|
:root:not([data-theme="light"]) {
|
||||||
--bg: #111;
|
--bg: #111;
|
||||||
--fg: #e6e6e6;
|
--fg: #e6e6e6;
|
||||||
--muted: #999;
|
--muted: #999;
|
||||||
@@ -19,6 +20,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:root[data-theme="dark"] {
|
||||||
|
--bg: #111;
|
||||||
|
--fg: #e6e6e6;
|
||||||
|
--muted: #999;
|
||||||
|
--line: #333;
|
||||||
|
--code-bg: #1c1c1c;
|
||||||
|
--link: #7ab7ff;
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="light"] { color-scheme: light; }
|
||||||
|
|
||||||
|
[hidden] { display: none !important; }
|
||||||
|
|
||||||
* { box-sizing: border-box; }
|
* { box-sizing: border-box; }
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@@ -47,6 +62,22 @@ h2 {
|
|||||||
a { color: var(--link); text-decoration: none; }
|
a { color: var(--link); text-decoration: none; }
|
||||||
a:hover { text-decoration: underline; }
|
a:hover { text-decoration: underline; }
|
||||||
|
|
||||||
|
/* Theme switch */
|
||||||
|
.topbar { display: flex; justify-content: flex-end; margin: -1.5rem 0 1.5rem; }
|
||||||
|
.theme-toggle {
|
||||||
|
padding: .25rem .7rem;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--fg);
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: 6px;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: .85rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.theme-toggle:hover { border-color: var(--muted); }
|
||||||
|
.theme-toggle:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }
|
||||||
|
|
||||||
/* Contact list */
|
/* Contact list */
|
||||||
dl {
|
dl {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
// Light/dark switch. The page follows the OS theme until the button is used;
|
||||||
|
// the choice is then remembered in localStorage. Loaded in <head> so a saved
|
||||||
|
// theme is applied before the page paints.
|
||||||
|
(function () {
|
||||||
|
var root = document.documentElement;
|
||||||
|
var media = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
|
||||||
|
try {
|
||||||
|
var saved = localStorage.getItem('theme');
|
||||||
|
if (saved === 'light' || saved === 'dark') root.dataset.theme = saved;
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
function current() {
|
||||||
|
return root.dataset.theme || (media.matches ? 'dark' : 'light');
|
||||||
|
}
|
||||||
|
|
||||||
|
function label(btn) {
|
||||||
|
var next = current() === 'dark' ? 'light' : 'dark';
|
||||||
|
btn.textContent = next === 'dark' ? 'Dark mode' : 'Light mode';
|
||||||
|
btn.setAttribute('aria-label', 'Switch to ' + next + ' mode');
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
var btn = document.getElementById('theme-toggle');
|
||||||
|
if (!btn) return;
|
||||||
|
label(btn);
|
||||||
|
btn.hidden = false;
|
||||||
|
btn.addEventListener('click', function () {
|
||||||
|
root.dataset.theme = current() === 'dark' ? 'light' : 'dark';
|
||||||
|
try { localStorage.setItem('theme', root.dataset.theme); } catch (e) {}
|
||||||
|
label(btn);
|
||||||
|
});
|
||||||
|
media.addEventListener('change', function () { label(btn); });
|
||||||
|
});
|
||||||
|
})();
|
||||||
Reference in New Issue
Block a user