diff --git a/pygitweb/static/main.css b/pygitweb/static/main.css
index 0ef4e59..13ded8f 100644
--- a/pygitweb/static/main.css
+++ b/pygitweb/static/main.css
@@ -1,11 +1,19 @@
 /*
  * Custom themes: load an extra stylesheet after this one that redefines
- * the same --pgw-* (and optional --d2h-*) variables on :root.
+ * the same --pgw-* (optional --pgw-hljs-*, --d2h-*) variables on :root.
  * Example: <link rel="stylesheet" href="static/themes/solarized.css">
  */
 
 :root {
 	color-scheme: light;
+
+	/* Theme colors */
+	--pgw-theme-wheat: #d1caa1;
+	--pgw-theme-slate: #66717e;
+	--pgw-theme-mist: #d4d6b9;
+	--pgw-theme-ink: #0f1218;
+	--pgw-theme-ink-soft: #1a1f2e;
+
 	/* Surfaces */
 	--pgw-bg: #fafafa;
 	--pgw-bg-raised: #ffffff;
@@ -19,7 +27,12 @@
 
 	--pgw-link: #2563eb;
 	--pgw-link-visited: #7c3aed;
-	--pgw-link-hover: #dc2626;
+	--pgw-link-hover: #2641dc;
+
+	--pgw-btn-bg: var(--pgw-theme-mist);
+	--pgw-btn-text: var(--pgw-theme-ink);
+	--pgw-btn-hover-bg: var(--pgw-theme-wheat);
+	--pgw-btn-hover-text: var(--pgw-theme-ink);
 
 	--pgw-accent-bg: #e4e4e7;
 	--pgw-accent-text: #18181b;
@@ -29,6 +42,24 @@
 	--pgw-code-bg: #f4f4f5;
 	--pgw-code-border: #e4e4e7;
 
+	/* highlight.js (github-light palette via pgw / Tabler) */
+	--pgw-hljs-fg: var(--pgw-text);
+	--pgw-hljs-bg: transparent;
+	--pgw-hljs-comment: var(--pgw-text-muted);
+	--pgw-hljs-keyword: var(--tblr-pink, #a71d5d);
+	--pgw-hljs-type: var(--tblr-red, #cf222e);
+	--pgw-hljs-string: var(--pgw-link);
+	--pgw-hljs-title: var(--tblr-purple, #8250df);
+	--pgw-hljs-attr: var(--tblr-cyan, #0550ae);
+	--pgw-hljs-name: var(--tblr-orange, #953800);
+	--pgw-hljs-built_in: var(--pgw-link);
+	--pgw-hljs-tag: var(--pgw-add-fg);
+	--pgw-hljs-meta: var(--pgw-hljs-fg);
+	--pgw-hljs-addition-fg: var(--pgw-add-fg);
+	--pgw-hljs-addition-bg: var(--pgw-add-bg);
+	--pgw-hljs-deletion-fg: var(--pgw-rem-fg);
+	--pgw-hljs-deletion-bg: var(--pgw-rem-bg);
+
 	--pgw-table-stripe: #fafafa;
 	--pgw-table-hover: #f4f4f5;
 
@@ -63,6 +94,7 @@
 	--d2h-ins-bg-color: rgb(220, 255, 220);
 	--d2h-dim-color: #666;
 	--d2h-bg-color: #fff;
+	--d2h-selected-color: rgba(255, 255, 255, 0.3);
 }
 
 @media (prefers-color-scheme: dark) {
@@ -82,6 +114,11 @@
 		--pgw-link-visited: #c4b5fd;
 		--pgw-link-hover: #fda4af;
 
+		--pgw-btn-bg: #2d2d4a;
+		--pgw-btn-text: var(--pgw-text);
+		--pgw-btn-hover-bg: #4f4f7a;
+		--pgw-btn-hover-text: var(--pgw-text);
+
 		--pgw-accent-bg: #27272a;
 		--pgw-accent-text: #fafafa;
 		--pgw-title-bg: #2d2d36;
@@ -90,6 +127,18 @@
 		--pgw-code-bg: #18181b;
 		--pgw-code-border: #27272a;
 
+		--pgw-hljs-fg: var(--pgw-text);
+		--pgw-hljs-comment: var(--pgw-text-dim);
+		--pgw-hljs-keyword: var(--tblr-red, #ff7b72);
+		--pgw-hljs-type: var(--pgw-hljs-keyword);
+		--pgw-hljs-string: var(--pgw-link);
+		--pgw-hljs-title: var(--tblr-purple, #d2a8ff);
+		--pgw-hljs-attr: var(--tblr-cyan, #79c0ff);
+		--pgw-hljs-name: var(--tblr-green, #7ee787);
+		--pgw-hljs-built_in: var(--tblr-orange, #ffa657);
+		--pgw-hljs-tag: var(--pgw-hljs-name);
+		--pgw-hljs-meta: var(--pgw-hljs-fg);
+
 		--pgw-table-stripe: #222226;
 		--pgw-table-hover: #2d2d36;
 
@@ -269,14 +318,14 @@ body {
 
 /* Buttons: primary and ghost variants */
 .btn-primary {
-	background-color: var(--pgw-link);
-	border-color: var(--pgw-link);
-	color: var(--pgw-accent-text);
+	background-color: var(--pgw-btn-bg);
+	border-color: var(--pgw-border-muted);
+	color: var(--pgw-btn-text);
 
 	&:hover {
-		background-color: var(--pgw-link-hover);
-		border-color: var(--pgw-link-hover);
-		color: var(--pgw-accent-text);
+		background-color: var(--pgw-btn-hover-bg);
+		border-color: var(--pgw-border);
+		color: var(--pgw-btn-hover-text);
 	}
 }
 
@@ -577,6 +626,109 @@ tbody tr {
 	}
 }
 
+/* highlight.js: token colors from --pgw-hljs-* (replaces CDN theme; tracks prefers-color-scheme) */
+.hljs,
+.hljs-subst {
+	color: var(--pgw-hljs-fg);
+	background: var(--pgw-hljs-bg);
+}
+
+.hljs-comment,
+.hljs-formula {
+	color: var(--pgw-hljs-comment);
+}
+
+.hljs-operator,
+.hljs-punctuation {
+	color: var(--pgw-hljs-fg);
+}
+
+.hljs-doctag,
+.hljs-keyword,
+.hljs-meta .hljs-keyword,
+.hljs-template-tag,
+.hljs-template-variable,
+.hljs-type,
+.hljs-variable.language_ {
+	color: var(--pgw-hljs-keyword);
+}
+
+.hljs-title,
+.hljs-title.class_,
+.hljs-title.class_.inherited__,
+.hljs-title.function_,
+.hljs-function .hljs-title,
+.hljs-section,
+.hljs-attribute,
+.ruby .hljs-property {
+	color: var(--pgw-hljs-title);
+}
+
+.hljs-attr,
+.hljs-literal,
+.hljs-meta,
+.hljs-number,
+.hljs-selector-attr,
+.hljs-selector-class,
+.hljs-selector-id,
+.hljs-variable,
+.hljs-variable.constant_ {
+	color: var(--pgw-hljs-attr);
+}
+
+.hljs-built_in,
+.hljs-symbol {
+	color: var(--pgw-hljs-built_in);
+}
+
+.hljs-meta .hljs-string,
+.hljs-regexp,
+.hljs-string {
+	color: var(--pgw-hljs-string);
+}
+
+.hljs-addition,
+.hljs-code,
+.hljs-keyword.hljs-atrule,
+.hljs-title.class_.inherited__ {
+	color: var(--pgw-hljs-string);
+}
+
+.hljs-name,
+.hljs-quote,
+.hljs-selector-pseudo,
+.hljs-selector-tag {
+	color: var(--pgw-hljs-name);
+}
+
+.hljs-tag {
+	color: var(--pgw-hljs-tag);
+}
+
+.hljs-bullet {
+	color: var(--pgw-hljs-built_in);
+}
+
+.hljs-emphasis {
+	color: var(--pgw-hljs-keyword);
+	font-style: italic;
+}
+
+.hljs-strong {
+	color: var(--pgw-hljs-title);
+	font-weight: 700;
+}
+
+.hljs-addition {
+	color: var(--pgw-hljs-addition-fg);
+	background-color: var(--pgw-hljs-addition-bg);
+}
+
+.hljs-deletion {
+	color: var(--pgw-hljs-deletion-fg);
+	background-color: var(--pgw-hljs-deletion-bg);
+}
+
 .blob-view.blame-view {
 	.blame-commits {
 		flex-shrink: 0;
@@ -624,23 +776,6 @@ tbody tr {
 		}
 	}
 
-	code {
-		background-color: var(--pgw-code-bg);
-		color: var(--pgw-text);
-		border: 1px solid var(--pgw-code-border);
-	}
-
-	pre {
-		background-color: var(--pgw-code-bg);
-		border: 1px solid var(--pgw-code-border);
-		color: var(--pgw-text);
-
-		code {
-			background: none;
-			border: none;
-		}
-	}
-
 	blockquote {
 		border-left: 0.25rem solid var(--pgw-border);
 		color: var(--pgw-text-muted);
@@ -707,6 +842,23 @@ tbody tr {
 	}
 }
 
+code {
+	background-color: var(--pgw-code-bg);
+	color: var(--pgw-text);
+	border: 1px solid var(--pgw-code-border);
+}
+
+pre {
+	background-color: var(--pgw-code-bg);
+	border: 1px solid var(--pgw-code-border);
+	color: var(--pgw-text);
+
+	code {
+		background: none;
+		border: none;
+	}
+}
+
 .readme-toc-mount {
 	position: fixed;
 	left: var(--tblr-navbar-vertical-width, 15rem);
diff --git a/pygitweb/templates/preamble.html b/pygitweb/templates/preamble.html
index a87e891..919909d 100644
--- a/pygitweb/templates/preamble.html
+++ b/pygitweb/templates/preamble.html
@@ -2,7 +2,6 @@
 <script>document.documentElement.setAttribute('data-bs-theme', window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e){ document.documentElement.setAttribute('data-bs-theme', e.matches ? 'dark' : 'light'); });</script>
 <link rel="icon" href="/static/logo.svg" type="image/svg+xml">
 <script id="Highlight-script" async src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
 <script id="MathJax-script" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-chtml.min.js"></script>
 <script id="GraphViz-script" async src="https://cdnjs.cloudflare.com/ajax/libs/viz.js/1.8.2/viz.js"></script>
 <script id="diff2html-script" async src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html-ui.min.js"></script>
