feat: add syntax highlighting and code block styling with theme support

This commit is contained in:
2025-10-21 08:34:46 -04:00
parent 062d743481
commit d788c9d267
75 changed files with 4783 additions and 830 deletions
+2 -1
View File
@@ -226,8 +226,9 @@
Focus Styles (Accessibility)
============================================ */
.cm-editor.cm-focused {
outline: 2px solid var(--cm-cursor);
outline: 2px solid var(--ring);
outline-offset: -2px;
box-shadow: 0 0 0 2px color-mix(in oklab, var(--ring) 25%, transparent);
}
/* ============================================
+9
View File
@@ -167,6 +167,15 @@
outline-offset: 2px;
}
.toc-toggle--idle {
color: var(--toc-muted);
}
.toc-toggle--active {
color: var(--toc-active);
filter: drop-shadow(0 0 4px color-mix(in oklab, var(--toc-active) 45%, transparent));
}
.badge {
@apply inline-flex items-center rounded-full px-2.5 py-1 text-xs font-semibold uppercase tracking-wide;
background-color: color-mix(in srgb, var(--bg-muted) 90%, transparent);
+109
View File
@@ -0,0 +1,109 @@
/* Scoped Markdown display styles */
.md-view {
color: var(--md-text);
line-height: 1.65;
}
/* Headings */
.md-view h1, .md-view h2, .md-view h3, .md-view h4, .md-view h5, .md-view h6 {
scroll-margin-top: 84px;
font-weight: 700;
}
.md-view h1 { color: var(--md-h1, var(--md-text)); font-size: 2rem; letter-spacing:-0.01em; }
.md-view h2 { color: var(--md-h2, var(--md-text)); font-size: 1.6rem; border-bottom: 1px solid var(--md-hr); padding-bottom: .25rem; }
.md-view h3 { color: var(--md-h3, var(--md-heading-accent)); font-size: 1.25rem; }
.md-view h4 { color: var(--md-heading-accent); font-size: 1.1rem; }
.md-view h5 { color: var(--md-muted); font-size: 1rem; font-weight: 600; }
.md-view h6 { color: var(--md-muted); font-size: .9rem; font-weight: 600; opacity:.85; }
/* Text, emphasis, inline code */
.md-view p { margin: .6rem 0; }
.md-view strong { font-weight: 700; }
.md-view em { font-style: italic; }
.md-view del { opacity:.8; text-decoration-thickness: .1rem; }
.md-view code {
background: var(--md-code-bg);
color: var(--md-code-fg);
border: 1px solid var(--md-pre-border);
border-radius: .45rem;
padding: .12rem .35rem;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
font-size: .94em;
}
/* Links & images */
.md-view a { color: var(--md-link); text-decoration: none; border-bottom: 1px dashed color-mix(in oklab, var(--md-link) 55%, transparent); }
.md-view a:hover { color: var(--md-link-hover); border-bottom-style: solid; }
.md-view img { max-width: 100%; border-radius: .5rem; display:block; margin: .5rem auto; }
/* Lists */
.md-view ul, .md-view ol { margin: .6rem 0 .6rem 1.25rem; }
.md-view li { margin: .25rem 0; }
.md-view ul ul, .md-view ol ol { margin-top:.25rem; }
/* Tasks */
.md-view input[type="checkbox"] {
appearance:none; width:1.05rem; height:1.05rem; margin-right:.5rem; vertical-align: middle;
border:1.5px solid var(--md-task-border); border-radius:.35rem; background:var(--md-task-bg);
}
.md-view input[type="checkbox"]:checked {
background: conic-gradient(var(--md-task-check) 0 100%, transparent 0);
border-color: var(--md-task-check);
}
/* Blockquote */
.md-view blockquote {
margin: .8rem 0; padding:.6rem .9rem;
background: var(--md-quote-bg);
border-left: .25rem solid var(--md-quote-bar);
color: var(--md-quote-fg);
border-radius: .5rem;
}
/* Code fences */
.md-view pre {
background: var(--md-pre-bg);
color: var(--md-pre-fg);
border:1px solid var(--md-pre-border);
border-radius:.75rem;
padding: .9rem 1rem;
overflow:auto;
}
.md-view pre code { background: transparent; border:0; padding:0; }
/* Tables */
.md-view table { width:100%; border-collapse: collapse; margin: .8rem 0; font-size:.95rem; }
.md-view thead th {
text-align:left; background: var(--md-table-head-bg);
border-bottom:1px solid var(--md-table-border); padding:.6rem .5rem; font-weight:600;
}
.md-view tbody td {
border-bottom:1px solid var(--md-table-border); padding:.6rem .5rem;
}
.md-view tbody tr:nth-child(even) { background: var(--md-table-row-alt); }
/* Separators */
.md-view hr { border:none; height:1px; background: var(--md-hr); margin:1.2rem 0; }
/* Footnotes */
.md-view sup.footnote-ref a { color: var(--md-fn-sup); font-weight:600; }
.md-view .footnotes { border-top:1px solid var(--md-fn-rule); margin-top:1rem; padding-top:.6rem; font-size:.9rem; color: var(--md-muted); }
/* Embedded HTML */
.md-view iframe, .md-view video { max-width:100%; border-radius:.5rem; }
/* Anchor visible on hover */
.md-view .heading-anchor {
opacity:0; margin-left:.25rem; font-size:.85em; color: var(--md-muted); text-decoration:none;
}
.md-view h1:hover .heading-anchor,
.md-view h2:hover .heading-anchor,
.md-view h3:hover .heading-anchor,
.md-view h4:hover .heading-anchor,
.md-view h5:hover .heading-anchor,
.md-view h6:hover .heading-anchor { opacity:1; }
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
.md-view * { transition: none !important; animation: none !important; }
}
+28
View File
@@ -0,0 +1,28 @@
/* Syntax highlighting mapped to Markdown tokens (Highlight.js selectors) */
.md-view pre code.hljs .hljs-keyword { color: var(--md-syntax-1); }
.md-view pre code.hljs .hljs-built_in { color: var(--md-syntax-2); }
.md-view pre code.hljs .hljs-type { color: var(--md-syntax-2); }
.md-view pre code.hljs .hljs-title { color: var(--md-syntax-2); }
.md-view pre code.hljs .hljs-string { color: var(--md-syntax-3); }
.md-view pre code.hljs .hljs-number { color: var(--md-syntax-4); }
.md-view pre code.hljs .hljs-literal { color: var(--md-syntax-4); }
.md-view pre code.hljs .hljs-attr { color: var(--md-syntax-2); }
.md-view pre code.hljs .hljs-attribute { color: var(--md-syntax-2); }
.md-view pre code.hljs .hljs-params { color: var(--md-syntax-2); }
.md-view pre code.hljs .hljs-selector-tag { color: var(--md-syntax-1); }
.md-view pre code.hljs .hljs-selector-id { color: var(--md-syntax-2); }
.md-view pre code.hljs .hljs-selector-class { color: var(--md-syntax-2); }
.md-view pre code.hljs .hljs-variable { color: var(--md-syntax-5); }
.md-view pre code.hljs .hljs-template-variable { color: var(--md-syntax-5); }
.md-view pre code.hljs .hljs-symbol { color: var(--md-syntax-5); }
.md-view pre code.hljs .hljs-bullet { color: var(--md-syntax-5); }
.md-view pre code.hljs .hljs-meta { color: var(--md-syntax-5); }
.md-view pre code.hljs .hljs-comment { opacity: .75; }
/* Prism fallback (if used) */
.md-view pre[class*="language-"] .token.keyword { color: var(--md-syntax-1); }
.md-view pre[class*="language-"] .token.function { color: var(--md-syntax-2); }
.md-view pre[class*="language-"] .token.string { color: var(--md-syntax-3); }
.md-view pre[class*="language-"] .token.number { color: var(--md-syntax-4); }
.md-view pre[class*="language-"] .token.punctuation,
.md-view pre[class*="language-"] .token.operator { color: var(--md-syntax-5); }
File diff suppressed because it is too large Load Diff
+30
View File
@@ -0,0 +1,30 @@
/* TOC styles for pane and page */
.toc-pane, .toc-page {
background: var(--toc-bg);
color: var(--toc-fg);
border-left: 1px solid var(--toc-border);
}
.toc-page { border:1px solid var(--toc-border); border-radius:1rem; padding:1rem; }
.toc-list { list-style:none; margin:0; padding:.25rem .5rem .75rem .5rem; }
.toc-item { margin:.15rem 0; }
.toc-link {
display:flex; gap:.45rem; align-items:center;
padding:.35rem .5rem; border-radius:.5rem; color: var(--toc-fg);
text-decoration:none; border:1px solid transparent;
}
.toc-link:hover { color: var(--toc-hover); background: color-mix(in oklab, var(--surface-2) 88%, transparent); }
.toc-link.active {
color: var(--toc-active);
background: color-mix(in oklab, var(--surface-2) 80%, transparent);
border-color: color-mix(in oklab, var(--toc-active) 40%, var(--toc-border));
}
.toc-depth-2 { padding-left: .75rem; }
.toc-depth-3 { padding-left: 1.25rem; opacity:.95; }
.toc-depth-4 { padding-left: 1.75rem; opacity:.85; }
.toc-muted { color: var(--toc-muted); font-size:.9em; }
.toc-link:focus-visible { outline: 2px solid var(--toc-active); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
.toc-link { transition: none !important; }
}