neiam
/gitgud
Git Gud
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
1
Log in to mark this repository.
Point "system" at the themes actually named light and dark
da63596 · Gabriel Morell · 2026-09-14 03:11
Message
{commit_body(@commit)}
Files changed
modified
assets/css/app.css
+22
−14
@@ -33,12 +33,20 @@
| 33 | 33 | --color-base-200: oklch(25.26% 0.014 253.1); |
| 34 | 34 | --color-base-300: oklch(20.15% 0.012 254.09); |
| 35 | 35 | --color-base-content: oklch(97.807% 0.029 256.847); |
| 36 | − --color-primary: oklch(58% 0.233 277.117); | |
| 37 | − --color-primary-content: oklch(96% 0.018 272.314); | |
| 38 | − --color-secondary: oklch(58% 0.233 277.117); | |
| 39 | − --color-secondary-content: oklch(96% 0.018 272.314); | |
| 40 | − --color-accent: oklch(60% 0.25 292.717); | |
| 41 | − --color-accent-content: oklch(96% 0.016 293.756); | |
| 36 | + --color-primary: oklch(64% 0.076 19); | |
| 37 | + --color-primary-content: oklch(10% 0.010 19); | |
| 38 | + --color-secondary: oklch(58% 0.090 19); | |
| 39 | + --color-secondary-content: oklch(98% 0.010 19); | |
| 40 | + /* Dark rose, in the same hue family as primary/secondary (~15-19) rather | |
| 41 | + than the violet daisyUI ships. This is what `text-accent` paints: the | |
| 42 | + eyebrow over the headline, the feature icons and the step numbers. It | |
| 43 | + has to stay light enough to read against base-100 at 30% lightness, so | |
| 44 | + "dark rose" here is depth of hue and restraint of chroma, not a low | |
| 45 | + lightness -- a genuinely dark rose would be illegible on this ground. | |
| 46 | + Chroma sits above primary's 0.076 so an accent still reads as one. | |
| 47 | + The content colour follows primary, which is the same lightness. */ | |
| 48 | + --color-accent: oklch(64% 0.135 15); | |
| 49 | + --color-accent-content: oklch(10% 0.012 15); | |
| 42 | 50 | --color-neutral: oklch(37% 0.044 257.287); |
| 43 | 51 | --color-neutral-content: oklch(98% 0.003 247.858); |
| 44 | 52 | --color-info: oklch(58% 0.158 241.966); |
@@ -64,14 +72,14 @@
| 64 | 72 | default: true; |
| 65 | 73 | prefersdark: false; |
| 66 | 74 | color-scheme: "light"; |
| 67 | − --color-base-100: oklch(98% 0 0); | |
| 68 | − --color-base-200: oklch(96% 0.001 286.375); | |
| 69 | − --color-base-300: oklch(92% 0.004 286.32); | |
| 70 | − --color-base-content: oklch(21% 0.006 285.885); | |
| 71 | − --color-primary: oklch(70% 0.213 47.604); | |
| 72 | − --color-primary-content: oklch(98% 0.016 73.684); | |
| 73 | − --color-secondary: oklch(55% 0.027 264.364); | |
| 74 | − --color-secondary-content: oklch(98% 0.002 247.839); | |
| 75 | + --color-base-100: oklch(98% 0.008 24); | |
| 76 | + --color-base-200: oklch(96% 0.014 24); | |
| 77 | + --color-base-300: oklch(92% 0.022 24); | |
| 78 | + --color-base-content: oklch(25% 0.050 24); | |
| 79 | + --color-primary: oklch(64% 0.076 19); | |
| 80 | + --color-primary-content: oklch(98% 0.010 19); | |
| 81 | + --color-secondary: oklch(55% 0.060 19); | |
| 82 | + --color-secondary-content: oklch(98% 0.010 19); | |
| 75 | 83 | --color-accent: oklch(0% 0 0); |
| 76 | 84 | --color-accent-content: oklch(100% 0 0); |
| 77 | 85 | --color-neutral: oklch(44% 0.017 285.786); |
modified
lib/git_gud/packages/formats/deb.ex
+2
−2
@@ -306,8 +306,8 @@ defmodule GitGud.Packages.Formats.Deb do
| 306 | 306 | <link rel="stylesheet" href="#{esc(stylesheet_path())}"> |
| 307 | 307 | <script> |
| 308 | 308 | (() => { |
| 309 | − const SYSTEM_DARK = "afterdark"; | |
| 310 | − const SYSTEM_LIGHT = "light"; | |
| 309 | + const SYSTEM_DARK = "#{GitGud.Themes.system_dark()}"; | |
| 310 | + const SYSTEM_LIGHT = "#{GitGud.Themes.system_light()}"; | |
| 311 | 311 | const mq = window.matchMedia("(prefers-color-scheme: dark)"); |
| 312 | 312 | const systemTheme = () => mq.matches ? SYSTEM_DARK : SYSTEM_LIGHT; |
| 313 | 313 | const apply = (theme) => |
modified
lib/git_gud/themes.ex
+18
−0
@@ -22,6 +22,24 @@ defmodule GitGud.Themes do
| 22 | 22 | @spec default() :: theme() |
| 23 | 23 | def default, do: "afterdark" |
| 24 | 24 | |
| 25 | + @doc """ | |
| 26 | + The pair "system" resolves to, following the OS preference. | |
| 27 | + | |
| 28 | + These are the two themes actually named `light` and `dark` — the ones | |
| 29 | + daisyUI declares with a matching `color-scheme`, so form controls, | |
| 30 | + scrollbars and the like are rendered by the browser to match. Any of the | |
| 31 | + other themes can be chosen explicitly; only these two are picked | |
| 32 | + automatically. | |
| 33 | + | |
| 34 | + Read by both theme bootstraps: the root layout's, and the read-only one | |
| 35 | + `GitGud.Packages.Formats.Deb` embeds in its registry index pages. | |
| 36 | + """ | |
| 37 | + @spec system_light() :: theme() | |
| 38 | + def system_light, do: "light" | |
| 39 | + | |
| 40 | + @spec system_dark() :: theme() | |
| 41 | + def system_dark, do: "dark" | |
| 42 | + | |
| 25 | 43 | @spec valid?(theme()) :: boolean() |
| 26 | 44 | def valid?(theme) when is_binary(theme), do: theme in all() or theme == "system" |
| 27 | 45 | def valid?(_), do: false |
modified
lib/git_gud_web/components/layouts/root.html.heex
+14
−6
@@ -1,5 +1,9 @@
| 1 | 1 | <!DOCTYPE html> |
| 2 | −<html lang="en"> | |
| 2 | +<html | |
| 3 | + lang="en" | |
| 4 | + data-system-light={GitGud.Themes.system_light()} | |
| 5 | + data-system-dark={GitGud.Themes.system_dark()} | |
| 6 | +> | |
| 3 | 7 | <head> |
| 4 | 8 | <meta charset="utf-8" /> |
| 5 | 9 | <meta name="viewport" content="width=device-width, initial-scale=1" /> |
@@ -25,20 +29,24 @@
| 25 | 29 | </script> |
| 26 | 30 | <script> |
| 27 | 31 | (() => { |
| 28 | − const SYSTEM_DARK = "afterdark"; | |
| 29 | − const SYSTEM_LIGHT = "light"; | |
| 32 | + // Read off <html> rather than written here: HEEx does not | |
| 33 | + // interpolate inside a <script>, it emits the expression verbatim. | |
| 34 | + // GitGud.Themes is the one place the pair is named. | |
| 35 | + const root = document.documentElement; | |
| 36 | + const SYSTEM_DARK = root.dataset.systemDark; | |
| 37 | + const SYSTEM_LIGHT = root.dataset.systemLight; | |
| 30 | 38 | const mq = window.matchMedia("(prefers-color-scheme: dark)"); |
| 31 | 39 | const systemTheme = () => mq.matches ? SYSTEM_DARK : SYSTEM_LIGHT; |
| 32 | 40 | const setTheme = (theme) => { |
| 33 | 41 | if (theme === "system") { |
| 34 | 42 | localStorage.removeItem("phx:theme"); |
| 35 | − document.documentElement.setAttribute("data-theme", systemTheme()); | |
| 43 | + root.setAttribute("data-theme", systemTheme()); | |
| 36 | 44 | } else { |
| 37 | 45 | localStorage.setItem("phx:theme", theme); |
| 38 | − document.documentElement.setAttribute("data-theme", theme); | |
| 46 | + root.setAttribute("data-theme", theme); | |
| 39 | 47 | } |
| 40 | 48 | }; |
| 41 | − if (!document.documentElement.hasAttribute("data-theme")) { | |
| 49 | + if (!root.hasAttribute("data-theme")) { | |
| 42 | 50 | setTheme(localStorage.getItem("phx:theme") || "system"); |
| 43 | 51 | } |
| 44 | 52 | mq.addEventListener("change", () => { |
Parents: 59b06a9