feat: add arborium syntax highlighting
Adds the arborium IIFE script (loaded from jsDelivr CDN) to the base
template. Highlighting is deferred via `manual: true` so Alpine controls
when it fires — on page init and whenever the dark/light toggle flips.
Theme: github-light in light mode, github-dark in dark mode. CSS overrides
keep quire's --code background and font stack over arborium's injected
theme, so the paper-toned palette stays consistent.
Code blocks without a language class still show as plain monospace. No
Rust changes needed — pulldown-cmark already emits
`<pre><code class="language-*">` from fenced blocks.
https://claude.ai/code/session_01BuheW8fNiXAUVyVpKzHhoe
diff --git a/quire-server/static/style.css b/quire-server/static/style.css
index bfe7198..43ed4d7 100644
--- a/quire-server/static/style.css
+++ b/quire-server/static/style.css
@@ -685,3 +685,23 @@ html.dark {
font-style: italic;
color: var(--mutedFaint);
}
+
+/* ── Arborium syntax highlighting integration ──────────────────── */
+
+/* Keep quire's paper-toned code background; strip any theme-imposed radius. */
+pre:has(code[class*="language-"]),
+pre:has(code[data-lang]) {
+ background: var(--code) !important;
+ border-radius: 0 !important;
+ /* Preserve the design's left-rail accent. */
+ border-left: 2px solid var(--accent) !important;
+}
+
+/* Arborium injects its own <style> for theme colors; let it control text
+ colors but keep our font stack and size. */
+pre code[class*="language-"],
+pre code[data-lang] {
+ font-family: var(--font-mono) !important;
+ font-size: 13px !important;
+ background: transparent !important;
+}
diff --git a/quire-server/templates/_base.html b/quire-server/templates/_base.html
index 3bd77bb..5f2fd9d 100644
--- a/quire-server/templates/_base.html
+++ b/quire-server/templates/_base.html
@@ -5,6 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}quire{% endblock %}</title>
<link rel="stylesheet" href="/style.css">
+ <script>window.Arborium = { manual: true };</script>
+ <script defer src="https://cdn.jsdelivr.net/npm/@arborium/arborium@2/dist/arborium.iife.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3/dist/cdn.min.js"></script>
</head>
<body>
@@ -27,10 +29,19 @@
} else {
this.darkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
}
+ this._highlight();
},
toggleDark() {
this.darkMode = !this.darkMode;
localStorage.setItem('quire-dark', this.darkMode ? '1' : '0');
+ this._highlight();
+ },
+ _highlight() {
+ const arborium = window.arborium;
+ if (!arborium) return;
+ const theme = this.darkMode ? 'github-dark' : 'github-light';
+ arborium.setConfig({ theme });
+ arborium.highlightAll();
}
}
}