feat(chat): tighten markdown typography and unify text selection colour
Chat prose read looser than the rest of the app: 15px body with a single line-height for everything, headings barely larger than the text, list bullets drawn as dashes with a 2em gutter, no vertical rhythm for lists or quotes, and inline code that took a syntax colour from the theme. Body text is 14px with a whole-pixel line height (22.75px rounded to 23px so baselines stay on the pixel grid). Every block carries the same 0.65rem margin on both sides, so any two neighbours are one spacing apart and the outer blocks add nothing. Headings step 20/18/16/14px at weight 600 with more air above than below. Lists use native markers that cycle by depth with a 1.25rem gutter and 0.25rem between items; task-list checkboxes replace the marker. Blockquotes get their left rule back. Headings, list markers and inline code render in the text colour; inline code is a muted chip one step smaller than the prose. The inlineCode theme tokens are removed from the built-in themes, the generator and the VS Code adapter; custom themes that still carry them are simply ignored. The remaining semantic sizes shrink by the same step (code 12px, labels and meta 13px, settings title 17px), in VS Code proportionally. Text selection in chat used the browser default in dark themes while the comment overlay painted the theme's row-selection token, so the colour changed the moment Comment was clicked; that token is also nearly the page background in several light themes and opaque in monokai, where the overlay hid the text. Native selection, file-preview selection and the overlay now share one translucent accent tint (primary at 30%), which stays visible over every built-in theme's background. Testing: ui type-check and lint; all theme JSON re-parsed; screenshots of prose, lists and the selection/comment states in headless Chrome; contrast of the new selection tint computed against every theme's background and text.
This commit is contained in:
@@ -103,8 +103,8 @@ const STYLE_CLASS: Record<AnyStyle, string> = {
|
||||
mentionAgent: 'text-[var(--status-success)]',
|
||||
mentionCommand: 'text-[var(--primary)]',
|
||||
mentionSnippet: 'text-[var(--status-warning)]',
|
||||
code: 'rounded-[6px] bg-[var(--markdown-inline-code-bg)] text-[var(--markdown-inline-code)]',
|
||||
codeFence: 'bg-[var(--surface-subtle)] text-[var(--markdown-inline-code)]',
|
||||
code: 'rounded-[6px] bg-[var(--surface-muted)]',
|
||||
codeFence: 'bg-[var(--surface-subtle)]',
|
||||
// A `~path` is written for the reader's benefit, not to attach anything —
|
||||
// it takes the same colour as a file mention, since it names the same kind
|
||||
// of thing.
|
||||
|
||||
@@ -2162,7 +2162,7 @@ const AssistantMessageBody = React.memo(({
|
||||
) : null}
|
||||
<div>
|
||||
<div
|
||||
className="message-content-text leading-relaxed overflow-hidden text-foreground/90 [&_p:last-child]:mb-0 [&_ul:last-child]:mb-0 [&_ol:last-child]:mb-0"
|
||||
className="message-content-text leading-relaxed overflow-hidden text-foreground/80 [&_p:last-child]:mb-0 [&_ul:last-child]:mb-0 [&_ol:last-child]:mb-0"
|
||||
>
|
||||
{renderedParts}
|
||||
{showErrorMessage && (
|
||||
|
||||
+64
-66
@@ -75,11 +75,15 @@ button,
|
||||
line-height: round(1.625em, 1px);
|
||||
}
|
||||
|
||||
:root.light .message-content-text::selection,
|
||||
:root.light .message-content-text ::selection,
|
||||
:root.light .oc-file-preview::selection,
|
||||
:root.light .oc-file-preview ::selection {
|
||||
background: color-mix(in srgb, var(--interactive-border-focus) 18%, transparent);
|
||||
/* Text selection in chat and file previews: the theme accent at 30%, the same
|
||||
in every theme. The themes' own selection token is tuned for selected rows
|
||||
and in several light themes is nearly the page background; a translucent
|
||||
accent stays visible over every background and never hides the text. */
|
||||
.message-content-text::selection,
|
||||
.message-content-text ::selection,
|
||||
.oc-file-preview::selection,
|
||||
.oc-file-preview ::selection {
|
||||
background: var(--oc-text-selection);
|
||||
color: var(--surface-foreground);
|
||||
}
|
||||
|
||||
@@ -89,14 +93,12 @@ button,
|
||||
|
||||
/* Quoted chat fragment kept visibly highlighted while its comment input is
|
||||
open (the native selection collapses once the input takes focus). The
|
||||
rectangles come from the selection's own client rects, so shape and shade
|
||||
both match the native selection that was just showing. */
|
||||
rectangles come from the selection's own client rects and paint in the
|
||||
selection colour, so shape and shade both match the native selection that
|
||||
was just showing; the colour is translucent because these rectangles sit
|
||||
above the text. */
|
||||
.oc-chat-comment-rect {
|
||||
background-color: var(--interactive-selection);
|
||||
}
|
||||
|
||||
:root.light .oc-chat-comment-rect {
|
||||
background-color: color-mix(in srgb, var(--interactive-border-focus) 18%, transparent);
|
||||
background-color: var(--oc-text-selection);
|
||||
}
|
||||
|
||||
.pierre-diff-wrapper {
|
||||
@@ -995,11 +997,13 @@ html:not(.dark) .chat-scroll {
|
||||
}
|
||||
}
|
||||
|
||||
/* Text font */
|
||||
/* Text font. The line height is snapped to whole pixels: a fractional
|
||||
value lets glyph baselines land on half pixels and text lines blur or
|
||||
render unevenly as they scroll. */
|
||||
.markdown-content {
|
||||
font-family: var(--font-sans);
|
||||
font-size: var(--text-markdown);
|
||||
line-height: inherit;
|
||||
line-height: round(1.625em, 1px);
|
||||
}
|
||||
|
||||
.markdown-content p,
|
||||
@@ -1010,20 +1014,31 @@ html:not(.dark) .chat-scroll {
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
/* Restore paragraph block spacing inside markdown content. The
|
||||
--markdown-paragraph-spacing token existed but was never wired, so Tailwind
|
||||
preflight's zeroed <p> margins left adjacent paragraphs collapsed into one
|
||||
visual line. */
|
||||
.markdown-content p {
|
||||
margin: 0 0 var(--markdown-paragraph-spacing) 0;
|
||||
/* Block rhythm: every block carries the same margin on both sides, so the
|
||||
gap between any two neighbours is one paragraph spacing (margins collapse)
|
||||
and the first/last block of a message adds nothing. Tailwind preflight
|
||||
zeroes these margins, which left adjacent paragraphs reading as one. */
|
||||
.markdown-content p,
|
||||
.markdown-content ul,
|
||||
.markdown-content ol,
|
||||
.markdown-content blockquote,
|
||||
.markdown-content hr,
|
||||
.markdown-content table {
|
||||
margin: var(--markdown-paragraph-spacing) 0;
|
||||
}
|
||||
|
||||
/* The markdown renderer wraps each block in a display:contents [data-md-block]
|
||||
element, so the message-level [&_.markdown-content>*:last-child]:mb-0
|
||||
nullifiers target the wrapper (where margin is ignored), not the paragraph.
|
||||
Drop the trailing margin on the last paragraph of the last block directly so
|
||||
messages don't gain extra space at the bottom. */
|
||||
.markdown-content > [data-md-block]:last-child p:last-child {
|
||||
element, so the message-level [&_.markdown-content>*:first-child]:mt-0 /
|
||||
[&_.markdown-content>*:last-child]:mb-0 nullifiers target the wrapper
|
||||
(where margin is ignored), not the block. Trim the outer blocks directly so
|
||||
messages gain no extra space at the top or bottom. */
|
||||
.markdown-content > [data-md-block]:first-child > :first-child,
|
||||
.markdown-content > :first-child:not([data-md-block]) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.markdown-content > [data-md-block]:last-child > :last-child,
|
||||
.markdown-content > :last-child:not([data-md-block]) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@@ -1110,35 +1125,35 @@ html:not(.dark) .chat-scroll {
|
||||
font-size: inherit !important;
|
||||
}
|
||||
|
||||
/* Streamdown headers: keep proportional but not oversized */
|
||||
.markdown-content h1 {
|
||||
font-size: 1.125em;
|
||||
/* Headings: a clear step above the body without becoming display type, and
|
||||
more air above than below so each heading binds to the text it introduces. */
|
||||
.markdown-content h1,
|
||||
.markdown-content h2,
|
||||
.markdown-content h3,
|
||||
.markdown-content h4,
|
||||
.markdown-content h5,
|
||||
.markdown-content h6 {
|
||||
margin: 1.25rem 0 0.5rem;
|
||||
font-weight: 600;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 0.5em;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.markdown-content h1 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.markdown-content h2 {
|
||||
font-size: 1.0625em;
|
||||
font-weight: 600;
|
||||
margin-top: 0.875em;
|
||||
margin-bottom: 0.375em;
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
.markdown-content h3 {
|
||||
font-size: 1em;
|
||||
font-weight: 600;
|
||||
margin-top: 0.75em;
|
||||
margin-bottom: 0.25em;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.markdown-content h4,
|
||||
.markdown-content h5,
|
||||
.markdown-content h6 {
|
||||
font-size: 1em;
|
||||
font-weight: 600;
|
||||
margin-top: 0.625em;
|
||||
margin-bottom: 0.25em;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
/* Code font */
|
||||
@@ -1148,35 +1163,17 @@ html:not(.dark) .chat-scroll {
|
||||
font-size: var(--text-code);
|
||||
}
|
||||
|
||||
/* Override Streamdown's hardcoded bg-muted for inline code - use theme colors instead */
|
||||
/* Inline code sits inside a sentence: a quiet muted chip in the text colour,
|
||||
one step smaller than the prose so it never towers over it. */
|
||||
.markdown-content code[data-markdown="inline-code"] {
|
||||
background-color: var(--markdown-inline-code-bg, var(--surface-subtle)) !important;
|
||||
color: var(--markdown-inline-code, var(--foreground)) !important;
|
||||
padding: 0.125rem 0.3125rem;
|
||||
background-color: var(--surface-muted) !important;
|
||||
color: inherit !important;
|
||||
padding: 0.1rem 0.35rem;
|
||||
border-radius: 0.375rem;
|
||||
word-break: break-all;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
/* Markdown headings - use theme colors */
|
||||
.markdown-content h1 {
|
||||
color: var(--markdown-heading1, var(--primary));
|
||||
}
|
||||
|
||||
.markdown-content h2 {
|
||||
color: var(--markdown-heading2, var(--primary));
|
||||
}
|
||||
|
||||
.markdown-content h3 {
|
||||
color: var(--markdown-heading3, var(--primary));
|
||||
}
|
||||
|
||||
.markdown-content h4,
|
||||
.markdown-content h5,
|
||||
.markdown-content h6 {
|
||||
color: var(--markdown-heading4, var(--foreground));
|
||||
}
|
||||
|
||||
/* Markdown links - use theme colors */
|
||||
.markdown-content a {
|
||||
color: var(--markdown-link, var(--primary));
|
||||
@@ -1212,8 +1209,9 @@ html:not(.dark) .chat-scroll {
|
||||
|
||||
/* Markdown blockquote - use theme colors */
|
||||
.markdown-content blockquote {
|
||||
border-left: 2px solid var(--markdown-blockquote-border, var(--border));
|
||||
padding-left: 0.8rem;
|
||||
color: var(--markdown-blockquote, var(--muted-foreground));
|
||||
border-left-color: var(--markdown-blockquote-border, var(--border));
|
||||
}
|
||||
|
||||
/* Markdown horizontal rule - use theme colors */
|
||||
|
||||
@@ -79,7 +79,7 @@ const markdownHighlight = () => syntaxHighlighting(HighlightStyle.define([
|
||||
{ tag: t.emphasis, fontStyle: 'italic' },
|
||||
{ tag: t.strikethrough, textDecoration: 'line-through' },
|
||||
{ tag: [t.link, t.url], color: 'var(--markdown-link, currentColor)', textDecoration: 'underline' },
|
||||
{ tag: t.monospace, color: 'var(--markdown-inline-code, currentColor)', backgroundColor: 'var(--markdown-inline-code-bg, transparent)' },
|
||||
{ tag: t.monospace, backgroundColor: 'var(--surface-muted)' },
|
||||
{ tag: t.quote, color: 'var(--markdown-blockquote, currentColor)', fontStyle: 'italic' },
|
||||
{ tag: t.list, color: 'color-mix(in srgb, var(--muted-foreground) 40%, var(--foreground) 60%)' },
|
||||
{ tag: t.heading, color: 'var(--markdown-heading1, currentColor)' },
|
||||
|
||||
@@ -370,7 +370,6 @@ const sidebarBaseRgb = hexToRgb(theme.colors.surface.muted);
|
||||
private generateMarkdownColors(markdown: Record<string, string>, theme: Theme): string[] {
|
||||
const vars: string[] = [];
|
||||
const primary = theme.colors.primary.base;
|
||||
const chatBackground = theme.colors.chat?.background || theme.colors.surface.background;
|
||||
|
||||
vars.push(` --markdown-heading1: ${markdown.heading1 || primary};`);
|
||||
vars.push(` --markdown-heading2: ${markdown.heading2 || this.opacity(primary, 0.9)};`);
|
||||
@@ -378,8 +377,6 @@ const sidebarBaseRgb = hexToRgb(theme.colors.surface.muted);
|
||||
vars.push(` --markdown-heading4: ${markdown.heading4 || theme.colors.surface.foreground};`);
|
||||
vars.push(` --markdown-link: ${markdown.link || primary};`);
|
||||
vars.push(` --markdown-link-hover: ${markdown.linkHover || theme.colors.primary.hover || this.darken(primary, 10)};`);
|
||||
vars.push(` --markdown-inline-code: ${markdown.inlineCode || theme.colors.syntax.base.string};`);
|
||||
vars.push(` --markdown-inline-code-bg: ${markdown.inlineCodeBackground || chatBackground};`);
|
||||
vars.push(` --markdown-blockquote: ${markdown.blockquote || theme.colors.surface.mutedForeground};`);
|
||||
vars.push(` --markdown-blockquote-border: ${markdown.blockquoteBorder || theme.colors.interactive.border};`);
|
||||
vars.push(` --markdown-list-marker: ${markdown.listMarker || this.opacity(primary, 0.6)};`);
|
||||
@@ -394,7 +391,6 @@ const sidebarBaseRgb = hexToRgb(theme.colors.surface.muted);
|
||||
private generateDefaultMarkdownColors(theme: Theme): string[] {
|
||||
const vars: string[] = [];
|
||||
const primary = theme.colors.primary.base;
|
||||
const chatBackground = theme.colors.chat?.background || theme.colors.surface.background;
|
||||
|
||||
vars.push(` --markdown-heading1: ${primary};`);
|
||||
vars.push(` --markdown-heading2: ${this.opacity(primary, 0.9)};`);
|
||||
@@ -402,8 +398,6 @@ const sidebarBaseRgb = hexToRgb(theme.colors.surface.muted);
|
||||
vars.push(` --markdown-heading4: ${theme.colors.surface.foreground};`);
|
||||
vars.push(` --markdown-link: ${primary};`);
|
||||
vars.push(` --markdown-link-hover: ${theme.colors.primary.hover || this.darken(primary, 10)};`);
|
||||
vars.push(` --markdown-inline-code: ${theme.colors.syntax.base.string};`);
|
||||
vars.push(` --markdown-inline-code-bg: ${chatBackground};`);
|
||||
vars.push(` --markdown-blockquote: ${theme.colors.surface.mutedForeground};`);
|
||||
vars.push(` --markdown-blockquote-border: ${theme.colors.interactive.border};`);
|
||||
vars.push(` --markdown-list-marker: ${this.opacity(primary, 0.6)};`);
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#EDECEE",
|
||||
"link": "#A277FF",
|
||||
"linkHover": "#F694FF",
|
||||
"inlineCode": "#61FFCA",
|
||||
"inlineCodeBackground": "#222128",
|
||||
"blockquote": "#6D6D6D",
|
||||
"blockquoteBorder": "#2D2B38",
|
||||
"listMarker": "#A277FF99"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#2D2640",
|
||||
"link": "#A277FF",
|
||||
"linkHover": "#C17AC8",
|
||||
"inlineCode": "#00732E",
|
||||
"inlineCodeBackground": "#E8E3F2",
|
||||
"blockquote": "#6D6D6D",
|
||||
"blockquoteBorder": "#E0D6F2",
|
||||
"listMarker": "#A277FF99"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#D6DAE0",
|
||||
"link": "#66C6F1",
|
||||
"linkHover": "#3FB7E3",
|
||||
"inlineCode": "#B1C74A",
|
||||
"inlineCodeBackground": "#1C2126",
|
||||
"blockquote": "#E4A75C",
|
||||
"blockquoteBorder": "#2B3440",
|
||||
"listMarker": "#3FB7E399"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#394049",
|
||||
"link": "#2F9BCE",
|
||||
"linkHover": "#4AA8C8",
|
||||
"inlineCode": "#497700",
|
||||
"inlineCodeBackground": "#F0EDE7",
|
||||
"blockquote": "#ED982E",
|
||||
"blockquoteBorder": "#E6DDCF",
|
||||
"listMarker": "#4AA8C899"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#F2F4F8",
|
||||
"link": "#33B1FF",
|
||||
"linkHover": "#78A9FF",
|
||||
"inlineCode": "#42BE65",
|
||||
"inlineCodeBackground": "#232323",
|
||||
"blockquote": "#8D8D8D",
|
||||
"blockquoteBorder": "#393939",
|
||||
"listMarker": "#33B1FF99"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#161616",
|
||||
"link": "#0072C3",
|
||||
"linkHover": "#0043CE",
|
||||
"inlineCode": "#00661E",
|
||||
"inlineCodeBackground": "#F2F2F2",
|
||||
"blockquote": "#525252",
|
||||
"blockquoteBorder": "#DCDCDC",
|
||||
"listMarker": "#0072C399"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#CDD6F4",
|
||||
"link": "#89DCEB",
|
||||
"linkHover": "#B4BEFE",
|
||||
"inlineCode": "#A6E3A1",
|
||||
"inlineCodeBackground": "#2B2B3B",
|
||||
"blockquote": "#F9E2AF",
|
||||
"blockquoteBorder": "#35324A",
|
||||
"listMarker": "#B4BEFE99"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#2e314a",
|
||||
"link": "#04A5E5",
|
||||
"linkHover": "#7287FD",
|
||||
"inlineCode": "#1A7A05",
|
||||
"inlineCodeBackground": "#F2E9E7",
|
||||
"blockquote": "#DF8E1D",
|
||||
"blockquoteBorder": "#E0CFD3",
|
||||
"listMarker": "#7287FD99"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#F8F8F2",
|
||||
"link": "#8BE9FD",
|
||||
"linkHover": "#BD93F9",
|
||||
"inlineCode": "#4aeb72",
|
||||
"inlineCodeBackground": "#21222C",
|
||||
"blockquote": "#FFB86C",
|
||||
"blockquoteBorder": "#2D2F3C",
|
||||
"listMarker": "#BD93F999"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#1F1F2F",
|
||||
"link": "#1D7FC5",
|
||||
"linkHover": "#7C6BF5",
|
||||
"inlineCode": "#007325",
|
||||
"inlineCodeBackground": "#EBEBE5",
|
||||
"blockquote": "#F7A14D",
|
||||
"blockquoteBorder": "#E2E3DA",
|
||||
"listMarker": "#7C6BF599"
|
||||
|
||||
@@ -136,8 +136,6 @@
|
||||
"heading4": "#ebe0d1",
|
||||
"link": "#5a6d7a",
|
||||
"linkHover": "#93a56b",
|
||||
"inlineCode": "#93a56b",
|
||||
"inlineCodeBackground": "#282522",
|
||||
"blockquote": "#a89888",
|
||||
"blockquoteBorder": "#f0e6d830",
|
||||
"listMarker": "#c47a3a99"
|
||||
|
||||
@@ -136,8 +136,6 @@
|
||||
"heading4": "#1a1612",
|
||||
"link": "#3d4f5a",
|
||||
"linkHover": "#4a6030",
|
||||
"inlineCode": "#4A6030",
|
||||
"inlineCodeBackground": "#ECE8DE",
|
||||
"blockquote": "#5a5048",
|
||||
"blockquoteBorder": "#1a161230",
|
||||
"listMarker": "#8c552099"
|
||||
|
||||
@@ -135,8 +135,6 @@
|
||||
"heading4": "#CECDC3",
|
||||
"link": "#4385BE",
|
||||
"linkHover": "#205EA6",
|
||||
"inlineCode": "#A0AF53",
|
||||
"inlineCodeBackground": "#242222",
|
||||
"blockquote": "#878580",
|
||||
"blockquoteBorder": "#343331",
|
||||
"listMarker": "#D0A21599"
|
||||
|
||||
@@ -135,8 +135,6 @@
|
||||
"heading4": "#100F0F",
|
||||
"link": "#205EA6",
|
||||
"linkHover": "#4385BE",
|
||||
"inlineCode": "#0A6961",
|
||||
"inlineCodeBackground": "#F2F0E7",
|
||||
"blockquote": "#6F6E69",
|
||||
"blockquoteBorder": "#DAD8CE",
|
||||
"listMarker": "#AD830199"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#EBDBB2",
|
||||
"link": "#8EC07C",
|
||||
"linkHover": "#83A598",
|
||||
"inlineCode": "#B8BB26",
|
||||
"inlineCodeBackground": "#353535",
|
||||
"blockquote": "#928374",
|
||||
"blockquoteBorder": "#504945",
|
||||
"listMarker": "#83A59899"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#3C3836",
|
||||
"link": "#427B58",
|
||||
"linkHover": "#076678",
|
||||
"inlineCode": "#5F5A00",
|
||||
"inlineCodeBackground": "#EBE4C8",
|
||||
"blockquote": "#928374",
|
||||
"blockquoteBorder": "#D5C4A1",
|
||||
"listMarker": "#07667899"
|
||||
|
||||
@@ -137,8 +137,6 @@
|
||||
"heading4": "#BCBEC4",
|
||||
"link": "#56A8F5",
|
||||
"linkHover": "#6796f5",
|
||||
"inlineCode": "#6AAB73",
|
||||
"inlineCodeBackground": "#2B2C2F",
|
||||
"blockquote": "#7A7E85",
|
||||
"blockquoteBorder": "#393B41",
|
||||
"listMarker": "#B3AE6099"
|
||||
|
||||
@@ -137,8 +137,6 @@
|
||||
"heading4": "#404040",
|
||||
"link": "#006DCC",
|
||||
"linkHover": "#3573F0",
|
||||
"inlineCode": "#067D17",
|
||||
"inlineCodeBackground": "#F2F2F2",
|
||||
"blockquote": "#8C8C8C",
|
||||
"blockquoteBorder": "#C9CCD6",
|
||||
"listMarker": "#9E880D99"
|
||||
|
||||
@@ -135,8 +135,6 @@
|
||||
"heading4": "#DCD7BA",
|
||||
"link": "#7FB4CA",
|
||||
"linkHover": "#7E9CD8",
|
||||
"inlineCode": "#98BB6C",
|
||||
"inlineCodeBackground": "#2C2C35",
|
||||
"blockquote": "#54546D",
|
||||
"blockquoteBorder": "#363646",
|
||||
"listMarker": "#FF9E3B99"
|
||||
|
||||
@@ -135,8 +135,6 @@
|
||||
"heading4": "#545464",
|
||||
"link": "#5D57A3",
|
||||
"linkHover": "#4D699B",
|
||||
"inlineCode": "#496328",
|
||||
"inlineCodeBackground": "#E9E6C9",
|
||||
"blockquote": "#716E61",
|
||||
"blockquoteBorder": "#716E61",
|
||||
"listMarker": "#836F4A99"
|
||||
|
||||
@@ -135,8 +135,6 @@
|
||||
"heading4": "#D9D9D9",
|
||||
"link": "#CCCCCC",
|
||||
"linkHover": "#FFFFFF",
|
||||
"inlineCode": "#B3B3B3",
|
||||
"inlineCodeBackground": "#0D0D0D",
|
||||
"blockquote": "#808080",
|
||||
"blockquoteBorder": "#333333",
|
||||
"listMarker": "#99999999"
|
||||
|
||||
@@ -135,8 +135,6 @@
|
||||
"heading4": "#262626",
|
||||
"link": "#333333",
|
||||
"linkHover": "#000000",
|
||||
"inlineCode": "#4D4D4D",
|
||||
"inlineCodeBackground": "#F2F2F2",
|
||||
"blockquote": "#808080",
|
||||
"blockquoteBorder": "#D9D9D9",
|
||||
"listMarker": "#66666699"
|
||||
|
||||
@@ -113,8 +113,6 @@
|
||||
"heading4": "#D9D9D9",
|
||||
"link": "#CCCCCC",
|
||||
"linkHover": "#a2bee8",
|
||||
"inlineCode": "#a2bee8",
|
||||
"inlineCodeBackground": "#0D0D0D",
|
||||
"blockquote": "#808080",
|
||||
"blockquoteBorder": "#333333",
|
||||
"listMarker": "#99999999"
|
||||
|
||||
@@ -113,8 +113,6 @@
|
||||
"heading4": "#262626",
|
||||
"link": "#333333",
|
||||
"linkHover": "#4a6a9e",
|
||||
"inlineCode": "#4A6A9E",
|
||||
"inlineCodeBackground": "#F2F2F2",
|
||||
"blockquote": "#808080",
|
||||
"blockquoteBorder": "#D9D9D9",
|
||||
"listMarker": "#66666699"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#F8F8F2",
|
||||
"link": "#66D9EF",
|
||||
"linkHover": "#AE81FF",
|
||||
"inlineCode": "#A6E22E",
|
||||
"inlineCodeBackground": "#30312B",
|
||||
"blockquote": "#FD971F",
|
||||
"blockquoteBorder": "#343528",
|
||||
"listMarker": "#AE81FF99"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#292318",
|
||||
"link": "#2D9AD7",
|
||||
"linkHover": "#BF7BFF",
|
||||
"inlineCode": "#0F750B",
|
||||
"inlineCodeBackground": "#F0EBDF",
|
||||
"blockquote": "#F1A948",
|
||||
"blockquoteBorder": "#E9E0CF",
|
||||
"listMarker": "#BF7BFF99"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#D6DEEB",
|
||||
"link": "#7FDBCA",
|
||||
"linkHover": "#82AAFF",
|
||||
"inlineCode": "#C5E478",
|
||||
"inlineCodeBackground": "#0E2334",
|
||||
"blockquote": "#5F7E97",
|
||||
"blockquoteBorder": "#1D3B53",
|
||||
"listMarker": "#82AAFF99"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#403F53",
|
||||
"link": "#2AA298",
|
||||
"linkHover": "#4876D6",
|
||||
"inlineCode": "#00746A",
|
||||
"inlineCodeBackground": "#EEEEEE",
|
||||
"blockquote": "#7A8181",
|
||||
"blockquoteBorder": "#D9D9D9",
|
||||
"listMarker": "#4876D699"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#E5E9F0",
|
||||
"link": "#81A1C1",
|
||||
"linkHover": "#88C0D0",
|
||||
"inlineCode": "#A3BE8C",
|
||||
"inlineCodeBackground": "#2C313D",
|
||||
"blockquote": "#D08770",
|
||||
"blockquoteBorder": "#343A47",
|
||||
"listMarker": "#88C0D099"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#2E3440",
|
||||
"link": "#81A1C1",
|
||||
"linkHover": "#5E81AC",
|
||||
"inlineCode": "#35561A",
|
||||
"inlineCodeBackground": "#DFE2E7",
|
||||
"blockquote": "#D08770",
|
||||
"blockquoteBorder": "#D5DBE7",
|
||||
"listMarker": "#5E81AC99"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#ABB2BF",
|
||||
"link": "#56B6C2",
|
||||
"linkHover": "#61AFEF",
|
||||
"inlineCode": "#a0c288",
|
||||
"inlineCodeBackground": "#2B2F37",
|
||||
"blockquote": "#E5C07B",
|
||||
"blockquoteBorder": "#323848",
|
||||
"listMarker": "#61AFEF99"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#2B303B",
|
||||
"link": "#61AFEF",
|
||||
"linkHover": "#528BFF",
|
||||
"inlineCode": "#186332",
|
||||
"inlineCodeBackground": "#E8E9EB",
|
||||
"blockquote": "#D19A66",
|
||||
"blockquoteBorder": "#DEE2EB",
|
||||
"listMarker": "#528BFF99"
|
||||
|
||||
@@ -137,8 +137,6 @@
|
||||
"heading4": "#c9c5ba",
|
||||
"link": "#5d99a9",
|
||||
"linkHover": "#6ba7b8",
|
||||
"inlineCode": "#76ad4f",
|
||||
"inlineCodeBackground": "#1F1C1B",
|
||||
"blockquote": "#8f8b81",
|
||||
"blockquoteBorder": "#302e2b",
|
||||
"listMarker": "#4d934e99"
|
||||
|
||||
@@ -137,8 +137,6 @@
|
||||
"heading4": "#393a34",
|
||||
"link": "#2e808f",
|
||||
"linkHover": "#296aa3",
|
||||
"inlineCode": "#006A2C",
|
||||
"inlineCodeBackground": "#F0EFED",
|
||||
"blockquote": "#6b6b63",
|
||||
"blockquoteBorder": "#d8d5d0",
|
||||
"listMarker": "#1e754f99"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#93A1A1",
|
||||
"link": "#2AA198",
|
||||
"linkHover": "#6C71C4",
|
||||
"inlineCode": "#859900",
|
||||
"inlineCodeBackground": "#0D2B32",
|
||||
"blockquote": "#B58900",
|
||||
"blockquoteBorder": "#20373F",
|
||||
"listMarker": "#6C71C499"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#586E75",
|
||||
"link": "#2AA198",
|
||||
"linkHover": "#268BD2",
|
||||
"inlineCode": "#576B00",
|
||||
"inlineCodeBackground": "#F0E9D6",
|
||||
"blockquote": "#B58900",
|
||||
"blockquoteBorder": "#E3E0CD",
|
||||
"listMarker": "#268BD299"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#C0CAF5",
|
||||
"link": "#7DCFFF",
|
||||
"linkHover": "#7AA2F7",
|
||||
"inlineCode": "#9ECE6A",
|
||||
"inlineCodeBackground": "#1C1E27",
|
||||
"blockquote": "#E0AF68",
|
||||
"blockquoteBorder": "#25283B",
|
||||
"listMarker": "#7AA2F799"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#273153",
|
||||
"link": "#007197",
|
||||
"linkHover": "#2E7DE9",
|
||||
"inlineCode": "#3E5B1F",
|
||||
"inlineCodeBackground": "#D4D5DA",
|
||||
"blockquote": "#8C6C3E",
|
||||
"blockquoteBorder": "#CDD0DC",
|
||||
"listMarker": "#2E7DE999"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#FFFFFF",
|
||||
"link": "#A0A0A0",
|
||||
"linkHover": "#FFC799",
|
||||
"inlineCode": "#bba2a2",
|
||||
"inlineCodeBackground": "#222222",
|
||||
"blockquote": "#FFFFFF",
|
||||
"blockquoteBorder": "#1C1C1C",
|
||||
"listMarker": "#FFFFFF99"
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
"heading4": "#101010",
|
||||
"link": "#717070",
|
||||
"linkHover": "#c48959",
|
||||
"inlineCode": "#665050",
|
||||
"inlineCodeBackground": "#F2F2F2",
|
||||
"blockquote": "#101010",
|
||||
"blockquoteBorder": "#E8E8E8",
|
||||
"listMarker": "#10101099"
|
||||
|
||||
@@ -113,8 +113,6 @@
|
||||
"heading4": "#dbd7caee",
|
||||
"link": "#4d9375",
|
||||
"linkHover": "#4d9375",
|
||||
"inlineCode": "#80a665",
|
||||
"inlineCodeBackground": "#1F1F1F",
|
||||
"blockquote": "#dedcd550",
|
||||
"blockquoteBorder": "#ffffff15",
|
||||
"listMarker": "#4d937599"
|
||||
|
||||
@@ -113,8 +113,6 @@
|
||||
"heading4": "#2c2c28",
|
||||
"link": "#1e754f",
|
||||
"linkHover": "#1c6b48",
|
||||
"inlineCode": "#3A631E",
|
||||
"inlineCodeBackground": "#F2F2F2",
|
||||
"blockquote": "#2c2c2850",
|
||||
"blockquoteBorder": "#00000015",
|
||||
"listMarker": "#1c6b4899"
|
||||
|
||||
@@ -605,9 +605,6 @@ export const buildVSCodeThemeFromPalette = (palette: VSCodeThemePalette): Theme
|
||||
heading4: foreground,
|
||||
link: accentMuted,
|
||||
linkHover: read('textLink.activeForeground', accentHover),
|
||||
inlineCode: read('textPreformat.foreground', syntaxString),
|
||||
inlineCodeBackground: subtle,
|
||||
inlineCodeBorder: read('textPreformat.border', read('chat.requestCodeBorder', effectiveBorder)),
|
||||
blockquote: foreground,
|
||||
blockquoteBackground: read('textBlockQuote.background', 'transparent'),
|
||||
blockquoteBorder: read('textBlockQuote.border', effectiveBorder),
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
export const SEMANTIC_TYPOGRAPHY = {
|
||||
markdown: '0.9375rem',
|
||||
code: '0.8125rem',
|
||||
uiHeader: '0.9375rem',
|
||||
uiLabel: '0.8750rem',
|
||||
meta: '0.875rem',
|
||||
micro: '0.875rem',
|
||||
markdown: '0.875rem',
|
||||
code: '0.75rem',
|
||||
uiHeader: '0.875rem',
|
||||
uiLabel: '0.8125rem',
|
||||
meta: '0.8125rem',
|
||||
micro: '0.8125rem',
|
||||
/** Settings page / detail-pane title — larger than section headers */
|
||||
settingsPageTitle: '1.125rem',
|
||||
settingsPageTitle: '1.0625rem',
|
||||
} as const;
|
||||
|
||||
export const VSCODE_TYPOGRAPHY = {
|
||||
// Keep VS Code webview typography slightly tighter; VS Code UI chrome already provides density.
|
||||
markdown: '0.9063rem',
|
||||
code: '0.8750rem',
|
||||
uiHeader: '0.9063rem',
|
||||
uiLabel: '0.8438rem',
|
||||
meta: '0.8438rem',
|
||||
micro: '0.7813rem',
|
||||
settingsPageTitle: '1.0625rem',
|
||||
markdown: '0.8438rem',
|
||||
code: '0.8125rem',
|
||||
uiHeader: '0.8438rem',
|
||||
uiLabel: '0.7813rem',
|
||||
meta: '0.7813rem',
|
||||
micro: '0.75rem',
|
||||
settingsPageTitle: '1rem',
|
||||
} as const;
|
||||
|
||||
export type SemanticTypographyKey = keyof typeof SEMANTIC_TYPOGRAPHY;
|
||||
|
||||
@@ -24,13 +24,16 @@
|
||||
--oc-glass-saturation: 1.24;
|
||||
|
||||
/* Semantic typography defaults (must match SEMANTIC_TYPOGRAPHY) */
|
||||
--text-markdown: 0.9375rem;
|
||||
--text-code: 0.8125rem;
|
||||
--text-ui-header: 0.9375rem;
|
||||
--text-ui-label: 0.8750rem;
|
||||
--text-meta: 0.875rem;
|
||||
--text-micro: 0.875rem;
|
||||
--text-settings-page-title: 1.125rem;
|
||||
--text-markdown: 0.875rem;
|
||||
--text-code: 0.75rem;
|
||||
--text-ui-header: 0.875rem;
|
||||
--text-ui-label: 0.8125rem;
|
||||
--text-meta: 0.8125rem;
|
||||
--text-micro: 0.8125rem;
|
||||
--text-settings-page-title: 1.0625rem;
|
||||
|
||||
/* Text selection colour shared by native ::selection and the comment overlay */
|
||||
--oc-text-selection: color-mix(in srgb, var(--primary) 30%, transparent);
|
||||
|
||||
/* Default Light Theme */
|
||||
--background: oklch(0.97 0.02 85); /* Warm sand background */
|
||||
@@ -154,25 +157,24 @@
|
||||
font-family: var(--font-mono, ui-monospace, SFMono-Regular, 'Liberation Mono', Menlo, monospace) !important;
|
||||
}
|
||||
|
||||
/* Restore default list styling inside markdown content - override Tailwind preflight */
|
||||
/* Restore list styling inside markdown content - override Tailwind preflight.
|
||||
Native markers with a compact gutter; nesting cycles the marker shape so
|
||||
depth stays readable without extra indentation. */
|
||||
.markdown-content ul,
|
||||
.markdown-content ol {
|
||||
padding-left: 2em !important;
|
||||
padding-left: 1.25rem !important;
|
||||
}
|
||||
|
||||
.markdown-content ul {
|
||||
list-style-type: none !important;
|
||||
list-style-type: disc !important;
|
||||
}
|
||||
|
||||
.markdown-content ul > li {
|
||||
position: relative;
|
||||
.markdown-content ul ul {
|
||||
list-style-type: circle !important;
|
||||
}
|
||||
|
||||
.markdown-content ul > li::before {
|
||||
content: "–";
|
||||
position: absolute;
|
||||
left: -1.25em;
|
||||
color: inherit;
|
||||
.markdown-content ul ul ul {
|
||||
list-style-type: square !important;
|
||||
}
|
||||
|
||||
.markdown-content ol {
|
||||
@@ -180,10 +182,40 @@
|
||||
list-style-position: outside !important;
|
||||
}
|
||||
|
||||
.markdown-content ol ol {
|
||||
list-style-type: lower-alpha !important;
|
||||
}
|
||||
|
||||
.markdown-content ol ol ol {
|
||||
list-style-type: lower-roman !important;
|
||||
}
|
||||
|
||||
.markdown-content li {
|
||||
display: list-item !important;
|
||||
}
|
||||
|
||||
.markdown-content li::marker {
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.markdown-content ol > li::marker {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.markdown-content li + li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
/* GitHub-style task lists: the checkbox replaces the list marker. */
|
||||
.markdown-content li:has(> input[type="checkbox"]:first-child) {
|
||||
list-style-type: none !important;
|
||||
}
|
||||
|
||||
.markdown-content li > input[type="checkbox"]:first-child {
|
||||
margin: 0 0.35em 0.15em -1.25rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* Remove focus rings globally (except inputs/textareas/dropdowns/selects/explicit accent rings) */
|
||||
*:focus:not(input):not(textarea):not([data-slot="dropdown-menu-content"]):not([data-slot="dropdown-menu-sub-content"]):not([data-slot="select-content"]):not(.focus-ring-accent):not([data-focus-ring="accent"]) {
|
||||
outline: none !important;
|
||||
@@ -425,13 +457,11 @@
|
||||
--markdown-link: var(--markdown-link);
|
||||
--markdown-link-hover: var(--markdown-link-hover);
|
||||
--markdown-list-marker: var(--markdown-list-marker);
|
||||
--markdown-inline-code: var(--markdown-inline-code);
|
||||
--markdown-inline-code-bg: var(--markdown-inline-code-bg);
|
||||
--markdown-blockquote: var(--markdown-blockquote);
|
||||
--markdown-blockquote-border: var(--markdown-blockquote-border);
|
||||
|
||||
/* Markdown spacing defaults */
|
||||
--markdown-paragraph-spacing: 0.75rem;
|
||||
--markdown-paragraph-spacing: 0.65rem;
|
||||
--markdown-heading-primary-top: 0.75rem;
|
||||
--markdown-heading-primary-bottom: 0.35rem;
|
||||
--markdown-heading-secondary-top: 0.6rem;
|
||||
|
||||
Reference in New Issue
Block a user