From f5faa8a3af0c81daa52491e35e691299eaa5b8b8 Mon Sep 17 00:00:00 2001 From: Willem van den Ende Date: Thu, 29 Oct 2026 13:07:08 +0000 Subject: [PATCH] yak(theme-explicit-light-is-overridden-on-dark-os-browsers-chip-backgrounds-are-dropped-pku7): theme: explicit light is overridden on dark-OS browsers; chip backgrounds are dropped --- app/assets/css/app.css | 42 ++-- app/lib/firehose_web/components/layouts.ex | 5 +- .../components/layouts/root.html.heex | 39 +++- .../firehose_web/theme_stylesheet_test.exs | 188 ++++++++++++++++++ 4 files changed, 248 insertions(+), 26 deletions(-) create mode 100644 app/test/firehose_web/theme_stylesheet_test.exs diff --git a/app/assets/css/app.css b/app/assets/css/app.css index 43f652e..8b464fb 100644 --- a/app/assets/css/app.css +++ b/app/assets/css/app.css @@ -27,7 +27,11 @@ --color-base-200: oklch(94% 0.012 75); --color-base-300: oklch(90% 0.016 75); --color-base-content: oklch(25% 0.015 50); - --color-primary: oklch(58% 0.16 45); + /* 54% lightness, not 58%: primary is also *text* (pagination links, body + links, the post-title hover). At 58% it measured 4.18:1 on base-100, below + the 4.5:1 floor; 54% is 4.93:1 there and 4.52:1 on base-200. Same hue and + chroma - this is a contrast fix, not a re-colour. */ + --color-primary: oklch(54% 0.16 45); --color-primary-content: oklch(98% 0.01 75); --color-secondary: oklch(55% 0.12 30); --color-secondary-content: oklch(98% 0.008 30); @@ -53,11 +57,18 @@ --noise: 0; } -/* Warm dark theme */ +/* Warm dark theme. + `prefersdark: false` deliberately: daisyUI emits an *unscoped* + `@media (prefers-color-scheme: dark) { :root { … } }` for a prefersdark + theme, which lands after the light block and beats `[data-theme="light"]` on + equal specificity - an explicit light choice rendered dark on a dark-OS + browser. The inline script in components/layouts/root.html.heex resolves + "system" to an explicit data-theme instead, so no rule here may follow the + OS preference on its own. */ @plugin "../vendor/daisyui-theme" { name: "dark"; default: false; - prefersdark: true; + prefersdark: false; color-scheme: "dark"; --color-base-100: oklch(24% 0.015 50); --color-base-200: oklch(20% 0.012 50); @@ -144,12 +155,12 @@ body { font-family: 'Source Sans 3', sans-serif; } } .blogex-post-preview header h2 a { - color: oklch(var(--color-base-content)); + color: var(--color-base-content); text-decoration: none; } .blogex-post-preview header h2 a:hover { - color: oklch(var(--color-primary)); + color: var(--color-primary); } .blogex-post-description { @@ -163,7 +174,10 @@ body { font-family: 'Source Sans 3', sans-serif; } align-items: center; gap: 0.5rem; font-size: 0.875rem; - opacity: 0.6; + /* 0.6 measured 4.16:1 (base-content over base-100, light theme) - below the + 4.5:1 floor. 0.625 is what the floor needs; 0.65 keeps a margin without + making the meta line as loud as the description (0.7 -> 5.66:1). */ + opacity: 0.65; margin-top: 0.25rem; } @@ -172,7 +186,7 @@ body { font-family: 'Source Sans 3', sans-serif; } padding: 0.125rem 0.5rem; border-radius: 9999px; font-size: 0.75rem; - background: oklch(var(--color-base-200)); + background: var(--color-base-200); } .blogex-post-header h1 { @@ -193,9 +207,9 @@ body { font-family: 'Source Sans 3', sans-serif; } .blogex-post-body p { margin-top: 1rem; } .blogex-post-body ul { list-style: disc; padding-left: 1.5rem; margin-top: 0.5rem; } .blogex-post-body ol { list-style: decimal; padding-left: 1.5rem; margin-top: 0.5rem; } -.blogex-post-body pre { background: oklch(var(--color-base-200)); padding: 1rem; border-radius: 0.5rem; overflow-x: auto; margin-top: 1rem; } +.blogex-post-body pre { background: var(--color-base-200); padding: 1rem; border-radius: 0.5rem; overflow-x: auto; margin-top: 1rem; } .blogex-post-body code { font-size: 0.875em; } -.blogex-post-body a { color: oklch(var(--color-primary)); text-decoration: underline; } +.blogex-post-body a { color: var(--color-primary); text-decoration: underline; } /* External link marker on links rewritten by Blogex.ExternalLinks (class `blogex-external`, added at compile time together with target="_blank"). @@ -235,7 +249,7 @@ body { font-family: 'Source Sans 3', sans-serif; } border-width: 0; } -.blogex-post-body blockquote { border-left: 3px solid oklch(var(--color-primary)); padding-left: 1rem; margin-top: 1rem; margin-bottom: 1rem; font-style: italic; opacity: 0.85; } +.blogex-post-body blockquote { border-left: 3px solid var(--color-primary); padding-left: 1rem; margin-top: 1rem; margin-bottom: 1rem; font-style: italic; opacity: 0.85; } .blogex-tag-list { display: flex; @@ -248,13 +262,13 @@ body { font-family: 'Source Sans 3', sans-serif; } padding: 0.25rem 0.75rem; border-radius: 9999px; font-size: 0.875rem; - background: oklch(var(--color-base-200)); + background: var(--color-base-200); text-decoration: none; } .blogex-tag-link:hover, .blogex-tag-active { - background: oklch(var(--color-primary)); - color: oklch(var(--color-primary-content)); + background: var(--color-primary); + color: var(--color-primary-content); } .blogex-pagination { @@ -267,7 +281,7 @@ body { font-family: 'Source Sans 3', sans-serif; } } .blogex-pagination a { - color: oklch(var(--color-primary)); + color: var(--color-primary); text-decoration: none; } diff --git a/app/lib/firehose_web/components/layouts.ex b/app/lib/firehose_web/components/layouts.ex index 1b0a1f2..b0bc720 100644 --- a/app/lib/firehose_web/components/layouts.ex +++ b/app/lib/firehose_web/components/layouts.ex @@ -84,7 +84,10 @@ defmodule FirehoseWeb.Layouts do def theme_toggle(assigns) do ~H"""
-
+ <%!-- The knob follows the visitor's choice, not the resolved palette: in + system mode data-theme may be light or dark, but the system icon stays + selected. --%> +