Files
deepseek-harness/packages/client/ui-primitives/src/markdown/MarkdownText.module.css
T

493 lines
11 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Visual baseline: deepsuite `@deepseek/md` markdown.css, adapted to CSS
Modules. Cite pills and header anchors are absent (no matching DOM).
Token names match that sheet. */
.markdown {
min-width: 0;
overflow-wrap: anywhere;
font: var(--dsw-font-markdown-base);
color: var(--dsw-alias-label-primary);
}
.markdown strong {
font-weight: 600;
}
.markdown h1 {
font: var(--dsw-font-markdown-h1);
margin: 32px 0 16px;
}
.markdown h2 {
font: var(--dsw-font-markdown-h2);
margin: 32px 0 16px;
}
.markdown h3 {
font: var(--dsw-font-markdown-h3);
margin: 32px 0 16px;
}
.markdown h4 {
font: var(--dsw-font-markdown-h4);
margin: 16px 0;
}
.markdown :where(h5, h6) {
font: var(--dsw-font-markdown-base-strong);
margin: 16px 0;
}
.markdown :where(h1, h2, h3, h4, h5, h6) strong {
font-weight: inherit;
}
.markdown p {
margin: 16px 0;
}
/* Tighten h4–h6 against a following list (design: 8px gap). */
.markdown :where(h4, h5, h6) + :where(ul, ol) {
margin-top: 8px;
}
.markdown :where(h4, h5, h6):has(+ :where(ul, ol)) {
margin-bottom: 8px;
}
.markdown a,
.markdown .fileLink {
/* deepsuite markdown.css uses brand-text (blue in newDesign); this sheet
keeps design-platform brand-text as near-black, so links use the
dedicated link alias instead. */
color: var(--dsw-alias-link);
font-weight: 500;
transition: box-shadow var(--ds-transition-duration) var(--ds-ease-in-out);
position: relative;
text-decoration: none;
/* Transparent hit-area padding; literal zero-alpha only (no painted color). */
border-left: 3px solid rgb(255 255 255 / 0);
border-right: 3px solid rgb(255 255 255 / 0);
border-top: 2px solid rgb(255 255 255 / 0);
border-bottom: 2px solid rgb(255 255 255 / 0);
margin-left: -3px;
margin-right: -3px;
}
.markdown a:focus {
outline: none;
text-decoration: underline dotted var(--dsw-alias-link);
text-underline-offset: 3px;
}
@media (hover: hover) {
.markdown a:hover {
outline: none;
text-decoration: underline dotted var(--dsw-alias-link);
text-underline-offset: 3px;
}
}
.markdown a:focus-visible,
.fileMention:focus-visible {
box-shadow: 0 0 0 2px var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));
}
/* Leading link-category glyph inside anchors, file mentions, and
URL-promoted inline code: outline glyphs ride the link's currentColor.
1.1em keeps the glyph proportional to the surrounding text's size (it
shrinks with the code chip's 0.875em); the small negative offset seats
its optical center on the cap height. */
.linkIcon {
flex: none;
width: 1.1em;
height: 1.1em;
vertical-align: -0.25em;
margin-right: 5px;
}
.markdown :where(ul, ol) {
margin: 16px 0;
padding-left: 18px;
}
.markdown li:not(:first-child) {
margin-top: 6px;
}
.markdown li > :where(ul, ol) {
margin-top: 4px;
}
.markdown li::marker {
line-height: 24px;
color: var(--dsw-alias-label-secondary);
}
/* Nested ol under ul/ol: markers inside (models sometimes emit this shape). */
.markdown :where(ul, ol) ol {
list-style-position: inside;
padding-left: 0;
}
.markdown :where(ul, ol) ol li p {
display: inline;
}
.markdown li > p {
margin: 8px 0;
}
.markdown li > *:first-child {
margin-top: 0;
}
/* Keep list-nested code-block vertical margins (design: +4px vs other last children). */
.markdown li > *:last-child:not(:global(.md-code-block)) {
margin-bottom: 0;
}
.markdown hr {
display: block;
border: none;
height: 0.5px;
margin: 32px 0;
background: var(--dsw-alias-border-l2);
}
.markdown blockquote {
border-left: 2px solid var(--dsw-alias-label-caption);
margin: 16px 0 0;
padding-left: 14px;
}
.markdown pre {
margin: 16px 0;
font-family: var(--ds-font-family-code);
overflow: auto;
}
.markdown :not(pre) > code {
display: inline-flex;
align-items: center;
box-sizing: border-box;
font: var(--dsw-font-markdown-code);
font-family: var(--ds-font-family-code);
font-size: 0.875em !important;
background-color: var(--dsw-alias-markdown-inline-code);
border: 0.5px solid var(--dsw-alias-border-l1);
border-radius: var(--dsw-radius-sm);
padding: 0 5px;
}
.markdown :where(h1, h2, h3, h4, h5, h6) code {
font: inherit;
font-family: var(--ds-font-family-code);
}
.markdown :global(.katex-display) {
max-width: 100%;
overflow-x: auto;
overflow-y: hidden;
}
.markdown input[type='checkbox'] {
margin: 0 8px 0 0;
accent-color: var(--dsw-alias-label-secondary);
}
.tableScroll {
max-width: 100%;
overflow-x: auto;
overscroll-behavior-x: contain;
}
/* Hover-capable inputs reveal a wide table's bar on hover or keyboard focus.
Other inputs keep native horizontal scrolling. Chromium never repaints state-conditioned
scrollbar STYLES (neither hover-conditioned `::-webkit-scrollbar*` rules
nor a :hover `scrollbar-color` change reaches the painted bar), so the
toggle is `overflow-x` itself — a layout change repaints reliably. The
resting padding matches the themed bar's height on the WebKit scrollbar
path. There, `scroll` reserves that height even when the table fits.
Other engines and overlay scrollbars may reserve a different height.
Wheel and trackpad scrolling need the pointer over the table, which is
already the hover that re-enables scrolling. */
.tableScroll:global(.md-table-wide):focus-visible {
overflow-x: scroll;
padding-bottom: 0;
}
@media (hover: hover) {
.tableScroll:global(.md-table-wide) {
overflow-x: hidden;
padding-bottom: var(--dsh-scrollbar-width, 5px);
}
.tableScroll:global(.md-table-wide):hover {
overflow-x: scroll;
padding-bottom: 0;
}
}
/* Chromium keyboard-focuses scrollable containers by default; the ring uses
the sheet's link focus color. */
.tableScroll:focus-visible {
outline: none;
box-shadow: 0 0 0 2px var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));
}
/* Many-column tables (the renderer's `md-table-wide` hook) keep their
natural width and scroll inside the wrapper; a hosting layout may widen
the wrapper through the hook (deepsuite chat TableWrapper parity). */
.tableScroll table {
border-collapse: collapse;
width: max-content;
max-width: max-content;
}
/* Tables under four columns, and any table inside a blockquote, fill the
column instead: cells wrap down to their minimum readable width, and the
wrapper's scroll only remains for the below-floor case (deepsuite chat
parity: `.wrapper:not(:has(th:nth-child(4), td:nth-child(4)))`). */
.tableFill table {
width: 100%;
max-width: none;
}
.tableScroll th {
text-align: start;
padding: 10px 16px;
border-bottom: 0.5px solid var(--dsw-alias-border-l3);
border-top: none;
font: var(--dsw-font-markdown-table-head);
max-width: 320px;
max-width: min(30vw, 320px);
min-width: 100px;
}
.tableScroll td {
padding: 10px 16px;
border-bottom: 0.5px solid var(--dsw-alias-border-l2);
font: var(--dsw-font-markdown-table);
max-width: 320px;
max-width: min(30vw, 320px);
min-width: 100px;
}
.tableScroll th:first-child,
.tableScroll td:first-child {
padding-left: 0;
}
.tableScroll td:last-child {
padding-right: 0;
}
.tableScroll table code {
font-size: 11px;
}
.markdown > *:first-child,
.markdown p:first-child {
margin-top: 0 !important;
}
.markdown > *:last-child,
.markdown p:last-child {
margin-bottom: 0 !important;
}
.imageAlt {
color: var(--dsw-alias-label-tertiary);
font-style: italic;
}
.image {
display: block;
width: auto;
max-width: 100%;
height: auto;
margin: 0;
border-radius: var(--dsw-radius-md);
background: var(--dsw-alias-bg-base);
object-fit: contain;
}
/* Inline file mention: the same link language this sheet gives anchors (and
thereby URL-promoted inline code) — link-blue at rest, dotted underline only
on hover/focus. An underline at rest reads badly inside the code chip, where
it collides with monospace descenders and the pill background. */
.fileMention {
margin: 0;
padding: 0;
border: none;
background: none;
font: inherit;
font-weight: 500;
color: var(--dsw-alias-link);
text-decoration: none;
cursor: pointer;
}
.fileLink {
max-width: 100%;
text-align: inherit;
}
.fileMention:focus {
outline: none;
text-decoration: underline dotted var(--dsw-alias-link);
text-underline-offset: 3px;
}
@media (hover: hover) {
.fileMention:hover {
outline: none;
text-decoration: underline dotted var(--dsw-alias-link);
text-underline-offset: 3px;
}
}
.compact {
max-width: 100%;
font-size: var(--dsh-content-font-size-secondary, 13px);
line-height: calc(20px + var(--dsh-content-font-delta-secondary, 0px));
color: var(--dsw-alias-label-tertiary);
}
.compact :is(h1, h2, h3, h4, h5, h6) {
margin: 8px 0 4px;
font: inherit;
font-weight: 600;
color: inherit;
}
.compact :is(p, ul, ol, blockquote) {
margin: 4px 0;
}
.compact li:not(:first-child) {
margin-top: 2px;
}
.compact li > p {
margin: 4px 0;
}
.compact li::marker {
line-height: inherit;
color: inherit;
}
.compact blockquote {
padding-left: 8px;
}
.compact hr {
margin: 8px 0;
}
.compact a,
.compact .fileMention {
font-weight: inherit;
color: inherit;
text-decoration: underline dotted;
}
.compact a:focus,
.compact .fileMention:focus {
text-decoration-color: currentColor;
}
@media (hover: hover) {
.compact a:hover,
.compact .fileMention:hover {
text-decoration-color: currentColor;
}
}
.compact :not(pre) > code {
display: inline;
font: inherit;
font-family: var(--ds-font-family-code);
font-size: 1em !important;
border-radius: var(--dsw-radius-xs);
padding: 0 3px;
box-decoration-break: clone;
}
.markdown.compact :global(.md-code-block) {
margin: 4px 0;
color: inherit;
}
.compact :global(.md-code-block) > :has(> [data-code-block-banner]) {
position: static;
z-index: auto;
}
/* Shiki writes token colors inline; compact code uses the surrounding text color. */
.compact pre,
.compact pre :is(code, span) {
color: inherit !important;
}
.markdown.compact .tableScroll {
width: 100%;
max-width: 100%;
margin: 4px 0;
padding-left: 0;
}
.markdown.compact .tableScroll > table {
z-index: auto;
}
.compact :is(th, td) {
padding: 4px 8px;
font: inherit;
}
.compact th {
font-weight: 600;
}
.compact :global(.katex) {
font-size: 1em;
}
/* Keep KaTeX's inline baseline and scroll the containing block only when needed. */
.compact :is(p, h1, h2, h3, h4, h5, h6, ul, ol):has(:global(.katex)) {
overflow-x: auto;
overflow-y: hidden;
/* KaTeX descenders can paint one pixel below a fractional line-box edge. */
padding-bottom: 1px;
}
.compact :global(.katex-display) {
margin: 4px 0;
}
.imageButton {
display: inline-block;
max-width: 100%;
padding: 0;
border: 0;
border-radius: var(--dsw-radius-sm);
background: transparent;
vertical-align: middle;
cursor: zoom-in;
}
.imageButton .image { max-width: min(100%, 640px); max-height: 360px; }
.imageButton:focus-visible { outline: var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary)); outline-offset: 3px; }
.previewName {
display: block;
margin-top: 8px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--dsw-alias-label-secondary);
font-size: 12px;
line-height: 18px;
}