From c44099cac0ec3c779a2d373221741a4263f3ce92 Mon Sep 17 00:00:00 2001 From: Kristian Wind Date: Wed, 19 Aug 2026 12:36:11 +0200 Subject: [PATCH] =?UTF-8?q?feat(site):=20v=C3=A6lg=20lys=20eller=20m=C3=B8?= =?UTF-8?q?rk,=20og=20sk=C3=A6rmbilledet=20f=C3=B8lger=20med?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Siden fulgte systemet og kunne ikke andet. Nu er der en knap, valget huskes, og skærmbilledet øverst skifter med — der ligger både en mørk og en lys udgave af det samme, og det er kejtet at vise et mørkt skærmbillede på en lys side. Farverne står to gange med vilje. Mediaforespørgslen er hvad en førstegangsbesøgende får; attributten er hvad en, der har valgt, får — og den skal vinde begge veje, både et valgt lyst tema på et mørkt system og omvendt. Én regel kan ikke gøre begge dele. Begge skærmbilleder ligger i markuppen og skjules med CSS, så ingen af dem skal hentes i det øjeblik nogen trykker på knappen. Co-Authored-By: Claude Opus 5 --- site/index.html | 104 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/site/index.html b/site/index.html index f8abe34..9edf909 100644 --- a/site/index.html +++ b/site/index.html @@ -43,6 +43,10 @@ --font-mono: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace; } + /* Written twice on purpose. The media query is what a first-time visitor + gets; the attribute is what somebody who has chosen gets, and it has to + win in both directions — a chosen light theme on a dark system as well + as the other way round. A single rule cannot do both. */ @media (prefers-color-scheme: light) { :root:not([data-theme='dark']) { --ground: #faf9f7; @@ -58,6 +62,63 @@ } } + :root[data-theme='light'] { + --ground: #faf9f7; + --surface: #ffffff; + --surface-raised: #ffffff; + --line: #e5e3de; + --line-strong: #d3d0c9; + --ink: #1c201e; + --ink-muted: #5f6763; + --ink-faint: #8b918d; + --accent: #2f8f63; + --accent-ink: #ffffff; + } + + .theme-toggle { + position: fixed; + top: 1rem; + right: 1rem; + z-index: 10; + width: 2.25rem; + height: 2.25rem; + display: grid; + place-items: center; + border: 1px solid var(--line); + border-radius: 999px; + background: var(--surface); + color: var(--ink-muted); + cursor: pointer; + font-size: 1rem; + line-height: 1; + } + + .theme-toggle:hover { + color: var(--ink); + border-color: var(--line-strong); + } + + /* Whichever screenshot does not belong to the theme in force is simply not + there. Both are in the markup so neither has to be fetched at the moment + somebody flips the switch. */ + :root:not([data-theme='light']) .only-light, + :root[data-theme='dark'] .only-light { + display: none; + } + + :root[data-theme='light'] .only-dark { + display: none; + } + + @media (prefers-color-scheme: light) { + :root:not([data-theme='dark']) .only-light { + display: block; + } + :root:not([data-theme='dark']) .only-dark { + display: none; + } + } + *, *::before, *::after { @@ -463,6 +524,9 @@ +
@@ -522,7 +586,7 @@

What it looks like

-
+
The Today view: a sidebar of projects, filters and labels beside a list of tasks due today, each with its priority ring, time and labels.Today. Dark is the default; there is a light theme too.
+
+ The Today view in the light theme: a sidebar of projects, filters and labels beside a list of tasks due today. +
Today. Dark is the default; there is a light theme too.
+
+