diff --git a/package-lock.json b/package-lock.json index d5c3e543..e4dd3129 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@kobalte/core": "0.13.11", "@opencode-ai/sdk": "0.15.13", "@solidjs/router": "^0.13.0", + "github-markdown-css": "^5.8.1", "ignore": "7.0.5", "lucide-solid": "^0.300.0", "marked": "^12.0.0", @@ -4499,6 +4500,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/github-markdown-css": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/github-markdown-css/-/github-markdown-css-5.8.1.tgz", + "integrity": "sha512-8G+PFvqigBQSWLQjyzgpa2ThD9bo7+kDsriUIidGcRhXgmcaAWUIpCZf8DavJgc+xifjbCG+GvMyWr0XMXmc7g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", diff --git a/package.json b/package.json index 654b3d32..f2bd4968 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@kobalte/core": "0.13.11", "@opencode-ai/sdk": "0.15.13", "@solidjs/router": "^0.13.0", + "github-markdown-css": "^5.8.1", "ignore": "7.0.5", "lucide-solid": "^0.300.0", "marked": "^12.0.0", diff --git a/src/components/markdown.tsx b/src/components/markdown.tsx index dadb2fdf..e3a2c8bf 100644 --- a/src/components/markdown.tsx +++ b/src/components/markdown.tsx @@ -133,17 +133,7 @@ export function Markdown(props: MarkdownProps) { }) }) - const proseClass = () => { - const classes = ["dark:prose-invert", "max-w-none", "prose-tight", "prose"] - - // if (props.size === "tight") { - // classes.push("prose-sm", "prose-tight") - // } else if (props.size === "sm") { - // classes.push("prose-sm") - // } - - return classes.join(" ") - } + const proseClass = () => "markdown-body" return
} diff --git a/src/styles/components.css b/src/styles/components.css index bc94084c..b943d926 100644 --- a/src/styles/components.css +++ b/src/styles/components.css @@ -776,6 +776,9 @@ button.button-primary:disabled { color: inherit; } +.message-text-assistant { + white-space: normal; +} .message-text pre { overflow-x: auto; diff --git a/src/styles/markdown.css b/src/styles/markdown.css index 51c72ac1..a672f8ed 100644 --- a/src/styles/markdown.css +++ b/src/styles/markdown.css @@ -1,321 +1,246 @@ -/* Markdown & Code Block Styles */ +@import "github-markdown-css/github-markdown-dark.css"; -/* Prose styles for markdown content */ -.prose { - color: var(--text-primary); - line-height: var(--line-height-tight) !important; +@layer components { + .markdown-body { + max-width: none; + background-color: transparent; + font-family: var(--font-family-sans); + font-size: var(--font-size-base); + line-height: var(--line-height-normal); + font-weight: var(--font-weight-regular); + color: var(--text-primary); + } + + .markdown-body p, + .markdown-body ul, + .markdown-body ol, + .markdown-body blockquote, + .markdown-body table { + font-size: inherit; + line-height: inherit; + color: inherit; + } + + .markdown-body h1, + .markdown-body h2, + .markdown-body h3, + .markdown-body h4, + .markdown-body h5, + .markdown-body h6 { + font-family: inherit; + color: inherit; + font-weight: var(--font-weight-semibold); + line-height: 1.3; + margin-top: 0.9em; + margin-bottom: 0.55em; + } + + .markdown-body h6 { + font-size: calc(var(--font-size-base) + 0.5px); + } + + .markdown-body h5 { + font-size: calc(var(--font-size-base) + 1px); + } + + .markdown-body h4 { + font-size: calc(var(--font-size-base) + 1.5px); + } + + .markdown-body h3 { + font-size: calc(var(--font-size-base) + 2px); + } + + .markdown-body h2 { + font-size: calc(var(--font-size-base) + 2.5px); + } + + .markdown-body h1 { + font-size: calc(var(--font-size-base) + 3px); + } + + .markdown-body h1, + .markdown-body h2 { + border-bottom: none; + padding-bottom: 0; + } + + .markdown-body hr { + display: none; + } + + .markdown-body strong { + font-weight: var(--font-weight-bold); + } + + .markdown-body em { + font-style: italic; + border-bottom: none; + font-size: calc(var(--font-size-base) + 1.5px); + margin-top: 0.3em; + margin-bottom: 0.3em; + display: inline; + } + + .markdown-body a { + color: var(--accent-primary); + text-decoration: none; + } + + .markdown-body a:hover { + color: var(--accent-hover); + text-decoration: underline; + } + + .markdown-body code { + font-family: var(--font-family-mono); + font-size: var(--font-size-sm); + background-color: var(--surface-muted); + border: 1px solid var(--border-base); + border-radius: 4px; + padding: 0.15em 0.35em; + } + + .markdown-body pre code { + padding: 0; + border: none; + background: transparent; + } + + .markdown-body pre { + font-family: var(--font-family-mono); + font-size: var(--font-size-sm); + line-height: var(--line-height-normal); + background-color: var(--surface-code); + border: 1px solid var(--border-base); + border-radius: 8px; + padding: 0.75rem; + margin: 1rem 0; + } + + .markdown-body blockquote { + border-left: 3px solid var(--border-base); + color: var(--text-secondary); + background-color: var(--surface-muted); + padding: 0.5rem 1rem; + border-radius: 0 8px 8px 0; + } + + .markdown-body ul, + .markdown-body ol { + padding-left: 1.5rem; + margin: 0.5rem 0; + } + + .markdown-body ul { + list-style-type: disc; + } + + .markdown-body ol { + list-style-type: decimal; + } + + .markdown-body ul li, + .markdown-body ol li { + margin: 0.25rem 0; + } + + .markdown-body table { + border-collapse: collapse; + width: 100%; + margin: 1rem 0; + background-color: transparent; + display: block; + padding-right: 0.75rem; + } + + .markdown-body thead, + .markdown-body tbody, + .markdown-body tfoot { + width: 100%; + display: table; + table-layout: fixed; + } + + .markdown-body th, + .markdown-body td { + border: 1px solid var(--border-base); + padding: 0.5rem 0.75rem; + text-align: left; + } + + .markdown-body th { + background-color: var(--surface-secondary); + } + + .markdown-code-block { + position: relative; + margin: 10px 0; + border-radius: 6px; + background-color: var(--surface-muted); + border: 1px solid var(--border-base); + } + + .code-block-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 4px 8px; + background-color: var(--surface-secondary); + border-bottom: 1px solid var(--border-base); + border-top-left-radius: 6px; + border-top-right-radius: 6px; + } + + .code-block-language { + font-family: var(--font-family-mono); + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.04em; + font-size: var(--font-size-sm); + } + + .code-block-copy { + display: flex; + align-items: center; + gap: 4px; + padding: 4px 8px; + background-color: transparent; + border: 1px solid var(--border-base); + border-radius: 4px; + cursor: pointer; + color: var(--text-secondary); + transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease; + margin-left: auto; + font-size: var(--font-size-sm); + } + + .code-block-copy:hover { + background-color: var(--surface-hover); + border-color: var(--accent-primary); + color: var(--accent-primary); + } + + .code-block-copy .copy-icon { + width: 14px; + height: 14px; + } + + .code-block-copy .copy-text { + font-family: var(--font-family-mono); + } + + .markdown-code-block pre { + margin: 0 !important; + padding: 12px !important; + overflow-x: auto; + background-color: transparent !important; + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + } + + .markdown-code-block code { + background: transparent !important; + padding: 0 !important; + } } - -.prose code { - background-color: var(--surface-secondary); - color: var(--text-primary); - padding: 2px 6px; - border-radius: 4px; - font-size: 0.9em; - font-family: var(--font-family-mono); -} - -.prose pre { - background-color: transparent; - padding: 0; - margin: 0; - overflow: visible; -} - -.prose pre code { - background: transparent; - padding: 0; - border-radius: 0; - font-size: 0.875em; -} - -.prose a { - color: var(--accent-primary); - text-decoration: none; -} - -.prose a:hover { - text-decoration: underline; -} - -.prose blockquote { - border-left: 4px solid var(--border-base); - padding-left: 16px; - font-style: italic; - color: var(--text-secondary); - margin: 12px 0; -} - -.prose ul, -.prose ol { - margin: 0; - padding-left: 24px; -} - -.prose ul { - margin: 0 !important; - list-style-type: disc; - line-height: var(--line-height-tight) !important; -} - -.prose ol { - margin: 0 !important; - list-style-type: decimal; - line-height: var(--line-height-tight) !important; -} - -.prose li { - margin: 0 !important; - line-height: var(--line-height-tight) !important; -} - -.prose h1 { - font-size: 1.5em; - font-weight: var(--font-weight-bold); - margin: 16px 0 12px 0; - line-height: var(--line-height-tight); -} - -.prose h2 { - font-size: 1.25em; - font-weight: var(--font-weight-bold); - margin: 14px 0 10px 0; - line-height: var(--line-height-tight); -} - -.prose h3 { - font-size: 1.1em; - font-weight: var(--font-weight-semibold); - margin: 12px 0 8px 0; - line-height: var(--line-height-tight); -} - -.prose table { - border-collapse: collapse; - width: 100%; - margin: 12px 0; - font-size: 0.9em; -} - -.prose th { - border: 1px solid var(--border-base); - padding: 8px 12px; - background-color: var(--surface-secondary); - font-weight: var(--font-weight-semibold); - text-align: left; -} - -.prose td { - border: 1px solid var(--border-base); - padding: 8px 12px; -} - -.prose p { - margin: 0 !important; - line-height: var(--line-height-normal) !important; -} - -.prose hr { - border: none; - border-top: 1px solid var(--border-base); - margin: 16px 0; -} - -/* Code block styles */ -.markdown-code-block { - position: relative; - margin: 12px 0; - border-radius: 6px; - background-color: var(--surface-muted); - border: 1px solid var(--border-base); -} - -.code-block-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 8px 12px; - background-color: var(--surface-secondary); - border-bottom: 1px solid var(--border-base); - border-top-left-radius: 6px; - border-top-right-radius: 6px; -} - -.code-block-language { - font-size: var(--font-size-xs); - font-family: var(--font-family-mono); - color: var(--text-secondary); - font-weight: var(--font-weight-medium); - text-transform: uppercase; -} - -.code-block-copy { - display: flex; - align-items: center; - gap: 4px; - padding: 4px 8px; - font-size: var(--font-size-xs); - background-color: transparent; - border: 1px solid var(--border-base); - border-radius: 4px; - cursor: pointer; - color: var(--text-secondary); - transition: all 150ms ease; - margin-left: auto; -} - -.code-block-copy:hover { - background-color: var(--surface-hover); - border-color: var(--border-base); -} - -.code-block-copy .copy-icon { - width: 14px; - height: 14px; -} - -.code-block-copy .copy-text { - font-family: var(--font-family-mono); -} - -.markdown-code-block pre { - margin: 0 !important; - padding: 12px !important; - overflow-x: auto; - background-color: transparent !important; - border-bottom-left-radius: 6px; - border-bottom-right-radius: 6px; -} - -.markdown-code-block code { - background: transparent !important; - padding: 0 !important; - font-size: 13px !important; - line-height: var(--line-height-relaxed); -} - -.code-block-inline { - position: relative; - margin: 8px 0; - border-radius: 6px; - overflow: hidden; - background-color: var(--surface-muted); - border: 1px solid var(--border-base); -} - -.code-block-inline .code-block-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 6px 10px; - background-color: var(--surface-secondary); - border-bottom: 1px solid var(--border-base); -} - -.code-block-inline pre { - margin: 0 !important; - padding: 10px !important; - overflow-x: auto; - background-color: transparent !important; -} - -.code-block-inline code { - background: transparent !important; - padding: 0 !important; - font-size: var(--font-size-xs) !important; - line-height: var(--line-height-normal); -} - -.message-text-assistant .prose p { - margin: 0; -} - - -.message-text-assistant .prose ul { - margin: 0; - padding-left: 16px; - line-height: 1; -} - -.message-text-assistant .prose ol { - margin: 0; - padding-left: 16px; - line-height: 1; -} - -.message-text-assistant .prose ul + * { - margin-top: 8px; -} - -.message-text-assistant .prose ul + ol { - margin-top: 4px; -} - -.message-text-assistant .prose ol + * { - margin-top: 14px; - line-height: 1.05; -} - -.message-text-assistant .prose ol + a, -.message-text-assistant .prose ol + code, -.message-text-assistant .prose ol + img { - margin-top: 14px !important; - display: inline-block; -} - -.message-text-assistant .prose li { - margin: 0; - line-height: 1; -} - -.message-text-assistant .prose li + li { - margin-top: 2px; -} - -.message-text-assistant .prose li:last-child { - margin-bottom: 0; - padding-bottom: 0; -} - -.message-text-assistant .prose li > br { - display: block; - margin: 0; -} - -.message-text-assistant .prose li > br + a, -.message-text-assistant .prose li > br + code, -.message-text-assistant .prose li > br + img { - display: inline-block; - margin-top: 12px !important; -} - -.message-text-assistant .prose h1 { - margin: 4px 0 2px; - font-size: 1.22em; - line-height: 1.15; -} - -.message-text-assistant .prose h2 { - margin: 3px 0 2px; - font-size: 1.12em; - line-height: 1.15; -} - -.message-text-assistant .prose h3 { - margin: 2px 0 2px; - font-size: 1.05em; - line-height: 1.15; -} - -.message-text-assistant .prose blockquote { - margin: 6px 0 10px; - padding-left: 12px; -} - -.message-text-assistant .prose blockquote p { - margin: 0; -} - - - -