diff --git a/quartz.lock.json b/quartz.lock.json
index 0e73a7b76..97a3200fb 100644
--- a/quartz.lock.json
+++ b/quartz.lock.json
@@ -124,8 +124,8 @@
"syntax-highlighting": {
"source": "github:quartz-community/syntax-highlighting",
"resolved": "https://github.com/quartz-community/syntax-highlighting.git",
- "commit": "7255e37de4d17690eba5508944c232c3a85f74d5",
- "installedAt": "2026-02-13T22:03:22.542Z"
+ "commit": "fada634ccd28a29580472555153933dcefe580e0",
+ "installedAt": "2026-02-13T23:33:13.407Z"
},
"obsidian-flavored-markdown": {
"source": "github:quartz-community/obsidian-flavored-markdown",
diff --git a/quartz/components/Body.tsx b/quartz/components/Body.tsx
index 96b627883..d396f4d5d 100644
--- a/quartz/components/Body.tsx
+++ b/quartz/components/Body.tsx
@@ -1,13 +1,7 @@
-// @ts-ignore
-import clipboardScript from "./scripts/clipboard.inline"
-import clipboardStyle from "./styles/clipboard.scss"
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"
const Body: QuartzComponent = ({ children }: QuartzComponentProps) => {
return
{children}
}
-Body.afterDOMLoaded = clipboardScript
-Body.css = clipboardStyle
-
export default (() => Body) satisfies QuartzComponentConstructor
diff --git a/quartz/components/scripts/callout.inline.ts b/quartz/components/scripts/callout.inline.ts
deleted file mode 100644
index 242ce514e..000000000
--- a/quartz/components/scripts/callout.inline.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-function toggleCallout(this: HTMLElement) {
- const outerBlock = this.parentElement!
- outerBlock.classList.toggle("is-collapsed")
- const content = outerBlock.getElementsByClassName("callout-content")[0] as HTMLElement
- if (!content) return
- const collapsed = outerBlock.classList.contains("is-collapsed")
- content.style.gridTemplateRows = collapsed ? "0fr" : "1fr"
-}
-
-function setupCallout() {
- const collapsible = document.getElementsByClassName(
- `callout is-collapsible`,
- ) as HTMLCollectionOf
- for (const div of collapsible) {
- const title = div.getElementsByClassName("callout-title")[0] as HTMLElement
- const content = div.getElementsByClassName("callout-content")[0] as HTMLElement
- if (!title || !content) continue
-
- title.addEventListener("click", toggleCallout)
- window.addCleanup(() => title.removeEventListener("click", toggleCallout))
-
- const collapsed = div.classList.contains("is-collapsed")
- content.style.gridTemplateRows = collapsed ? "0fr" : "1fr"
- }
-}
-
-document.addEventListener("nav", setupCallout)
diff --git a/quartz/components/scripts/checkbox.inline.ts b/quartz/components/scripts/checkbox.inline.ts
deleted file mode 100644
index 50ab0425a..000000000
--- a/quartz/components/scripts/checkbox.inline.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { getFullSlug } from "../../util/path"
-
-const checkboxId = (index: number) => `${getFullSlug(window)}-checkbox-${index}`
-
-document.addEventListener("nav", () => {
- const checkboxes = document.querySelectorAll(
- "input.checkbox-toggle",
- ) as NodeListOf
- checkboxes.forEach((el, index) => {
- const elId = checkboxId(index)
-
- const switchState = (e: Event) => {
- const newCheckboxState = (e.target as HTMLInputElement)?.checked ? "true" : "false"
- localStorage.setItem(elId, newCheckboxState)
- }
-
- el.addEventListener("change", switchState)
- window.addCleanup(() => el.removeEventListener("change", switchState))
- if (localStorage.getItem(elId) === "true") {
- el.checked = true
- }
- })
-})
diff --git a/quartz/components/scripts/clipboard.inline.ts b/quartz/components/scripts/clipboard.inline.ts
deleted file mode 100644
index e16c11299..000000000
--- a/quartz/components/scripts/clipboard.inline.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-const svgCopy =
- ''
-const svgCheck =
- ''
-
-document.addEventListener("nav", () => {
- const els = document.getElementsByTagName("pre")
- for (let i = 0; i < els.length; i++) {
- const codeBlock = els[i].getElementsByTagName("code")[0]
- if (codeBlock) {
- const source = (
- codeBlock.dataset.clipboard ? JSON.parse(codeBlock.dataset.clipboard) : codeBlock.innerText
- ).replace(/\n\n/g, "\n")
- const button = document.createElement("button")
- button.className = "clipboard-button"
- button.type = "button"
- button.innerHTML = svgCopy
- button.ariaLabel = "Copy source"
- function onClick() {
- navigator.clipboard.writeText(source).then(
- () => {
- button.blur()
- button.innerHTML = svgCheck
- setTimeout(() => {
- button.innerHTML = svgCopy
- button.style.borderColor = ""
- }, 2000)
- },
- (error) => console.error(error),
- )
- }
- button.addEventListener("click", onClick)
- window.addCleanup(() => button.removeEventListener("click", onClick))
- els[i].prepend(button)
- }
- }
-})
diff --git a/quartz/components/scripts/mermaid.inline.ts b/quartz/components/scripts/mermaid.inline.ts
deleted file mode 100644
index 10399739d..000000000
--- a/quartz/components/scripts/mermaid.inline.ts
+++ /dev/null
@@ -1,300 +0,0 @@
-import { registerEscapeHandler, removeAllChildren } from "./util"
-
-interface Position {
- x: number
- y: number
-}
-
-class DiagramPanZoom {
- private isDragging = false
- private startPan: Position = { x: 0, y: 0 }
- private currentPan: Position = { x: 0, y: 0 }
- private scale = 1
- private readonly MIN_SCALE = 0.5
- private readonly MAX_SCALE = 3
-
- cleanups: (() => void)[] = []
-
- constructor(
- private container: HTMLElement,
- private content: HTMLElement,
- ) {
- this.setupEventListeners()
- this.setupNavigationControls()
- this.resetTransform()
- }
-
- private setupEventListeners() {
- // Mouse drag events
- const mouseDownHandler = this.onMouseDown.bind(this)
- const mouseMoveHandler = this.onMouseMove.bind(this)
- const mouseUpHandler = this.onMouseUp.bind(this)
-
- // Touch drag events
- const touchStartHandler = this.onTouchStart.bind(this)
- const touchMoveHandler = this.onTouchMove.bind(this)
- const touchEndHandler = this.onTouchEnd.bind(this)
-
- const resizeHandler = this.resetTransform.bind(this)
-
- this.container.addEventListener("mousedown", mouseDownHandler)
- document.addEventListener("mousemove", mouseMoveHandler)
- document.addEventListener("mouseup", mouseUpHandler)
-
- this.container.addEventListener("touchstart", touchStartHandler, { passive: false })
- document.addEventListener("touchmove", touchMoveHandler, { passive: false })
- document.addEventListener("touchend", touchEndHandler)
-
- window.addEventListener("resize", resizeHandler)
-
- this.cleanups.push(
- () => this.container.removeEventListener("mousedown", mouseDownHandler),
- () => document.removeEventListener("mousemove", mouseMoveHandler),
- () => document.removeEventListener("mouseup", mouseUpHandler),
- () => this.container.removeEventListener("touchstart", touchStartHandler),
- () => document.removeEventListener("touchmove", touchMoveHandler),
- () => document.removeEventListener("touchend", touchEndHandler),
- () => window.removeEventListener("resize", resizeHandler),
- )
- }
-
- cleanup() {
- for (const cleanup of this.cleanups) {
- cleanup()
- }
- }
-
- private setupNavigationControls() {
- const controls = document.createElement("div")
- controls.className = "mermaid-controls"
-
- // Zoom controls
- const zoomIn = this.createButton("+", () => this.zoom(0.1))
- const zoomOut = this.createButton("-", () => this.zoom(-0.1))
- const resetBtn = this.createButton("Reset", () => this.resetTransform())
-
- controls.appendChild(zoomOut)
- controls.appendChild(resetBtn)
- controls.appendChild(zoomIn)
-
- this.container.appendChild(controls)
- }
-
- private createButton(text: string, onClick: () => void): HTMLButtonElement {
- const button = document.createElement("button")
- button.textContent = text
- button.className = "mermaid-control-button"
- button.addEventListener("click", onClick)
- window.addCleanup(() => button.removeEventListener("click", onClick))
- return button
- }
-
- private onMouseDown(e: MouseEvent) {
- if (e.button !== 0) return // Only handle left click
- this.isDragging = true
- this.startPan = { x: e.clientX - this.currentPan.x, y: e.clientY - this.currentPan.y }
- this.container.style.cursor = "grabbing"
- }
-
- private onMouseMove(e: MouseEvent) {
- if (!this.isDragging) return
- e.preventDefault()
-
- this.currentPan = {
- x: e.clientX - this.startPan.x,
- y: e.clientY - this.startPan.y,
- }
-
- this.updateTransform()
- }
-
- private onMouseUp() {
- this.isDragging = false
- this.container.style.cursor = "grab"
- }
-
- private onTouchStart(e: TouchEvent) {
- if (e.touches.length !== 1) return
- this.isDragging = true
- const touch = e.touches[0]
- this.startPan = { x: touch.clientX - this.currentPan.x, y: touch.clientY - this.currentPan.y }
- }
-
- private onTouchMove(e: TouchEvent) {
- if (!this.isDragging || e.touches.length !== 1) return
- e.preventDefault() // Prevent scrolling
-
- const touch = e.touches[0]
- this.currentPan = {
- x: touch.clientX - this.startPan.x,
- y: touch.clientY - this.startPan.y,
- }
-
- this.updateTransform()
- }
-
- private onTouchEnd() {
- this.isDragging = false
- }
-
- private zoom(delta: number) {
- const newScale = Math.min(Math.max(this.scale + delta, this.MIN_SCALE), this.MAX_SCALE)
-
- // Zoom around center
- const rect = this.content.getBoundingClientRect()
- const centerX = rect.width / 2
- const centerY = rect.height / 2
-
- const scaleDiff = newScale - this.scale
- this.currentPan.x -= centerX * scaleDiff
- this.currentPan.y -= centerY * scaleDiff
-
- this.scale = newScale
- this.updateTransform()
- }
-
- private updateTransform() {
- this.content.style.transform = `translate(${this.currentPan.x}px, ${this.currentPan.y}px) scale(${this.scale})`
- }
-
- private resetTransform() {
- const svg = this.content.querySelector("svg")!
- const rect = svg.getBoundingClientRect()
- const width = rect.width / this.scale
- const height = rect.height / this.scale
-
- this.scale = 1
- this.currentPan = {
- x: (this.container.clientWidth - width) / 2,
- y: (this.container.clientHeight - height) / 2,
- }
- this.updateTransform()
- }
-}
-
-const cssVars = [
- "--secondary",
- "--tertiary",
- "--gray",
- "--light",
- "--lightgray",
- "--highlight",
- "--dark",
- "--darkgray",
- "--codeFont",
-] as const
-
-let mermaidImport = undefined
-document.addEventListener("nav", async () => {
- const center = document.querySelector(".center") as HTMLElement
- const nodes = center.querySelectorAll("code.mermaid") as NodeListOf
- if (nodes.length === 0) return
-
- mermaidImport ||= await import(
- // @ts-ignore
- "https://cdnjs.cloudflare.com/ajax/libs/mermaid/11.4.0/mermaid.esm.min.mjs"
- )
- const mermaid = mermaidImport.default
-
- const textMapping: WeakMap = new WeakMap()
- for (const node of nodes) {
- textMapping.set(node, node.innerText)
- }
-
- async function renderMermaid() {
- // de-init any other diagrams
- for (const node of nodes) {
- node.removeAttribute("data-processed")
- const oldText = textMapping.get(node)
- if (oldText) {
- node.innerHTML = oldText
- }
- }
-
- const computedStyleMap = cssVars.reduce(
- (acc, key) => {
- acc[key] = window.getComputedStyle(document.documentElement).getPropertyValue(key)
- return acc
- },
- {} as Record<(typeof cssVars)[number], string>,
- )
-
- const darkMode = document.documentElement.getAttribute("saved-theme") === "dark"
- mermaid.initialize({
- startOnLoad: false,
- securityLevel: "loose",
- theme: darkMode ? "dark" : "base",
- themeVariables: {
- fontFamily: computedStyleMap["--codeFont"],
- primaryColor: computedStyleMap["--light"],
- primaryTextColor: computedStyleMap["--darkgray"],
- primaryBorderColor: computedStyleMap["--tertiary"],
- lineColor: computedStyleMap["--darkgray"],
- secondaryColor: computedStyleMap["--secondary"],
- tertiaryColor: computedStyleMap["--tertiary"],
- clusterBkg: computedStyleMap["--light"],
- edgeLabelBackground: computedStyleMap["--highlight"],
- },
- })
-
- await mermaid.run({ nodes })
- }
-
- await renderMermaid()
- document.addEventListener("themechange", renderMermaid)
- window.addCleanup(() => document.removeEventListener("themechange", renderMermaid))
-
- for (let i = 0; i < nodes.length; i++) {
- const codeBlock = nodes[i] as HTMLElement
- const pre = codeBlock.parentElement as HTMLPreElement
- const clipboardBtn = pre.querySelector(".clipboard-button") as HTMLButtonElement
- const expandBtn = pre.querySelector(".expand-button") as HTMLButtonElement
-
- const clipboardStyle = window.getComputedStyle(clipboardBtn)
- const clipboardWidth =
- clipboardBtn.offsetWidth +
- parseFloat(clipboardStyle.marginLeft || "0") +
- parseFloat(clipboardStyle.marginRight || "0")
-
- // Set expand button position
- expandBtn.style.right = `calc(${clipboardWidth}px + 0.3rem)`
- pre.prepend(expandBtn)
-
- // query popup container
- const popupContainer = pre.querySelector("#mermaid-container") as HTMLElement
- if (!popupContainer) return
-
- let panZoom: DiagramPanZoom | null = null
- function showMermaid() {
- const container = popupContainer.querySelector("#mermaid-space") as HTMLElement
- const content = popupContainer.querySelector(".mermaid-content") as HTMLElement
- if (!content) return
- removeAllChildren(content)
-
- // Clone the mermaid content
- const mermaidContent = codeBlock.querySelector("svg")!.cloneNode(true) as SVGElement
- content.appendChild(mermaidContent)
-
- // Show container
- popupContainer.classList.add("active")
- container.style.cursor = "grab"
-
- // Initialize pan-zoom after showing the popup
- panZoom = new DiagramPanZoom(container, content)
- }
-
- function hideMermaid() {
- popupContainer.classList.remove("active")
- panZoom?.cleanup()
- panZoom = null
- }
-
- expandBtn.addEventListener("click", showMermaid)
- registerEscapeHandler(popupContainer, hideMermaid)
-
- window.addCleanup(() => {
- panZoom?.cleanup()
- expandBtn.removeEventListener("click", showMermaid)
- })
- }
-})
diff --git a/quartz/components/styles/clipboard.scss b/quartz/components/styles/clipboard.scss
deleted file mode 100644
index 196b8945c..000000000
--- a/quartz/components/styles/clipboard.scss
+++ /dev/null
@@ -1,36 +0,0 @@
-.clipboard-button {
- position: absolute;
- display: flex;
- float: right;
- right: 0;
- padding: 0.4rem;
- margin: 0.3rem;
- color: var(--gray);
- border-color: var(--dark);
- background-color: var(--light);
- border: 1px solid;
- border-radius: 5px;
- opacity: 0;
- transition: 0.2s;
-
- & > svg {
- fill: var(--light);
- filter: contrast(0.3);
- }
-
- &:hover {
- cursor: pointer;
- border-color: var(--secondary);
- }
-
- &:focus {
- outline: 0;
- }
-}
-
-pre {
- &:hover > .clipboard-button {
- opacity: 1;
- transition: 0.2s;
- }
-}
diff --git a/quartz/components/styles/listPage.scss b/quartz/components/styles/listPage.scss
deleted file mode 100644
index e86c39dcb..000000000
--- a/quartz/components/styles/listPage.scss
+++ /dev/null
@@ -1,40 +0,0 @@
-@use "../../styles/variables.scss" as *;
-
-ul.section-ul {
- list-style: none;
- margin-top: 2em;
- padding-left: 0;
-}
-
-li.section-li {
- margin-bottom: 1em;
-
- & > .section {
- display: grid;
- grid-template-columns: fit-content(8em) 3fr 1fr;
-
- @media all and ($mobile) {
- & > .tags {
- display: none;
- }
- }
-
- & > .desc > h3 > a {
- background-color: transparent;
- }
-
- & .meta {
- margin: 0 1em 0 0;
- opacity: 0.6;
- }
- }
-}
-
-// modifications in popover context
-.popover .section {
- grid-template-columns: fit-content(8em) 1fr !important;
-
- & > .tags {
- display: none;
- }
-}
diff --git a/quartz/components/styles/mermaid.inline.scss b/quartz/components/styles/mermaid.inline.scss
deleted file mode 100644
index 4b11b6dd7..000000000
--- a/quartz/components/styles/mermaid.inline.scss
+++ /dev/null
@@ -1,132 +0,0 @@
-.expand-button {
- position: absolute;
- display: flex;
- float: right;
- padding: 0.4rem;
- margin: 0.3rem;
- right: 0; // NOTE: right will be set in mermaid.inline.ts
- color: var(--gray);
- border-color: var(--dark);
- background-color: var(--light);
- border: 1px solid;
- border-radius: 5px;
- opacity: 0;
- transition: 0.2s;
-
- & > svg {
- fill: var(--light);
- filter: contrast(0.3);
- }
-
- &:hover {
- cursor: pointer;
- border-color: var(--secondary);
- }
-
- &:focus {
- outline: 0;
- }
-}
-
-pre {
- &:hover > .expand-button {
- opacity: 1;
- transition: 0.2s;
- }
-}
-
-#mermaid-container {
- position: fixed;
- contain: layout;
- z-index: 999;
- left: 0;
- top: 0;
- width: 100vw;
- height: 100vh;
- overflow: hidden;
- display: none;
- backdrop-filter: blur(4px);
- background: rgba(0, 0, 0, 0.5);
-
- &.active {
- display: inline-block;
- }
-
- & > #mermaid-space {
- border: 1px solid var(--lightgray);
- background-color: var(--light);
- border-radius: 5px;
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- height: 80vh;
- width: 80vw;
- overflow: hidden;
-
- & > .mermaid-content {
- position: relative;
- transform-origin: 0 0;
- transition: transform 0.1s ease;
- overflow: visible;
- min-height: 200px;
- min-width: 200px;
-
- pre {
- margin: 0;
- border: none;
- }
-
- svg {
- max-width: none;
- height: auto;
- }
- }
-
- & > .mermaid-controls {
- position: absolute;
- bottom: 20px;
- right: 20px;
- display: flex;
- gap: 8px;
- padding: 8px;
- background: var(--light);
- border: 1px solid var(--lightgray);
- border-radius: 6px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- z-index: 2;
-
- .mermaid-control-button {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 32px;
- height: 32px;
- padding: 0;
- border: 1px solid var(--lightgray);
- background: var(--light);
- color: var(--dark);
- border-radius: 4px;
- cursor: pointer;
- font-size: 16px;
- font-family: var(--bodyFont);
- transition: all 0.2s ease;
-
- &:hover {
- background: var(--lightgray);
- }
-
- &:active {
- transform: translateY(1px);
- }
-
- // Style the reset button differently
- &:nth-child(2) {
- width: auto;
- padding: 0 12px;
- font-size: 14px;
- }
- }
- }
- }
-}