diff --git a/packages/app/src/components/dialog-edit-project.tsx b/packages/app/src/components/dialog-edit-project.tsx index 2ab25ceeb..490753e62 100644 --- a/packages/app/src/components/dialog-edit-project.tsx +++ b/packages/app/src/components/dialog-edit-project.tsx @@ -145,8 +145,7 @@ export function DialogEditProject(props: { project: LocalProject }) { } @@ -159,39 +158,19 @@ export function DialogEditProject(props: { project: LocalProject }) {
diff --git a/packages/app/src/components/dialog-fork.tsx b/packages/app/src/components/dialog-fork.tsx index 17782f5ab..09d62021f 100644 --- a/packages/app/src/components/dialog-fork.tsx +++ b/packages/app/src/components/dialog-fork.tsx @@ -90,12 +90,8 @@ export const DialogFork: Component = () => { > {(item) => (
- - {item.text} - - - {item.time} - + {item.text} + {item.time}
)} diff --git a/packages/app/src/components/dialog-release-notes.tsx b/packages/app/src/components/dialog-release-notes.tsx index d3ee7e201..c6f2f3930 100644 --- a/packages/app/src/components/dialog-release-notes.tsx +++ b/packages/app/src/components/dialog-release-notes.tsx @@ -73,80 +73,86 @@ export function DialogReleaseNotes(props: { highlights: Highlight[] }) { }) return ( - + {/* Hidden element to capture initial focus and handle escape */}
- {/* Left side - Text content */} -
- {/* Top section - feature content (fixed position from top) */} -
-
-

{feature()?.title ?? ""}

-
-

{feature()?.description ?? ""}

-
- - {/* Spacer to push buttons to bottom */} -
- - {/* Bottom section - buttons and indicators (fixed position) */} -
-
- {isLast() ? ( - - ) : ( - - )} - - -
- - {paged() && ( -
- {props.highlights.map((_, i) => ( - - ))} +
+ {/* Left side - Text content */} +
+ {/* Top section - feature content (fixed position from top) */} +
+
+

{feature()?.title ?? ""}

- )} -
-
+

{feature()?.description ?? ""}

+
- {/* Right side - Media content (edge to edge) */} - {feature()?.media && ( -
- {feature()!.media!.type === "image" ? ( - {feature()!.media!.alt - ) : ( -
) } diff --git a/packages/app/src/components/dialog-select-server.tsx b/packages/app/src/components/dialog-select-server.tsx index 910b05ad4..e9e7646d5 100644 --- a/packages/app/src/components/dialog-select-server.tsx +++ b/packages/app/src/components/dialog-select-server.tsx @@ -59,18 +59,16 @@ function AddRow(props: AddRowProps) {
{ // Position relative to input-wrapper requestAnimationFrame(() => { const wrapper = el.parentElement?.querySelector('[data-slot="input-wrapper"]') if (wrapper instanceof HTMLElement) { - wrapper.style.position = "relative" wrapper.appendChild(el) } }) diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index 84f16d67e..c736ef0f1 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -1746,10 +1746,7 @@ export const PromptInput: Component = (props) => { - + {getDirectory(item.path)} {getFilename(item.path)} @@ -1772,10 +1769,7 @@ export const PromptInput: Component = (props) => { >
-
+
{getFilenameTruncated(item.path, 14)} {(sel) => ( diff --git a/packages/app/src/components/session/session-new-view.tsx b/packages/app/src/components/session/session-new-view.tsx index 2b79c47df..9306e8acb 100644 --- a/packages/app/src/components/session/session-new-view.tsx +++ b/packages/app/src/components/session/session-new-view.tsx @@ -45,10 +45,7 @@ export function NewSessionView(props: NewSessionViewProps) { } return ( -
+
{language.t("command.session.new")}
diff --git a/packages/app/src/components/session/session-sortable-terminal-tab.tsx b/packages/app/src/components/session/session-sortable-terminal-tab.tsx index 75e9b22f9..aedf67876 100644 --- a/packages/app/src/components/session/session-sortable-terminal-tab.tsx +++ b/packages/app/src/components/session/session-sortable-terminal-tab.tsx @@ -146,7 +146,7 @@ export function SortableTerminalTab(props: { terminal: LocalPTY; onClose?: () => /> } > - + {label()} @@ -167,8 +167,8 @@ export function SortableTerminalTab(props: { terminal: LocalPTY; onClose?: () => setStore("menuOpen", open)}> { const soundOptions = [...SOUND_OPTIONS] return ( -
-
+
+

{language.t("settings.tab.general")}

diff --git a/packages/app/src/components/settings-keybinds.tsx b/packages/app/src/components/settings-keybinds.tsx index 7ff3425ab..a2cd3280c 100644 --- a/packages/app/src/components/settings-keybinds.tsx +++ b/packages/app/src/components/settings-keybinds.tsx @@ -352,14 +352,8 @@ export const SettingsKeybinds: Component = () => { }) return ( -
-
+
+

{language.t("settings.shortcuts.title")}

diff --git a/packages/app/src/components/settings-models.tsx b/packages/app/src/components/settings-models.tsx index 3a73a42de..0cb6deee1 100644 --- a/packages/app/src/components/settings-models.tsx +++ b/packages/app/src/components/settings-models.tsx @@ -39,14 +39,8 @@ export const SettingsModels: Component = () => { }) return ( -
-
+
+

{language.t("settings.models.title")}

diff --git a/packages/app/src/components/settings-permissions.tsx b/packages/app/src/components/settings-permissions.tsx index 1381515f5..bcbf7b68f 100644 --- a/packages/app/src/components/settings-permissions.tsx +++ b/packages/app/src/components/settings-permissions.tsx @@ -175,13 +175,7 @@ export const SettingsPermissions: Component = () => { return (
-
+

{language.t("settings.permissions.title")}

{language.t("settings.permissions.description")}

diff --git a/packages/app/src/components/settings-providers.tsx b/packages/app/src/components/settings-providers.tsx index d098db279..86a393b98 100644 --- a/packages/app/src/components/settings-providers.tsx +++ b/packages/app/src/components/settings-providers.tsx @@ -68,7 +68,7 @@ export const SettingsProviders: Component = () => { } return ( -
+

{language.t("settings.providers.title")}

diff --git a/packages/app/src/components/status-popover.tsx b/packages/app/src/components/status-popover.tsx index 79511ef04..102c477a1 100644 --- a/packages/app/src/components/status-popover.tsx +++ b/packages/app/src/components/status-popover.tsx @@ -176,33 +176,16 @@ export function StatusPopover() { placement="bottom-end" shift={-136} > -
+
- + {serverCount() > 0 ? `${serverCount()} ` : ""} {language.t("status.popover.tab.servers")} diff --git a/packages/app/src/index.css b/packages/app/src/index.css index c0c7da858..4af87bca6 100644 --- a/packages/app/src/index.css +++ b/packages/app/src/index.css @@ -1,84 +1 @@ @import "@opencode-ai/ui/styles/tailwind"; - -:root { - a { - cursor: default; - } -} - -[data-component="markdown"] ul { - list-style: disc outside; - padding-left: 1.5rem; -} - -[data-component="markdown"] ol { - list-style: decimal outside; - padding-left: 1.5rem; -} - -[data-component="markdown"] li > p:first-child { - display: inline; - margin: 0; -} - -[data-component="markdown"] li > p + p { - display: block; - margin-top: 0.5rem; -} - -*[data-tauri-drag-region] { - app-region: drag; -} - -.session-scroller::-webkit-scrollbar { - width: 10px !important; - height: 10px !important; -} - -.session-scroller::-webkit-scrollbar-track { - background: transparent !important; - border-radius: 5px !important; -} - -.session-scroller::-webkit-scrollbar-thumb { - background: var(--border-weak-base) !important; - border-radius: 5px !important; - border: 3px solid transparent !important; - background-clip: padding-box !important; -} - -.session-scroller::-webkit-scrollbar-thumb:hover { - background: var(--border-weak-base) !important; -} - -.session-scroller { - scrollbar-width: thin !important; - scrollbar-color: var(--border-weak-base) transparent !important; -} - -/* Wider dialog variant for release notes modal */ -[data-component="dialog"]:has(.dialog-release-notes) { - padding: 20px; - box-sizing: border-box; - - [data-slot="dialog-container"] { - width: min(100%, 720px); - height: min(100%, 400px); - margin-top: -80px; - - [data-slot="dialog-content"] { - min-height: auto; - overflow: hidden; - height: 100%; - border: none; - box-shadow: var(--shadow-lg-border-base); - } - - [data-slot="dialog-body"] { - overflow: hidden; - height: 100%; - display: flex; - flex-direction: row; - } - } -} diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index 97eed72d7..15557dedb 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -1563,7 +1563,6 @@ export default function Layout(props: ParentProps) { const notifications = createMemo(() => notification.project.unseen(props.project.worktree)) const hasError = createMemo(() => notifications().some((n) => n.type === "error")) const name = createMemo(() => props.project.name || getFilename(props.project.worktree)) - const mask = "radial-gradient(circle 5px at calc(100% - 4px) 4px, transparent 5px, black 5.5px)" const opencode = "4b0ea68d7af9a6031a7ffda7ad66e0cb83315750" return ( @@ -1574,11 +1573,7 @@ export default function Layout(props: ParentProps) { src={props.project.id === opencode ? "https://opencode.ai/favicon.svg" : props.project.icon?.override} {...getAvatarColors(props.project.icon?.color)} class="size-full rounded" - style={ - notifications().length > 0 && props.notify - ? { "-webkit-mask-image": mask, "mask-image": mask } - : undefined - } + classList={{ "badge-mask": notifications().length > 0 && props.notify }} />
0 && props.notify}> @@ -2348,8 +2343,7 @@ export default function Layout(props: ParentProps) { ref={(el) => { if (!props.mobile) scrollContainerRef = el }} - class="size-full flex flex-col py-2 overflow-y-auto no-scrollbar" - style={{ "overflow-anchor": "none" }} + class="size-full flex flex-col py-2 overflow-y-auto no-scrollbar [overflow-anchor:none]" >
) diff --git a/packages/ui/src/components/message-part.css b/packages/ui/src/components/message-part.css index d47a3a79b..56fe9cf41 100644 --- a/packages/ui/src/components/message-part.css +++ b/packages/ui/src/components/message-part.css @@ -81,6 +81,14 @@ padding: 8px 12px; border-radius: 4px; + [data-highlight="file"] { + color: var(--syntax-property); + } + + [data-highlight="agent"] { + color: var(--syntax-type); + } + [data-slot="user-message-copy-wrapper"] { position: absolute; top: 7px; diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx index 194d5148a..3fde255c8 100644 --- a/packages/ui/src/components/message-part.tsx +++ b/packages/ui/src/components/message-part.tsx @@ -477,20 +477,7 @@ function HighlightedText(props: { text: string; references: FilePart[]; agents: return result }) - return ( - - {(segment) => ( - - {segment.text} - - )} - - ) + return {(segment) => {segment.text}} } export function Part(props: MessagePartProps) { diff --git a/packages/ui/src/components/session-turn.css b/packages/ui/src/components/session-turn.css index 4a2714c0e..d1ade879e 100644 --- a/packages/ui/src/components/session-turn.css +++ b/packages/ui/src/components/session-turn.css @@ -499,6 +499,10 @@ gap: 8px; color: var(--text-weak); + [data-slot="session-turn-trigger-icon"] { + color: var(--icon-base); + } + [data-component="spinner"] { width: 12px; height: 12px; diff --git a/packages/ui/src/components/session-turn.tsx b/packages/ui/src/components/session-turn.tsx index 5aa79e0b9..8b20a73b4 100644 --- a/packages/ui/src/components/session-turn.tsx +++ b/packages/ui/src/components/session-turn.tsx @@ -565,7 +565,7 @@ export function SessionTurn( viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg" - class="text-icon-base" + data-slot="session-turn-trigger-icon" > ) { {split.children} diff --git a/packages/ui/src/styles/tailwind/utilities.css b/packages/ui/src/styles/tailwind/utilities.css index 8194aeffb..be305b4cb 100644 --- a/packages/ui/src/styles/tailwind/utilities.css +++ b/packages/ui/src/styles/tailwind/utilities.css @@ -8,6 +8,39 @@ } } +@utility session-scroller { + &::-webkit-scrollbar { + width: 10px; + height: 10px; + } + + &::-webkit-scrollbar-track { + background: transparent; + border-radius: 5px; + } + + &::-webkit-scrollbar-thumb { + background: var(--border-weak-base); + border-radius: 5px; + border: 3px solid transparent; + background-clip: padding-box; + } + + &::-webkit-scrollbar-thumb:hover { + background: var(--border-weak-base); + } + + & { + scrollbar-width: thin; + scrollbar-color: var(--border-weak-base) transparent; + } +} + +@utility badge-mask { + -webkit-mask-image: radial-gradient(circle 5px at calc(100% - 4px) 4px, transparent 5px, black 5.5px); + mask-image: radial-gradient(circle 5px at calc(100% - 4px) 4px, transparent 5px, black 5.5px); +} + @utility truncate-start { text-overflow: ellipsis; overflow: hidden;