feat(app): refine session UI styling (#33860)

Co-authored-by: Brendan Allan <14191578+Brendonovich@users.noreply.github.com>
This commit is contained in:
usrnk1 2026-06-26 10:04:56 +02:00 committed by GitHub
commit 78a5a030ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 711 additions and 129 deletions

View file

@ -43,7 +43,7 @@
align-items: center;
justify-content: center;
flex-shrink: 0;
color: var(--text-weak);
color: var(--v2-text-text-faint);
[data-component="spinner"] {
width: 16px;
@ -89,14 +89,14 @@
font-weight: var(--font-weight-medium);
line-height: var(--line-height-large);
letter-spacing: var(--letter-spacing-normal);
color: var(--text-strong);
color: var(--v2-text-text-base);
&.capitalize {
text-transform: capitalize;
}
&.agent-title {
color: var(--text-strong);
color: var(--v2-text-text-base);
font-weight: var(--font-weight-medium);
}
}
@ -114,7 +114,7 @@
font-weight: var(--font-weight-regular);
line-height: var(--line-height-large);
letter-spacing: var(--letter-spacing-normal);
color: var(--text-base);
color: var(--v2-text-text-muted);
&.clickable {
cursor: pointer;
@ -122,7 +122,7 @@
transition: color 0.15s ease;
&:hover {
color: var(--text-base);
color: var(--v2-text-text-muted);
}
}
@ -160,7 +160,7 @@
font-weight: var(--font-weight-regular);
line-height: var(--line-height-large);
letter-spacing: var(--letter-spacing-normal);
color: var(--text-base);
color: var(--v2-text-text-muted);
}
[data-slot="basic-tool-tool-action"] {
@ -178,7 +178,7 @@
gap: 8px;
padding: 8px 12px;
border-radius: 6px;
border: 1px solid var(--border-weak-base, rgba(255, 255, 255, 0.08));
border: 0.5px solid var(--border-weak-base, rgba(255, 255, 255, 0.08));
background: color-mix(in srgb, var(--background-base) 92%, transparent);
transition:
border-color 0.15s ease,
@ -213,7 +213,7 @@
align-items: center;
justify-content: center;
flex-shrink: 0;
color: var(--icon-weak);
color: var(--v2-text-text-faint);
margin-left: auto;
opacity: 0;
transition:
@ -233,7 +233,7 @@
}
[data-slot="basic-tool-tool-subtitle"] {
color: var(--text-strong);
color: var(--v2-text-text-base);
}
&:hover,
@ -246,3 +246,34 @@
}
}
}
body:not([data-new-layout]) {
[data-component="tool-trigger"] {
[data-slot="basic-tool-tool-spinner"] {
color: var(--text-weak);
}
[data-slot="basic-tool-tool-title"],
[data-slot="basic-tool-tool-title"].agent-title {
color: var(--text-strong);
}
[data-slot="basic-tool-tool-subtitle"],
[data-slot="basic-tool-tool-subtitle"].clickable:hover,
[data-slot="basic-tool-tool-arg"] {
color: var(--text-base);
}
}
[data-component="task-tool-card"] {
border-width: 1px;
[data-component="task-tool-action"] {
color: var(--icon-weak);
}
[data-slot="basic-tool-tool-subtitle"] {
color: var(--text-strong);
}
}
}

View file

@ -0,0 +1,30 @@
import { describe, expect, test } from "bun:test"
import { inlineCodeKind } from "./markdown-inline-code-kind"
describe("inlineCodeKind", () => {
test("leaves code expressions as normal inline code", () => {
expect(
inlineCodeKind(`case "question.asked": ... input.setStore("question", question.sessionID, [question]) / splice/insert`),
).toBeUndefined()
expect(inlineCodeKind(`<SessionQuestionDock request={request} ... />`)).toBeUndefined()
expect(inlineCodeKind(`from sync.data.question + sync.data.session.`)).toBeUndefined()
expect(inlineCodeKind(`@opencode-ai/app <StatusPopover />)`)).toBeUndefined()
expect(inlineCodeKind(`sync.data.session`)).toBeUndefined()
expect(inlineCodeKind(`window.api`)).toBeUndefined()
})
test("detects file and directory paths", () => {
expect(inlineCodeKind(`app.tsx`)).toBe("path")
expect(inlineCodeKind(`packages/desktop-electron`)).toBe("path")
expect(inlineCodeKind(`~/.config/opencode`)).toBe("path")
expect(inlineCodeKind(`@opencode-ai/app`)).toBe("path")
expect(inlineCodeKind(`session/status`)).toBe("path")
})
test("detects urls", () => {
expect(inlineCodeKind(`https://opencode.ai/docs`)).toBe("url")
expect(inlineCodeKind(`http://localhost:4444`)).toBe("url")
expect(inlineCodeKind(`file:///tmp/opencode`)).toBeUndefined()
expect(inlineCodeKind(`ftp://opencode.ai/docs`)).toBeUndefined()
})
})

