- built-boot smoke asserts [data-variant=web][data-tool=web_search/fetch] (the keyed WebRow) instead of [data-web] (which WebBlock draws even on the GenericToolCard fallback, so a silent keyed-registration failure passed). - WebBlock renders an explicit empty-state note when a search returns no answer and no sources, instead of a blank <ol>; the chat row does not surface the raw result content, so the backend's 'No results found.' was otherwise invisible. - README (ui-conversation, ui-primitives) and the frontend Agent Note record the unknown-web-kind null arm, the details-panel flattened body, and the empty-search copy; pairings re-recorded.
134 lines
2.6 KiB
CSS
134 lines
2.6 KiB
CSS
/* Geometry mirrors CodeBlock/TerminalBlock (12px radius, code-block surface,
|
|
16px vertical margin) so a web card, a terminal card, and a fenced code block
|
|
read as one family. A source list is prose, not aligned output, so it wraps
|
|
normally rather than scrolling horizontally like a terminal card's output. */
|
|
|
|
.block {
|
|
--dsl-web-radius: 12px;
|
|
|
|
margin: 16px 0;
|
|
padding: 12px 14px;
|
|
color: var(--dsw-alias-label-primary);
|
|
background: var(--dsw-alias-markdown-code-block);
|
|
border-radius: var(--dsl-web-radius);
|
|
}
|
|
|
|
/* The provider answer reads as body prose above the citation list; its own
|
|
MarkdownText margins are trimmed so the list sits tight under it. */
|
|
.answer {
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.answer > :global(div) > :first-child {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.answer > :global(div) > :last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
/* The citation list: ordered so each source reads as a numbered reference. */
|
|
.sources {
|
|
margin: 0;
|
|
padding-left: 20px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.source {
|
|
min-width: 0;
|
|
}
|
|
|
|
.sourceLink {
|
|
color: var(--dsw-alias-state-business-primary);
|
|
font-size: 14px;
|
|
line-height: 20px;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.sourceLink:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.snippet {
|
|
margin-top: 2px;
|
|
color: var(--dsw-alias-label-secondary);
|
|
font-size: 13px;
|
|
line-height: 19px;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.published {
|
|
margin-top: 2px;
|
|
color: var(--dsw-alias-label-tertiary);
|
|
font: var(--dsw-font-xs-13);
|
|
}
|
|
|
|
.expandItem {
|
|
list-style: none;
|
|
}
|
|
|
|
.expand {
|
|
display: block;
|
|
width: 100%;
|
|
padding: 0;
|
|
border: none;
|
|
background-color: transparent;
|
|
color: var(--dsw-alias-label-tertiary);
|
|
cursor: pointer;
|
|
font: inherit;
|
|
text-align: left;
|
|
}
|
|
|
|
.expand:hover {
|
|
color: var(--dsw-alias-label-secondary);
|
|
}
|
|
|
|
.truncated {
|
|
margin-top: 8px;
|
|
color: var(--dsw-alias-label-tertiary);
|
|
font: var(--dsw-font-xs-13);
|
|
}
|
|
|
|
.empty {
|
|
color: var(--dsw-alias-label-secondary);
|
|
font: var(--dsw-font-xs-13);
|
|
}
|
|
|
|
/* The fetch card is a compact summary: the URL over a status/truncation row. */
|
|
.fetch {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
}
|
|
|
|
.fetchUrl {
|
|
color: var(--dsw-alias-state-business-primary);
|
|
font-family: var(--ds-font-family-code);
|
|
font-size: 13px;
|
|
line-height: 19px;
|
|
word-break: break-all;
|
|
}
|
|
|
|
.fetchUrl:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.fetchMeta {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: 12px;
|
|
}
|
|
|
|
.status {
|
|
color: var(--dsw-alias-label-secondary);
|
|
font: var(--dsw-font-xs-13);
|
|
}
|
|
|
|
/* The fetch card's truncation note sits inline beside the status, so it drops
|
|
the search card's top margin. */
|
|
.fetch .truncated {
|
|
margin-top: 0;
|
|
}
|