diff --git a/internal/render/render.go b/internal/render/render.go
index 69dbc1e..749c684 100644
--- a/internal/render/render.go
+++ b/internal/render/render.go
@@ -36,7 +36,12 @@ const MaxSize = 512 * 1024
// highlightStyle is the chroma theme shared by blob view and README code
// blocks, so the two match. Class-based output pairs it with HighlightCSS.
-var highlightStyle = styles.Get("github")
+// darkStyle is its dark-mode counterpart, emitted under a prefers-color-scheme
+// media query — same class names, so it overrides when the viewer's OS is dark.
+var (
+ highlightStyle = styles.Get("github")
+ darkStyle = styles.Get("github-dark")
+)
// classFormatter emits class-based (not inline-style) highlight markup, so a
// single stylesheet from HighlightCSS covers every page.
@@ -77,6 +82,11 @@ func HighlightCSS() template.CSS {
highlightCSS.Do(func() {
var buf bytes.Buffer
_ = classFormatter.WriteCSS(&buf, highlightStyle)
+ // The dark theme reuses the same classes, wrapped in a media query so it
+ // only takes effect when the viewer's OS is in dark mode.
+ buf.WriteString("@media (prefers-color-scheme: dark) {\n")
+ _ = classFormatter.WriteCSS(&buf, darkStyle)
+ buf.WriteString("}\n")
highlightCSS.css = template.CSS(buf.String())
})
return highlightCSS.css
diff --git a/internal/render/render_test.go b/internal/render/render_test.go
index b2a1473..7895580 100644
--- a/internal/render/render_test.go
+++ b/internal/render/render_test.go
@@ -45,6 +45,10 @@ func TestHighlightCSS(t *testing.T) {
if css == "" || !strings.Contains(css, ".chroma") {
t.Fatalf("HighlightCSS looks wrong:\n%s", css)
}
+ // A dark-mode override ships alongside the light theme.
+ if !strings.Contains(css, "prefers-color-scheme: dark") {
+ t.Fatalf("HighlightCSS missing dark-mode variant:\n%s", css)
+ }
}
func TestMarkdownGFM(t *testing.T) {
diff --git a/internal/webui/templates/layout.html b/internal/webui/templates/layout.html
index 51d544e..ce99342 100644
--- a/internal/webui/templates/layout.html
+++ b/internal/webui/templates/layout.html
@@ -54,7 +54,11 @@
{{define "bottom"}}
{{if .Mermaid}}
<script src="/ui/static/mermaid.min.js"></script>
-<script>mermaid.initialize({ startOnLoad: false, securityLevel: 'strict' }); mermaid.run();</script>
+<script>
+ var dark = matchMedia('(prefers-color-scheme: dark)').matches;
+ mermaid.initialize({ startOnLoad: false, securityLevel: 'strict', theme: dark ? 'dark' : 'default' });
+ mermaid.run();
+</script>
{{end}}
</body>
</html>