View file

@ -0,0 +1,13 @@
export function inlineCodeKind(text: string): "path" | "url" | undefined {
if (/^https?:\/\//i.test(text)) return "url"
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(text)) return
if (/^\/[a-z][a-z0-9-]*$/i.test(text)) return
if (/\s/.test(text)) return
if (/[()\[\]{}*+=<>|&^"';]/.test(text)) return
if (
/[/\\]/.test(text) ||
/^\.\.?[/\\]/.test(text) ||
/\.(tsx?|jsx?|json|py|go|rs|rb|php|css|html|md|sh|ya?ml|toml|sql|c|cpp|h|java|kt|swift|scala|xml|png|jpe?g|gif|svg|ico)$/i.test(text)
)
return "path"
}

View file

@ -1,9 +1,17 @@
[data-component="markdown"] {
--markdown-inline-code-path-color: var(--v2-text-text-code-accent);
--markdown-inline-code-color: var(--v2-text-text-code-accent);
--markdown-inline-code-bg-mix: 8%;
--markdown-shell-code-background: var(--v2-background-bg-layer-02);
--markdown-shell-code-border: var(--v2-border-border-muted);
--markdown-shell-code-color: var(--v2-text-text-base);
--markdown-shell-code-token-color: currentColor;
/* Reset & Base Typography */
min-width: 0;
max-width: 100%;
overflow-wrap: break-word;
color: var(--text-strong);
color: var(--v2-text-text-base);
font-family: var(--font-family-sans);
font-size: var(--font-size-base); /* 14px */
line-height: 160%;
@ -22,15 +30,31 @@
margin-bottom: 0;
}
/* Headings: Same size, distinguished by color and spacing */
h1,
h2,
/* Headings: Sized by level, distinguished by color and spacing */
h1 {
font-size: 17px;
color: var(--v2-text-text-base);
font-weight: 600;
margin-top: 0px;
margin-bottom: 24px;
line-height: var(--line-height-large);
}
h2 {
font-size: 15px;
color: var(--v2-text-text-base);
font-weight: 600;
margin-top: 0px;
margin-bottom: 24px;
line-height: var(--line-height-large);
}
h3,
h4,
h5,
h6 {
font-size: 14px;
color: var(--text-strong);
font-size: 13px;
color: var(--v2-text-text-base);
font-weight: var(--font-weight-medium);
margin-top: 0px;
margin-bottom: 24px;
@ -40,7 +64,7 @@
/* Emphasis & Strong: Neutral strong color */
strong,
b {
color: var(--text-strong);
color: var(--v2-text-text-base);
font-weight: var(--font-weight-medium);
}
@ -95,7 +119,7 @@
}
li::marker {
color: var(--text-weak);
color: var(--v2-text-text-muted);
}
/* Nested lists spacing */
@ -112,10 +136,10 @@
/* Blockquotes */
blockquote {
border-left: 2px solid var(--border-weak-base);
border-left: 0.5px solid var(--v2-border-border-base);
margin: 1.5rem 0;
padding-left: 0.5rem;
color: var(--text-weak);
color: var(--v2-text-text-muted);
font-style: normal;
}
@ -132,13 +156,27 @@
font-size: 13px;
padding: 12px;
border-radius: 6px;
border: 0.5px solid var(--border-weak-base);
border: 0.5px solid var(--v2-border-border-base);
}
[data-component="markdown-code"] {
position: relative;
}
[data-component="markdown-code"][data-code-kind="shell"] .shiki {
background: var(--markdown-shell-code-background);
border-color: var(--markdown-shell-code-border);
color: var(--markdown-shell-code-color);
}
[data-component="markdown-code"][data-code-kind="shell"] code {
color: var(--markdown-shell-code-color);
}
[data-component="markdown-code"][data-code-kind="shell"] code span {
color: var(--markdown-shell-code-token-color) !important;
}
[data-slot="markdown-copy-button"] {
position: absolute;
top: 4px;
@ -160,7 +198,7 @@
background: var(--surface-float-base);
color: var(--text-invert-strong);
padding: 2px 8px;
border: 1px solid var(--border-weak-base, rgba(0, 0, 0, 0.07));
border: 0.5px solid var(--v2-border-border-base, rgba(0, 0, 0, 0.07));
box-shadow: var(--shadow-md);
pointer-events: none;
@ -185,11 +223,11 @@
[data-slot="markdown-copy-button"][data-variant="secondary"] {
box-shadow: none;
border: 1px solid var(--border-weak-base);
border: 0.5px solid var(--v2-border-border-base);
}
[data-slot="markdown-copy-button"][data-variant="secondary"] [data-slot="icon-svg"] {
color: var(--icon-base);
color: var(--v2-icon-icon-base);
}
[data-component="markdown-code"]:hover [data-slot="markdown-copy-button"] {
@ -222,15 +260,28 @@
:not(pre) > code {
font-family: var(--font-family-mono);
font-feature-settings: var(--font-family-mono--font-feature-settings);
color: var(--syntax-string);
color: var(--v2-text-text-base);
font-weight: var(--font-weight-medium);
/* font-size: 13px; */
padding: 2px 4px;
border-radius: 4px;
background: color-mix(in oklch, var(--v2-text-text-base) var(--markdown-inline-code-bg-mix), transparent);
}
/* padding: 2px 2px; */
/* margin: 0 1.5px; */
/* border-radius: 2px; */
/* background: var(--surface-base); */
/* box-shadow: 0 0 0 0.5px var(--border-weak-base); */
:not(pre) > code[data-inline-code-kind="path"] {
color: var(--markdown-inline-code-path-color);
background: color-mix(
in oklch,
var(--markdown-inline-code-path-color) var(--markdown-inline-code-bg-mix),
transparent
);
}
a.external-link > code[data-inline-code-kind="url"] {
color: var(--markdown-inline-code-color);
background: none;
text-decoration: underline;
text-decoration-color: color-mix(in oklch, var(--markdown-inline-code-color) 25%, transparent);
text-underline-offset: 2px;
}
/* Tables */
@ -246,16 +297,16 @@
th,
td {
/* Minimal borders for structure, matching TUI "lines" roughly but keeping it web-clean */
border-bottom: 1px solid var(--border-weaker-base);
border-bottom: 0.5px solid var(--v2-border-border-muted);
padding: 12px;
text-align: left;
vertical-align: top;
}
th {
color: var(--text-strong);
color: var(--v2-text-text-base);
font-weight: var(--font-weight-medium);
border-bottom: 1px solid var(--border-weak-base);
border-bottom: 0.5px solid var(--v2-border-border-base);
}
/* Images */
@ -268,6 +319,68 @@
}
}
body:not([data-new-layout]) [data-component="markdown"] {
color: var(--text-strong);
h1,
h2,
h3,
h4,
h5,
h6 {
font-size: 14px;
color: var(--text-strong);
font-weight: var(--font-weight-medium);
}
strong,
b {
color: var(--text-strong);
}
li::marker {
color: var(--text-weak);
}
blockquote {
border-left: 2px solid var(--border-weak-base);
color: var(--text-weak);
}
.shiki {
border-color: var(--border-weak-base);
}
:not(pre) > code {
color: var(--syntax-string);
padding: 0;
border-radius: 0;
background: none;
}
[data-slot="markdown-copy-button"]::after {
border: 1px solid var(--border-weak-base, rgba(0, 0, 0, 0.07));
}
[data-slot="markdown-copy-button"][data-variant="secondary"] {
border: 1px solid var(--border-weak-base);
}
[data-slot="markdown-copy-button"][data-variant="secondary"] [data-slot="icon-svg"] {
color: var(--icon-base);
}
th,
td {
border-bottom: 1px solid var(--border-weaker-base);
}
th {
color: var(--text-strong);
border-bottom-color: var(--border-weak-base);
}
}
[data-component="markdown"] a.external-link:hover > code {
text-decoration: underline;
text-underline-offset: 2px;

View file

@ -25,6 +25,7 @@ import {
import { markdownBlockKey, type MarkdownToken } from "./markdown-worker-protocol"
import { shouldResetCodeTokens, type RenderedCodeState } from "./markdown-code-state"
import { getCachedMarkdown, sanitizeMarkdown, touchCachedMarkdown, type MarkdownCacheEntry } from "./markdown-cache"
import { inlineCodeKind } from "./markdown-inline-code-kind"
type RenderedBlock =
| (MarkdownCacheEntry & { key: string; mode: Exclude<Block["mode"], "code"> })
@ -140,6 +141,35 @@ function setCopyState(button: HTMLButtonElement, labels: CopyLabels, copied: boo
button.setAttribute("data-tooltip", labels.copy)
}
const shellLanguages = new Set(["bash", "sh", "shell", "zsh", "fish", "console", "terminal"])
function codeKind(language: string | undefined) {
const value = language?.toLowerCase()
if (!value) return
if (shellLanguages.has(value)) return "shell"
}
function codeLanguage(block: HTMLPreElement) {
const code = block.querySelector("code")
if (!(code instanceof HTMLElement)) return
return code.className.match(/(?:^|\s)language-([^\s]+)/)?.[1]
}
function applyCodeMetadata(wrapper: HTMLElement, language: string | undefined) {
if (!document.body.hasAttribute("data-new-layout")) {
delete wrapper.dataset.language
delete wrapper.dataset.codeKind
return
}
if (language) wrapper.dataset.language = language
else delete wrapper.dataset.language
const kind = codeKind(language)
if (kind) wrapper.dataset.codeKind = kind
else delete wrapper.dataset.codeKind
}
function ensureCodeWrapper(block: HTMLPreElement, labels: CopyLabels) {
const parent = block.parentElement
if (!parent) return
@ -147,12 +177,15 @@ function ensureCodeWrapper(block: HTMLPreElement, labels: CopyLabels) {
if (!wrapped) {
const wrapper = document.createElement("div")
wrapper.setAttribute("data-component", "markdown-code")
applyCodeMetadata(wrapper, codeLanguage(block))
parent.replaceChild(wrapper, block)
wrapper.appendChild(block)
wrapper.appendChild(createCopyButton(labels))
return
}
applyCodeMetadata(parent, codeLanguage(block))
const buttons = Array.from(parent.querySelectorAll('[data-slot="markdown-copy-button"]')).filter(
(el): el is HTMLButtonElement => el instanceof HTMLButtonElement,
)
@ -196,11 +229,23 @@ function markCodeLinks(root: HTMLDivElement) {
}
}
function markInlineCode(root: HTMLDivElement) {
const codeNodes = Array.from(root.querySelectorAll(":not(pre) > code"))
for (const code of codeNodes) {
if (!(code instanceof HTMLElement)) continue
delete code.dataset.inlineCodeKind
const kind = inlineCodeKind(code.textContent ?? "")
if (kind) code.dataset.inlineCodeKind = kind
}
}
function decorate(root: HTMLDivElement, labels: CopyLabels) {
const blocks = Array.from(root.querySelectorAll("pre"))
for (const block of blocks) {
ensureCodeWrapper(block, labels)
}
if (!document.body.hasAttribute("data-new-layout")) return
markInlineCode(root)
markCodeLinks(root)
}
@ -522,6 +567,8 @@ function updateCodeBlock(
const code = existing?.querySelector("code")
if (code instanceof HTMLElement) {
const wrapper = code.closest('[data-component="markdown-code"]')
if (wrapper instanceof HTMLElement) applyCodeMetadata(wrapper, block.language)
code.className = `language-${block.language}`
const previous = renderedCodeTokens.get(next)
const reset = shouldResetCodeTokens(previous, {
@ -552,6 +599,7 @@ function updateCodeBlock(
const wrapper = document.createElement("div")
wrapper.setAttribute("data-component", "markdown-code")
applyCodeMetadata(wrapper, block.language)
const pre = document.createElement("pre")
pre.className = "shiki OpenCode"
const codeElement = document.createElement("code")

View file

@ -14,7 +14,7 @@
font-weight: var(--font-weight-regular);
line-height: var(--line-height-large);
letter-spacing: var(--letter-spacing-normal);
color: var(--text-strong);
color: var(--v2-text-text-base);
display: flex;
flex-direction: column;
align-items: flex-end;
@ -41,15 +41,15 @@
min-width: 0;
border-radius: 6px;
overflow: hidden;
background: var(--surface-weak);
border: 1px solid var(--border-weak-base);
background: var(--v2-background-bg-layer-02);
border: 0.5px solid var(--v2-border-border-base);
cursor: default;
transition:
border-color 0.15s ease,
opacity 0.3s ease;
&:hover {
border-color: var(--border-strong-base);
border-color: var(--v2-border-border-strong);
}
&[data-clickable] {
@ -107,7 +107,7 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--text-base);
color: var(--v2-text-text-muted);
font-size: var(--font-size-small);
line-height: var(--line-height-large);
}
@ -130,10 +130,10 @@
white-space: pre-wrap;
word-break: break-word;
overflow: hidden;
background: var(--surface-base);
border: 1px solid var(--border-weak-base);
background: var(--v2-background-bg-layer-02);
border: none;
padding: 8px 12px;
border-radius: 6px;
border-radius: 10px;
[data-highlight="file"] {
color: var(--syntax-property);
@ -199,7 +199,7 @@
}
.text-text-strong {
color: var(--text-strong);
color: var(--v2-text-text-base);
}
.font-medium {
@ -267,7 +267,7 @@
[data-slot="compaction-part-line"] {
flex: 1 1 auto;
height: 1px;
background: var(--border-weak-base);
background: var(--v2-border-border-base);
}
[data-slot="compaction-part-label"] {
@ -279,18 +279,18 @@
[data-component="reasoning-part"] {
width: 100%;
color: var(--text-base);
color: var(--v2-text-text-muted);
line-height: var(--line-height-normal);
[data-component="markdown"] {
margin-top: 16px;
font-style: normal;
font-size: 13px;
color: var(--text-weak);
color: var(--v2-text-text-muted);
strong,
b {
color: var(--text-weak);
color: var(--v2-text-text-muted);
}
p:has(strong) {
@ -357,7 +357,7 @@
[data-component="bash-output"] {
width: 100%;
border: 1px solid var(--border-weak-base);
border: 0.5px solid var(--v2-border-border-base);
border-radius: 6px;
background: transparent;
position: relative;
@ -380,7 +380,7 @@
[data-slot="bash-copy"] [data-component="icon-button"][data-variant="secondary"] {
box-shadow: none;
border: 1px solid var(--border-weak-base);
border: 0.5px solid var(--v2-border-border-base);
}
[data-slot="bash-copy"] [data-component="icon-button"][data-variant="secondary"] [data-slot="icon-svg"] {
@ -442,7 +442,7 @@
font-weight: var(--font-weight-medium);
line-height: var(--line-height-large);
letter-spacing: var(--letter-spacing-normal);
color: var(--text-base);
color: var(--v2-text-text-muted);
}
[data-slot="message-part-title-spinner"] {
@ -453,7 +453,7 @@
align-items: center;
justify-content: center;
flex-shrink: 0;
color: var(--text-weak);
color: var(--v2-text-text-muted);
[data-component="spinner"] {
width: 16px;
@ -464,7 +464,7 @@
[data-slot="message-part-title-text"] {
flex-shrink: 0;
text-transform: capitalize;
color: var(--text-strong);
color: var(--v2-text-text-base);
}
[data-slot="message-part-title-filename"] {
@ -484,7 +484,7 @@
}
[data-slot="message-part-directory"] {
color: var(--text-weak);
color: var(--v2-text-text-muted);
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
@ -493,7 +493,7 @@
}
[data-slot="message-part-filename"] {
color: var(--text-strong);
color: var(--v2-text-text-base);
flex-shrink: 0;
}
@ -508,7 +508,7 @@
[data-component="edit-content"] {
border-radius: inherit;
border-top: 1px solid var(--border-weaker-base);
border-top: 0.5px solid var(--v2-border-border-muted);
overflow-x: hidden;
overflow-y: visible;
@ -527,7 +527,7 @@
[data-component="write-content"] {
border-radius: inherit;
border-top: 1px solid var(--border-weaker-base);
border-top: 0.5px solid var(--v2-border-border-muted);
overflow-x: hidden;
overflow-y: visible;
@ -561,7 +561,7 @@
font-family: var(--font-family-sans);
font-size: var(--font-size-base);
line-height: var(--line-height-large);
color: var(--text-base);
color: var(--v2-text-text-muted);
}
[data-slot="basic-tool-tool-subtitle"].exa-tool-query {
@ -583,7 +583,7 @@
max-width: 100%;
font: inherit;
line-height: inherit;
color: var(--text-interactive-base);
color: var(--v2-text-text-accent);
text-decoration: underline;
text-underline-offset: 2px;
overflow: hidden;
@ -591,11 +591,11 @@
white-space: nowrap;
&:hover {
color: var(--text-interactive-base);
color: var(--v2-text-text-accent);
}
&:visited {
color: var(--text-interactive-base);
color: var(--v2-text-text-accent);
}
}
@ -615,7 +615,7 @@
&[data-completed="completed"] {
text-decoration: line-through;
color: var(--text-weaker);
color: var(--v2-text-text-faint);
}
}
}
@ -660,8 +660,8 @@
flex-direction: column;
gap: 4px;
padding: 8px 12px;
background-color: var(--surface-critical-weak);
border-top: 1px solid var(--border-critical-base);
background-color: var(--v2-state-bg-danger);
border-top: 0.5px solid var(--v2-state-border-danger);
[data-slot="diagnostic"] {
display: flex;
@ -673,7 +673,7 @@
}
[data-slot="diagnostic-label"] {
color: var(--text-on-critical-base);
color: var(--v2-state-fg-danger);
font-weight: var(--font-weight-medium);
text-transform: uppercase;
letter-spacing: -0.5px;
@ -681,12 +681,12 @@
}
[data-slot="diagnostic-location"] {
color: var(--text-on-critical-weak);
color: var(--v2-state-fg-danger);
flex-shrink: 0;
}
[data-slot="diagnostic-message"] {
color: var(--text-on-critical-base);
color: var(--v2-state-fg-danger);
word-break: break-word;
display: -webkit-box;
-webkit-box-orient: vertical;
@ -761,7 +761,7 @@
font-size: 14px;
font-weight: var(--font-weight-medium);
line-height: var(--line-height-large);
color: var(--text-strong);
color: var(--v2-text-text-base);
min-width: 0;
}
@ -778,7 +778,7 @@
font-size: 14px;
font-weight: var(--font-weight-regular);
line-height: var(--line-height-large);
color: var(--text-weak);
color: var(--v2-text-text-muted);
padding: 0;
}
@ -856,7 +856,7 @@
font-size: 14px;
font-weight: var(--font-weight-medium);
line-height: var(--line-height-large);
color: var(--text-strong);
color: var(--v2-text-text-base);
min-width: 0;
}
@ -916,7 +916,7 @@
font-size: 14px;
font-weight: var(--font-weight-medium);
line-height: var(--line-height-large);
color: var(--text-strong);
color: var(--v2-text-text-base);
padding: 0 10px;
-webkit-user-select: text;
user-select: text;
@ -927,7 +927,7 @@
font-size: 13px;
font-weight: var(--font-weight-regular);
line-height: var(--line-height-large);
color: var(--text-weak);
color: var(--v2-text-text-muted);
padding: 0 10px;
}
@ -953,8 +953,8 @@
align-items: flex-start;
gap: 12px;
padding: 8px 8px 8px 10px;
background-color: var(--surface-raised-stronger-non-alpha);
border: 1px solid var(--border-weak-base);
background-color: var(--v2-background-bg-layer-01);
border: 0.5px solid var(--v2-border-border-base);
border-radius: 6px;
box-shadow: none;
text-align: left;
@ -966,11 +966,11 @@
box-shadow 0.15s ease;
&:hover:not([data-picked="true"]) {
background-color: var(--background-base);
background-color: var(--v2-background-bg-base);
}
&[data-picked="true"] {
background-color: var(--surface-interactive-weak);
background-color: var(--v2-state-bg-info);
border-color: transparent;
box-shadow: var(--shadow-xs-border-hover);
}
@ -991,7 +991,7 @@
height: 16px;
padding: 2px;
border-radius: var(--radius-sm);
border: 1px solid var(--border-weak-base);
border: 0.5px solid var(--v2-border-border-base);
display: inline-flex;
align-items: center;
justify-content: center;
@ -1014,7 +1014,7 @@
width: 6px;
height: 6px;
border-radius: 999px;
background-color: var(--background-stronger);
background-color: var(--v2-background-bg-layer-01);
opacity: 0;
}
@ -1052,7 +1052,7 @@
font-size: 14px;
font-weight: var(--font-weight-medium);
line-height: var(--line-height-large);
color: var(--text-strong);
color: var(--v2-text-text-base);
}
[data-slot="option-description"] {
@ -1060,7 +1060,7 @@
font-size: 14px;
font-weight: var(--font-weight-regular);
line-height: var(--line-height-large);
color: var(--text-base);
color: var(--v2-text-text-muted);
min-width: 0;
overflow-wrap: anywhere;
white-space: normal;
@ -1088,7 +1088,7 @@
font-size: 14px;
font-weight: var(--font-weight-regular);
line-height: var(--line-height-large);
color: var(--text-base);
color: var(--v2-text-text-muted);
min-width: 0;
cursor: text;
resize: none;
@ -1096,11 +1096,11 @@
overflow-wrap: anywhere;
&::placeholder {
color: var(--text-weak);
color: var(--v2-text-text-muted);
}
&:focus-visible {
outline: 1px solid var(--border-interactive-base);
outline: 0.5px solid var(--v2-border-border-focus);
outline-offset: 2px;
border-radius: var(--radius-xs);
}
@ -1139,11 +1139,11 @@
font-size: 13px;
[data-slot="question-text"] {
color: var(--text-weak);
color: var(--v2-text-text-muted);
}
[data-slot="answer-text"] {
color: var(--text-strong);
color: var(--v2-text-text-base);
}
}
}
@ -1166,13 +1166,13 @@
z-index: 20;
height: calc(32px + var(--tool-content-gap));
padding-bottom: var(--tool-content-gap);
background-color: var(--background-stronger);
background-color: var(--v2-background-bg-base);
}
}
[data-component="accordion"][data-scope="apply-patch"] {
[data-slot="accordion-trigger"] {
background-color: var(--background-stronger) !important;
background-color: var(--v2-background-bg-base) !important;
}
[data-slot="apply-patch-trigger-content"] {
@ -1199,7 +1199,7 @@
}
[data-slot="apply-patch-directory"] {
color: var(--text-base);
color: var(--v2-text-text-muted);
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
@ -1208,7 +1208,7 @@
}
[data-slot="apply-patch-filename"] {
color: var(--text-strong);
color: var(--v2-text-text-base);
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
@ -1268,10 +1268,199 @@
font-size: var(--font-size-small);
font-weight: var(--font-weight-regular);
line-height: var(--line-height-large);
color: var(--text-weak);
color: var(--v2-text-text-muted);
[data-component="icon"] {
flex-shrink: 0;
color: var(--icon-weak);
}
}
body:not([data-new-layout]) {
[data-component="user-message"] {
color: var(--text-strong);
[data-slot="user-message-attachment"] {
background: var(--surface-weak);
border: 1px solid var(--border-weak-base);
&:hover {
border-color: var(--border-strong-base);
}
}
[data-slot="user-message-attachment-name"] {
color: var(--text-base);
}
[data-slot="user-message-text"] {
background: var(--surface-base);
border: 1px solid var(--border-weak-base);
border-radius: 6px;
}
.text-text-strong {
color: var(--text-strong);
}
}
[data-slot="compaction-part-line"] {
background: var(--border-weak-base);
}
[data-component="reasoning-part"] {
color: var(--text-base);
[data-component="markdown"],
[data-component="markdown"] :is(strong, b) {
color: var(--text-weak);
}
}
[data-component="bash-output"] {
border: 1px solid var(--border-weak-base);
[data-slot="bash-copy"] [data-component="icon-button"][data-variant="secondary"] {
border: 1px solid var(--border-weak-base);
}
}
[data-component="edit-trigger"],
[data-component="write-trigger"] {
[data-slot="message-part-title"] {
color: var(--text-base);
}
[data-slot="message-part-title-spinner"],
[data-slot="message-part-directory"] {
color: var(--text-weak);
}
[data-slot="message-part-title-text"],
[data-slot="message-part-filename"] {
color: var(--text-strong);
}
}
[data-component="edit-content"],
[data-component="write-content"] {
border-top: 1px solid var(--border-weaker-base);
}
[data-component="exa-tool-output"] {
color: var(--text-base);
}
[data-slot="exa-tool-link"],
[data-slot="exa-tool-link"]:hover,
[data-slot="exa-tool-link"]:visited {
color: var(--text-interactive-base);
}
[data-slot="message-part-todo-content"][data-completed="completed"] {
color: var(--text-weaker);
}
[data-component="diagnostics"] {
background-color: var(--surface-critical-weak);
border-top: 1px solid var(--border-critical-base);
[data-slot="diagnostic-label"],
[data-slot="diagnostic-message"] {
color: var(--text-on-critical-base);
}
[data-slot="diagnostic-location"] {
color: var(--text-on-critical-weak);
}
}
[data-component="dock-prompt"][data-kind="permission"] {
[data-slot="permission-header-title"] {
color: var(--text-strong);
}
[data-slot="permission-hint"] {
color: var(--text-weak);
}
}
[data-component="dock-prompt"][data-kind="question"] {
[data-slot="question-header-title"],
[data-slot="question-text"],
[data-slot="option-label"] {
color: var(--text-strong);
}
[data-slot="question-hint"] {
color: var(--text-weak);
}
[data-slot="question-option"] {
background-color: var(--surface-raised-stronger-non-alpha);
border: 1px solid var(--border-weak-base);
&:hover:not([data-picked="true"]) {
background-color: var(--background-base);
}
&[data-picked="true"] {
background-color: var(--surface-interactive-weak);
}
}
[data-slot="question-option-box"] {
border: 1px solid var(--border-weak-base);
[data-slot="question-option-radio-dot"] {
background-color: var(--background-stronger);
}
}
[data-slot="option-description"],
[data-slot="question-custom-input"] {
color: var(--text-base);
}
[data-slot="question-custom-input"] {
&::placeholder {
color: var(--text-weak);
}
&:focus-visible {
outline: 1px solid var(--border-interactive-base);
}
}
}
[data-component="question-answers"] {
[data-slot="question-text"] {
color: var(--text-weak);
}
[data-slot="answer-text"] {
color: var(--text-strong);
}
}
:is([data-component="edit-tool"], [data-component="write-tool"], [data-component="apply-patch-tool"])
> [data-component="collapsible"]
> [data-slot="collapsible-trigger"][aria-expanded="true"],
[data-component="accordion"][data-scope="apply-patch"] [data-slot="accordion-trigger"] {
background-color: var(--background-stronger) !important;
}
[data-component="accordion"][data-scope="apply-patch"] {
[data-slot="apply-patch-directory"] {
color: var(--text-base);
}
[data-slot="apply-patch-filename"] {
color: var(--text-strong);
}
}
[data-component="tool-loaded-file"] {
color: var(--text-weak);
}
}

View file

@ -21,7 +21,7 @@
[data-slot="session-review-header"] {
z-index: 120;
background-color: var(--background-stronger);
background-color: var(--v2-background-bg-base);
height: 40px;
padding-bottom: 8px;
flex-shrink: 0;
@ -211,7 +211,7 @@
[data-slot="session-review-large-diff"] {
padding: 12px;
background: var(--background-stronger);
background: var(--v2-background-bg-base);
}
[data-slot="session-review-large-diff-title"] {
@ -235,3 +235,13 @@
margin-top: 10px;
}
}
body:not([data-new-layout]) [data-component="session-review"] {
[data-slot="session-review-header"] {
background-color: var(--background-stronger);
}
[data-slot="session-review-large-diff"] {
background: var(--background-stronger);
}
}

View file

@ -71,7 +71,7 @@
}
.error-card {
color: var(--text-on-critical-base);
color: var(--v2-text-text-base);
max-height: 240px;
white-space: pre-wrap;
overflow-wrap: anywhere;
@ -102,7 +102,7 @@
position: sticky;
top: var(--sticky-accordion-top, 0px);
z-index: 20;
background-color: var(--background-stronger);
background-color: var(--v2-background-bg-base);
height: 44px;
}
@ -226,6 +226,16 @@
}
}
body:not([data-new-layout]) [data-component="session-turn"] {
.error-card {
color: var(--text-on-critical-base);
}
[data-slot="session-turn-diffs-header"] {
background-color: var(--background-stronger);
}
}
[data-slot="session-turn-list"] {
gap: 24px;
}

View file

@ -2,6 +2,19 @@
--card-pad-y: 8px;
--card-line-pad: 12px;
[data-slot="basic-tool-tool-title"] {
color: var(--v2-text-text-base);
}
[data-slot="basic-tool-tool-subtitle"] {
color: var(--v2-text-text-muted);
}
[data-slot="collapsible-arrow"],
[data-slot="collapsible-arrow-icon"] {
color: var(--v2-text-text-faint);
}
> [data-component="collapsible"].tool-collapsible {
gap: 0px;
}
@ -43,10 +56,34 @@
}
[data-slot="tool-error-card-content"] :where(*)::selection {
background: var(--surface-critical-base);
color: var(--text-on-critical-base);
background: var(--v2-state-bg-danger);
color: var(--v2-text-text-base);
}
[data-slot="tool-error-card-content"] :where(*)::-moz-selection {
background: var(--v2-state-bg-danger);
color: var(--v2-text-text-base);
}
}
body:not([data-new-layout]) [data-component="card"][data-kind="tool-error-card"] {
[data-slot="basic-tool-tool-title"] {
color: var(--text-strong);
}
[data-slot="basic-tool-tool-subtitle"] {
color: var(--text-base);
}
[data-slot="collapsible-arrow"] {
color: var(--text-base);
}
[data-slot="collapsible-arrow-icon"] {
color: var(--icon-weaker);
}
[data-slot="tool-error-card-content"] :where(*)::selection,
[data-slot="tool-error-card-content"] :where(*)::-moz-selection {
background: var(--surface-critical-base);
color: var(--text-on-critical-base);