From 86d979046bfe2e319f8333d14aa209343ed09f4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Tue, 4 Aug 2026 03:00:16 +0000 Subject: [PATCH] restore list markers in rendered markdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tailwind's preflight resets `list-style: none` on every ul/ol, and none of the three prose scopes put it back. the indent was there, so a bulleted list just looked tight — but an ORDERED list rendered with no numbers at all, which reads as the model having emitted broken markdown. pasting the same text into an editor showed it numbered correctly, which is the tell. the `li::marker` rules were colouring a marker that was never drawn. fixed in .chat-md, .file-viewer-md and .skill-md, plus the inline .markdown-preview block in MarkdownEditor, which had the same hole. nested levels follow the usual convention (disc/circle/square, decimal/alpha/roman) and task-list items drop the bullet, since the checkbox is already the marker. Co-Authored-By: Claude Opus 5 --- src/apps/officer-web/styles/prose.css | 105 +++++++++++++++++-- src/workspaces/components/MarkdownEditor.tsx | 8 +- 2 files changed, 103 insertions(+), 10 deletions(-) diff --git a/src/apps/officer-web/styles/prose.css b/src/apps/officer-web/styles/prose.css index a45c32dc..ff4b86ba 100644 --- a/src/apps/officer-web/styles/prose.css +++ b/src/apps/officer-web/styles/prose.css @@ -36,7 +36,9 @@ margin: 1em 0 0.3em; } -.chat-md h4, .chat-md h5, .chat-md h6 { +.chat-md h4, +.chat-md h5, +.chat-md h6 { font-size: 1em; font-weight: 600; margin: 0.8em 0 0.25em; @@ -69,9 +71,46 @@ color: hsl(var(--muted-foreground)); } -.chat-md ul, .chat-md ol { +/* Tailwind's preflight resets `list-style: none` on every ul/ol, so a list rendered here had the + indent but no bullets and — more confusingly — no NUMBERS: an ordered list read as an unordered + pile of lines, and copying the same text elsewhere showed it numbered correctly, which makes it + look like the model emitted bad markdown rather than the stylesheet eating the markers. The + `li::marker` rule below was colouring a marker that was never drawn. */ +.chat-md ul, +.chat-md ol { margin: 0.5em 0; padding-left: 1.5em; + list-style-position: outside; +} + +.chat-md ul { + list-style-type: disc; +} + +.chat-md ol { + list-style-type: decimal; +} + +/* Nested levels, following the usual typographic convention so depth stays readable. */ +.chat-md ul ul { + list-style-type: circle; +} + +.chat-md ul ul ul { + list-style-type: square; +} + +.chat-md ol ol { + list-style-type: lower-alpha; +} + +.chat-md ol ol ol { + list-style-type: lower-roman; +} + +/* A task list carries its own checkbox; a bullet next to it is noise. */ +.chat-md li:has(> input[type='checkbox']) { + list-style-type: none; } .chat-md li { @@ -147,7 +186,7 @@ margin: 0.75em 0; } -.chat-md input[type="checkbox"] { +.chat-md input[type='checkbox'] { accent-color: var(--duck-teal); margin-right: 0.4em; } @@ -185,7 +224,9 @@ margin: 1.2em 0 0.4em; } -.file-viewer-md h4, .file-viewer-md h5, .file-viewer-md h6 { +.file-viewer-md h4, +.file-viewer-md h5, +.file-viewer-md h6 { color: hsl(var(--foreground)); font-size: 1.05em; font-weight: 600; @@ -219,9 +260,31 @@ color: hsl(var(--muted-foreground)); } -.file-viewer-md ul, .file-viewer-md ol { +.file-viewer-md ul, +.file-viewer-md ol { margin: 0.75em 0; padding-left: 1.75em; + list-style-position: outside; +} + +.file-viewer-md ul { + list-style-type: disc; +} + +.file-viewer-md ol { + list-style-type: decimal; +} + +.file-viewer-md ul ul { + list-style-type: circle; +} + +.file-viewer-md ol ol { + list-style-type: lower-alpha; +} + +.file-viewer-md li:has(> input[type='checkbox']) { + list-style-type: none; } .file-viewer-md li { @@ -270,7 +333,7 @@ margin: 1em 0; } -.file-viewer-md input[type="checkbox"] { +.file-viewer-md input[type='checkbox'] { accent-color: var(--duck-teal); margin-right: 0.5em; } @@ -308,7 +371,9 @@ margin: 1.2em 0 0.4em; } -.skill-md h4, .skill-md h5, .skill-md h6 { +.skill-md h4, +.skill-md h5, +.skill-md h6 { color: hsl(var(--foreground)); font-size: 1.05em; font-weight: 600; @@ -342,9 +407,31 @@ color: hsl(var(--muted-foreground)); } -.skill-md ul, .skill-md ol { +.skill-md ul, +.skill-md ol { margin: 0.75em 0; padding-left: 1.75em; + list-style-position: outside; +} + +.skill-md ul { + list-style-type: disc; +} + +.skill-md ol { + list-style-type: decimal; +} + +.skill-md ul ul { + list-style-type: circle; +} + +.skill-md ol ol { + list-style-type: lower-alpha; +} + +.skill-md li:has(> input[type='checkbox']) { + list-style-type: none; } .skill-md li { @@ -420,7 +507,7 @@ margin: 1em 0; } -.skill-md input[type="checkbox"] { +.skill-md input[type='checkbox'] { accent-color: var(--duck-teal); margin-right: 0.5em; } diff --git a/src/workspaces/components/MarkdownEditor.tsx b/src/workspaces/components/MarkdownEditor.tsx index 715fbbd3..be3c14dd 100644 --- a/src/workspaces/components/MarkdownEditor.tsx +++ b/src/workspaces/components/MarkdownEditor.tsx @@ -83,7 +83,13 @@ export function MarkdownEditor({ .markdown-preview h2 { font-size: 1.5rem; font-weight: bold; margin: 1.25rem 0 0.75rem 0; } .markdown-preview h3 { font-size: 1.25rem; font-weight: bold; margin: 1rem 0 0.5rem 0; } .markdown-preview p { margin: 0.75rem 0; line-height: 1.6; } - .markdown-preview ul, .markdown-preview ol { margin: 1rem 0; padding-left: 2rem; } + /* list-style is restored explicitly — tailwind preflight strips it, which leaves an + ordered list indented but unnumbered. */ + .markdown-preview ul, .markdown-preview ol { margin: 1rem 0; padding-left: 2rem; list-style-position: outside; } + .markdown-preview ul { list-style-type: disc; } + .markdown-preview ol { list-style-type: decimal; } + .markdown-preview ul ul { list-style-type: circle; } + .markdown-preview ol ol { list-style-type: lower-alpha; } .markdown-preview li { margin: 0.5rem 0; line-height: 1.6; } .markdown-preview code { background-color: rgb(229, 229, 229); color: rgb(31, 41, 55); padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-size: 0.875rem; } .markdown-preview pre { background-color: rgb(17, 24, 39); color: rgb(243, 244, 246); padding: 1rem; border-radius: 0.5rem; overflow-x: auto; margin: 1rem 0; }