evOo-local/packages/chat-ui/src/markdown.web.css
cynarAI 3d180dc2dd
fix(web): keep chat text readable in the light theme (#104)
Chat markdown hard-coded a near-white text color, so on light surfaces
(ask cards, delegated task briefs, peer and file previews) the text was
white on white. The desktop conversation panel and the bubble and glass
surfaces were hard-coded dark while the text on them follows the theme,
so in the light theme the user's own messages rendered as empty pills.

- Chat markdown uses the foreground token; heading, code and quote colors
  come from the shared @rakazo/chat-ui markdown styles instead of
  white/emerald overrides. Quotes read in the body color, as on mobile,
  so they stay legible in the dimmed transcript.
- User bubbles use the chat-user tokens; bubble and glass card surfaces use
  card and border tokens.
- The conversation panel uses the background token on desktop too, as it
  already did on mobile. Bot reply footers, summary cards, quick prompt
  chips, the awareness strip and the chart expand button drop hard-coded
  white/zinc/emerald classes that would vanish on that panel.
- New web E2E measures the contrast of the user's messages, a markdown bot
  reply, a delegated brief and an ask card in a group transcript in both
  themes and captures screenshots.


Claude-Session: https://claude.ai/code/session_01WnqLpAn8253EY1eCLKVJb2

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-03 14:43:05 +02:00

226 lines
4.1 KiB
CSS

.rk-chat-markdown {
min-width: 0;
overflow-wrap: anywhere;
}
.rk-chat-markdown > :first-child,
.rk-chat-markdown > :first-child > :first-child {
margin-top: 0;
}
.rk-chat-markdown > :last-child,
.rk-chat-markdown > :last-child > :last-child {
margin-bottom: 0;
}
.rk-chat-markdown p,
.rk-chat-markdown blockquote,
.rk-chat-markdown pre,
.rk-chat-markdown table,
.rk-chat-markdown ul,
.rk-chat-markdown ol {
margin: 0.65em 0;
}
.rk-chat-markdown h1,
.rk-chat-markdown h2,
.rk-chat-markdown h3,
.rk-chat-markdown h4,
.rk-chat-markdown h5,
.rk-chat-markdown h6 {
margin: 0.9em 0 0.35em;
color: var(--foreground);
font-weight: 650;
line-height: 1.25;
}
.rk-chat-markdown h1 {
font-size: 1.35em;
}
.rk-chat-markdown h2 {
font-size: 1.2em;
}
.rk-chat-markdown h3,
.rk-chat-markdown h4,
.rk-chat-markdown h5,
.rk-chat-markdown h6 {
font-size: 1.05em;
}
.rk-chat-markdown ul,
.rk-chat-markdown ol {
padding-left: 1.45em;
}
.rk-chat-markdown ul {
list-style: disc;
}
.rk-chat-markdown ol {
list-style: decimal;
}
.rk-chat-markdown li + li {
margin-top: 0.25em;
}
.rk-chat-markdown li > p {
margin: 0.2em 0;
}
.rk-chat-markdown .contains-task-list,
.rk-chat-markdown .task-list-item {
list-style: none;
}
.rk-chat-markdown .contains-task-list {
padding-left: 0;
}
.rk-chat-markdown a {
color: var(--link);
text-decoration: underline;
text-decoration-color: color-mix(in srgb, var(--link) 55%, transparent);
text-underline-offset: 0.15em;
}
.rk-chat-markdown code {
border: 1px solid var(--border);
border-radius: 0.35em;
background: var(--muted);
color: var(--foreground);
padding: 0.08em 0.32em;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
font-size: 0.88em;
direction: ltr;
unicode-bidi: isolate;
}
.rk-chat-markdown pre {
max-width: 100%;
overflow-x: auto;
border: 1px solid var(--border);
border-radius: 0.75em;
background: var(--card);
padding: 0.8em 0.9em;
direction: ltr;
unicode-bidi: isolate;
}
.rk-chat-markdown pre code {
border: 0;
background: transparent;
padding: 0;
font-size: 0.84em;
white-space: pre;
}
.rk-chat-markdown-pre-wrap {
position: relative;
margin: 0.65em 0;
}
.rk-chat-markdown .rk-chat-markdown-pre-wrap pre {
margin: 0;
}
.rk-chat-markdown-copy {
position: absolute;
top: 0.5em;
right: 0.5em;
display: flex;
align-items: center;
justify-content: center;
width: 1.75em;
height: 1.75em;
border: 1px solid var(--border);
border-radius: 0.4em;
background: var(--muted);
color: var(--muted-foreground);
opacity: 0;
transition: opacity 0.12s;
cursor: pointer;
}
.rk-chat-markdown-pre-wrap:hover .rk-chat-markdown-copy,
.rk-chat-markdown-copy:focus-visible {
opacity: 1;
}
.rk-chat-markdown-copy:hover {
background: var(--accent);
color: var(--foreground);
}
.rk-chat-markdown blockquote {
border-left: 3px solid var(--border);
padding-left: 0.85em;
}
.rk-chat-markdown table {
display: block;
max-width: 100%;
overflow-x: auto;
border-collapse: collapse;
font-size: 0.92em;
}
.rk-chat-markdown th,
.rk-chat-markdown td {
border: 1px solid var(--border);
padding: 0.4em 0.6em;
text-align: left;
/* Not the container's `anywhere`: its break opportunities count toward
min-content, so columns collapse to 1ch and the table never overflows. */
overflow-wrap: break-word;
}
.rk-chat-markdown th {
background: var(--muted);
color: var(--foreground);
font-weight: 600;
}
.rk-chat-markdown hr {
margin: 0.9em 0;
border: 0;
border-top: 1px solid var(--border);
}
.rk-chat-markdown img {
display: block;
max-width: 100%;
height: auto;
margin: 0.65em 0;
border-radius: 0.65em;
}
.rk-chat-markdown input[type="checkbox"] {
margin-right: 0.4em;
accent-color: var(--primary);
}
.rk-chat-markdown-streaming {
position: relative;
padding-right: 0.8em;
}
.rk-chat-markdown-cursor {
position: absolute;
right: 0;
bottom: 0.24em;
width: 0.16em;
height: 1em;
border-radius: 999px;
background: var(--muted-foreground);
animation: rkMarkdownCursor 1s steps(2, jump-none) infinite;
}
@keyframes rkMarkdownCursor {
50% {
opacity: 0;
}
}