493 lines
11 KiB
CSS
493 lines
11 KiB
CSS
/* 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;
|
||
}
|