fix: replace prose plugin with custom CSS for markdown styling

This commit is contained in:
2026-05-01 09:49:26 +08:00
parent 7749162414
commit 7bcd580397
4 changed files with 148 additions and 37 deletions
+139 -18
View File
@@ -1,5 +1,4 @@
@import "tailwindcss"; @import "tailwindcss";
@plugin "@tailwindcss/typography";
@theme inline { @theme inline {
/* Colors */ /* Colors */
@@ -15,23 +14,6 @@
/* Defaults */ /* Defaults */
--default-transition-duration: 0.3s; --default-transition-duration: 0.3s;
/* Prose */
--prose-body: var(--color-text);
--prose-headings: var(--color-text);
--prose-links: var(--color-primary);
--prose-bold: var(--color-text);
--prose-counters: var(--color-text);
--prose-bullets: var(--color-text);
--prose-hr: var(--color-border);
--prose-quotes: var(--color-text);
--prose-quote-borders: var(--color-border);
--prose-captions: var(--color-text);
--prose-code: var(--color-accent);
--prose-pre-code: var(--color-text);
--prose-pre-bg: var(--color-foreground);
--prose-th-borders: var(--color-border);
--prose-td-borders: var(--color-border);
/* Fonts */ /* Fonts */
--font-sans: var(--font-lexend); --font-sans: var(--font-lexend);
} }
@@ -43,3 +25,142 @@
.scrollbar-hide::-webkit-scrollbar { .scrollbar-hide::-webkit-scrollbar {
display: none; display: none;
} }
/* Markdown content styles */
.update-content {
color: var(--color-text);
}
.update-content h2 {
font-size: 1.5rem;
font-weight: 700;
margin-top: 2.5rem;
margin-bottom: 1rem;
color: var(--color-text);
}
.update-content h3 {
font-size: 1.125rem;
font-weight: 600;
margin-top: 1.5rem;
margin-bottom: 0.75rem;
color: var(--color-text);
}
.update-content p {
margin-bottom: 0.75rem;
line-height: 1.7;
color: rgba(235, 228, 241, 0.8);
}
.update-content ul {
list-style-type: disc;
padding-left: 1.5rem;
margin-bottom: 1rem;
}
.update-content ol {
list-style-type: decimal;
padding-left: 1.5rem;
margin-bottom: 1rem;
}
.update-content li {
margin-bottom: 0.375rem;
line-height: 1.6;
}
.update-content li > ul,
.update-content li > ol {
margin-top: 0.25rem;
margin-bottom: 0.5rem;
}
.update-content a {
color: var(--color-primary);
text-decoration: none;
transition: opacity 0.2s;
}
.update-content a:hover {
text-decoration: underline;
opacity: 0.8;
}
/* Hide anchor link icons from rehype-autolink-headings by default */
.update-content a[aria-hidden="true"] {
text-decoration: none;
margin-right: 0.375rem;
opacity: 0;
transition: opacity 0.2s;
}
.update-content h2:hover a[aria-hidden="true"],
.update-content h3:hover a[aria-hidden="true"] {
opacity: 0.4;
}
.update-content a[aria-hidden="true"]::before {
content: "#";
font-size: 0.75rem;
font-weight: 400;
}
.update-content code {
color: var(--color-accent);
background: rgba(235, 228, 241, 0.06);
padding: 0.125rem 0.375rem;
border-radius: 0.25rem;
font-size: 0.875rem;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}
.update-content pre {
background: rgba(235, 228, 241, 0.06);
padding: 1rem;
border-radius: 0.5rem;
overflow-x: auto;
margin-bottom: 1rem;
}
.update-content pre code {
background: transparent;
padding: 0;
}
.update-content strong {
font-weight: 700;
color: var(--color-text);
}
.update-content hr {
border: none;
border-top: 1px solid var(--color-border);
margin: 2rem 0;
}
.update-content blockquote {
border-left: 3px solid var(--color-primary);
padding-left: 1rem;
margin: 1rem 0;
color: rgba(235, 228, 241, 0.7);
font-style: italic;
}
.update-content table {
width: 100%;
border-collapse: collapse;
margin-bottom: 1rem;
}
.update-content th,
.update-content td {
border: 1px solid var(--color-border);
padding: 0.5rem 0.75rem;
text-align: left;
}
.update-content th {
font-weight: 600;
background: rgba(235, 228, 241, 0.05);
}
-9
View File
@@ -9,7 +9,6 @@
"@better-auth/drizzle-adapter": "^1.6.9", "@better-auth/drizzle-adapter": "^1.6.9",
"@better-auth/passkey": "^1.6.9", "@better-auth/passkey": "^1.6.9",
"@elysia/eden": "^1.4.10", "@elysia/eden": "^1.4.10",
"@tailwindcss/typography": "^0.5.19",
"@tiptap/core": "^3.22.4", "@tiptap/core": "^3.22.4",
"@tiptap/extension-link": "^3.22.4", "@tiptap/extension-link": "^3.22.4",
"@tiptap/extension-placeholder": "^3.22.4", "@tiptap/extension-placeholder": "^3.22.4",
@@ -600,8 +599,6 @@
"@tailwindcss/postcss": ["@tailwindcss/postcss@4.2.4", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.2.4", "@tailwindcss/oxide": "4.2.4", "postcss": "^8.5.6", "tailwindcss": "4.2.4" } }, "sha512-wgAVj6nUWAolAu8YFvzT2cTBIElWHkjZwFYovF+xsqKsW2ADxM/X2opxj5NsF/qVccAOjRNe8X2IdPzMsWyHTg=="], "@tailwindcss/postcss": ["@tailwindcss/postcss@4.2.4", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.2.4", "@tailwindcss/oxide": "4.2.4", "postcss": "^8.5.6", "tailwindcss": "4.2.4" } }, "sha512-wgAVj6nUWAolAu8YFvzT2cTBIElWHkjZwFYovF+xsqKsW2ADxM/X2opxj5NsF/qVccAOjRNe8X2IdPzMsWyHTg=="],
"@tailwindcss/typography": ["@tailwindcss/typography@0.5.19", "", { "dependencies": { "postcss-selector-parser": "6.0.10" }, "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg=="],
"@tiptap/core": ["@tiptap/core@3.22.4", "", { "peerDependencies": { "@tiptap/pm": "3.22.4" } }, "sha512-vGIGm/HpqLg8EAAQXQ+koV+/S828OEpzocfWcPOwo1u2QUVf9dQG47Yy6JJ8zFFaJwfv4dBcOXli+7BrJwsxDQ=="], "@tiptap/core": ["@tiptap/core@3.22.4", "", { "peerDependencies": { "@tiptap/pm": "3.22.4" } }, "sha512-vGIGm/HpqLg8EAAQXQ+koV+/S828OEpzocfWcPOwo1u2QUVf9dQG47Yy6JJ8zFFaJwfv4dBcOXli+7BrJwsxDQ=="],
"@tiptap/extension-blockquote": ["@tiptap/extension-blockquote@3.22.4", "", { "peerDependencies": { "@tiptap/core": "3.22.4" } }, "sha512-7/61kNPbGFhMgM//zMknD0pSb69rGdRIkpulXOWS1JBrFHkH6hjZDfrOETNzgKkO+NlmzVl9rXSTv0xauS3lzA=="], "@tiptap/extension-blockquote": ["@tiptap/extension-blockquote@3.22.4", "", { "peerDependencies": { "@tiptap/core": "3.22.4" } }, "sha512-7/61kNPbGFhMgM//zMknD0pSb69rGdRIkpulXOWS1JBrFHkH6hjZDfrOETNzgKkO+NlmzVl9rXSTv0xauS3lzA=="],
@@ -870,8 +867,6 @@
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
"cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
"damerau-levenshtein": ["damerau-levenshtein@1.0.8", "", {}, "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="], "damerau-levenshtein": ["damerau-levenshtein@1.0.8", "", {}, "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="],
@@ -1390,8 +1385,6 @@
"postcss": ["postcss@8.5.10", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ=="], "postcss": ["postcss@8.5.10", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ=="],
"postcss-selector-parser": ["postcss-selector-parser@6.0.10", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="],
"postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], "postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="],
"postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="], "postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="],
@@ -1646,8 +1639,6 @@
"use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="],
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
"uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="], "uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="],
"vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="],
+9 -9
View File
@@ -18,7 +18,14 @@ export function UpdateViewer({
return ( return (
<> <>
<ReadingProgressBar /> <ReadingProgressBar />
<div className="w-full max-w-4xl mx-auto px-4 py-8 flex flex-row gap-8"> <div className="w-full max-w-7xl mx-auto px-4 py-8 flex flex-row gap-8">
{/* Chapter navigation sidebar (desktop) */}
<aside className="hidden md:block w-48 shrink-0">
<div className="sticky top-20">
<ChapterNav headings={update.headings} />
</div>
</aside>
{/* Main content */} {/* Main content */}
<article className="flex-1 min-w-0"> <article className="flex-1 min-w-0">
<header className="mb-8"> <header className="mb-8">
@@ -31,17 +38,10 @@ export function UpdateViewer({
<h1 className="text-2xl md:text-3xl font-bold">{update.meta.title}</h1> <h1 className="text-2xl md:text-3xl font-bold">{update.meta.title}</h1>
</header> </header>
<div <div
className="prose prose-invert prose-p:text-text/80 prose-headings:text-text prose-a:text-primary prose-a:no-underline hover:prose-a:underline prose-strong:text-text prose-code:text-accent prose-code:bg-text/5 prose-code:px-1 prose-code:py-0.5 prose-code:rounded prose-code:text-sm prose-li:text-text/80 prose-ul:list-disc prose-ol:list-decimal max-w-none" className="update-content max-w-none"
dangerouslySetInnerHTML={{ __html: update.html }} dangerouslySetInnerHTML={{ __html: update.html }}
/> />
</article> </article>
{/* Chapter navigation sidebar (desktop) */}
<aside className="hidden md:block w-48 shrink-0">
<div className="sticky top-20">
<ChapterNav headings={update.headings} />
</div>
</aside>
</div> </div>
{/* Mobile chapter nav (rendered inside viewer for context) */} {/* Mobile chapter nav (rendered inside viewer for context) */}
-1
View File
@@ -20,7 +20,6 @@
"@better-auth/drizzle-adapter": "^1.6.9", "@better-auth/drizzle-adapter": "^1.6.9",
"@better-auth/passkey": "^1.6.9", "@better-auth/passkey": "^1.6.9",
"@elysia/eden": "^1.4.10", "@elysia/eden": "^1.4.10",
"@tailwindcss/typography": "^0.5.19",
"@tiptap/core": "^3.22.4", "@tiptap/core": "^3.22.4",
"@tiptap/extension-link": "^3.22.4", "@tiptap/extension-link": "^3.22.4",
"@tiptap/extension-placeholder": "^3.22.4", "@tiptap/extension-placeholder": "^3.22.4",