{props.provider ? (
diff --git a/apps/web/src/components/chat/ThreadDetailsCard.tsx b/apps/web/src/components/chat/ThreadDetailsCard.tsx
index 495e758fb1476..3216c6c376c1b 100644
--- a/apps/web/src/components/chat/ThreadDetailsCard.tsx
+++ b/apps/web/src/components/chat/ThreadDetailsCard.tsx
@@ -123,7 +123,7 @@ export function ThreadDetailsCard({
const card = (
) : null}
-
+
);
}
diff --git a/apps/web/src/components/settings/SettingsScopeSentence.tsx b/apps/web/src/components/settings/SettingsScopeSentence.tsx
index 200f09a8ec5fa..9a16d12a3be5b 100644
--- a/apps/web/src/components/settings/SettingsScopeSentence.tsx
+++ b/apps/web/src/components/settings/SettingsScopeSentence.tsx
@@ -69,7 +69,7 @@ export function SettingsScopeSentence() {
onChange: scope.selectScope,
};
return (
-
+
Applying settings for
diff --git a/apps/web/src/components/settings/SettingsSidebarNav.tsx b/apps/web/src/components/settings/SettingsSidebarNav.tsx
index f096583ed3bc5..9d4642bb4785b 100644
--- a/apps/web/src/components/settings/SettingsSidebarNav.tsx
+++ b/apps/web/src/components/settings/SettingsSidebarNav.tsx
@@ -106,7 +106,7 @@ const SETTINGS_NAV_ITEMS: ReadonlyArray<{
function SettingsSectionIcon({ to }: { to: SettingsPath }) {
const Icon = SETTINGS_SECTION_ICONS[to];
- return ;
+ return ;
}
export function SettingsSidebarNav({ pathname }: { pathname: string }) {
diff --git a/apps/web/src/components/settings/settingsLayout.tsx b/apps/web/src/components/settings/settingsLayout.tsx
index 3d6abb71f3f6c..f1f363ad1f790 100644
--- a/apps/web/src/components/settings/settingsLayout.tsx
+++ b/apps/web/src/components/settings/settingsLayout.tsx
@@ -183,7 +183,9 @@ export function SettingsSearchTarget({
);
}
-export const SETTINGS_PICKER_TRIGGER_CLASSNAME = "min-w-0 max-w-none shrink-0";
+// Settings pickers reuse composer controls but match the bordered selects beside them.
+export const SETTINGS_PICKER_TRIGGER_CLASSNAME =
+ "min-w-0 max-w-none shrink-0 border-input bg-background font-normal text-foreground shadow-xs/5 hover:bg-accent/50 dark:bg-input/32";
export function PolicyTooltip({ children }: { readonly children: string }) {
return (
@@ -246,7 +248,7 @@ export function SettingsSection({
className="flex min-h-7 items-start justify-between gap-4 px-3 sm:px-4"
>
-
+
{icon}
{title}
@@ -492,9 +494,7 @@ export function SettingsRow({
{description ? (
-
- {description}
-
+ {description}
) : null}
{renderedStatus ? (
{renderedStatus}
diff --git a/apps/web/src/components/sidebar/SidebarListMarkers.tsx b/apps/web/src/components/sidebar/SidebarListMarkers.tsx
index 0bfee0f6bfa86..0cc27a5411859 100644
--- a/apps/web/src/components/sidebar/SidebarListMarkers.tsx
+++ b/apps/web/src/components/sidebar/SidebarListMarkers.tsx
@@ -113,7 +113,6 @@ export function SidebarSectionHeader(props: {
: props.marker === "snoozed-header"
? "snoozed"
: "settled";
- const snoozed = shelf === "snoozed";
return (
{props.label}
diff --git a/apps/web/src/components/sidebar/SidebarThreadRow.tsx b/apps/web/src/components/sidebar/SidebarThreadRow.tsx
index 0227096adef22..a051bd8f33ecd 100644
--- a/apps/web/src/components/sidebar/SidebarThreadRow.tsx
+++ b/apps/web/src/components/sidebar/SidebarThreadRow.tsx
@@ -892,11 +892,13 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowP
const rowSurfaceClassName = cn(
"group/sidebar-row relative w-full cursor-pointer overflow-hidden rounded-md text-left outline-none select-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
- variantAction === "unsettle" && "[&:not(:hover):not(:focus-within)_*]:text-secondary-label/70",
+ variantAction === "unsettle" &&
+ !props.isActive &&
+ "[&:not(:hover):not(:focus-within)_*]:text-secondary-label/70",
props.isActive
- ? "bg-sidebar-row-active text-sidebar-foreground"
+ ? "bg-sidebar-row-active text-sidebar-foreground light:shadow-xs light:ring-1 light:ring-inset light:ring-sidebar-border/70"
: isSelected || props.sweepAction !== null
- ? "bg-sidebar-row-selected text-sidebar-foreground"
+ ? "bg-sidebar-row-selected text-sidebar-foreground light:ring-1 light:ring-inset light:ring-sidebar-border/70"
: hasUnsentDraft
? cn(draftSurfaceClassName, "text-sidebar-foreground")
: shouldRecede
@@ -979,7 +981,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowP
? "text-foreground"
: status === "failed"
? "text-foreground/95"
- : "text-foreground/90",
+ : "text-foreground",
)
: cn(
"truncate group-focus-within/sidebar-row:text-foreground group-hover/sidebar-row:text-foreground",
@@ -1279,12 +1281,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowP
label for the wider row controls. */}
{pinIndicator}
{props.projectDisplayName ? (
-
+
{props.projectDisplayName}
) : (
@@ -1441,7 +1438,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowP
{thread.branch ? (
<>
-
+
>
@@ -1450,9 +1447,9 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowP
-
+
{props.scratchMachineLabel}
>
diff --git a/apps/web/src/components/ui/collapsible-section-header.tsx b/apps/web/src/components/ui/collapsible-section-header.tsx
index 99063f64c9e6a..0c303f4409d37 100644
--- a/apps/web/src/components/ui/collapsible-section-header.tsx
+++ b/apps/web/src/components/ui/collapsible-section-header.tsx
@@ -3,8 +3,7 @@ import { ChevronDownIcon } from "lucide-react";
import { cn } from "../../lib/utils";
const tones = {
- muted: { label: "text-sidebar-muted-foreground/60", line: "bg-sidebar-border/60" },
- info: { label: "text-blue-600 dark:text-blue-400", line: "bg-blue-500/20 dark:bg-blue-400/15" },
+ muted: { label: "text-sidebar-muted-foreground", line: "bg-sidebar-border/50" },
emphasized: { label: "text-sidebar-foreground/80", line: "bg-sidebar-foreground/25" },
accent: { label: "text-primary", line: "bg-primary/50" },
} as const;
diff --git a/apps/web/src/components/ui/menu.tsx b/apps/web/src/components/ui/menu.tsx
index 10da89dbf9713..287c871beb8b0 100644
--- a/apps/web/src/components/ui/menu.tsx
+++ b/apps/web/src/components/ui/menu.tsx
@@ -197,7 +197,7 @@ function MenuCheckboxItem({
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
- strokeWidth="2"
+ strokeWidth="1.75"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
diff --git a/apps/web/src/components/ui/select.tsx b/apps/web/src/components/ui/select.tsx
index 64cbc4f1ca42b..e28e4014d9a96 100644
--- a/apps/web/src/components/ui/select.tsx
+++ b/apps/web/src/components/ui/select.tsx
@@ -52,7 +52,7 @@ function SelectTrigger({
>
{children}
- {icon ?? }
+ {icon ?? }
);
@@ -77,7 +77,7 @@ function SelectButton({
children: (
<>
{children}
-
+
>
),
},
diff --git a/apps/web/src/index.css b/apps/web/src/index.css
index 0f1f4b2b1f871..58b600b7e1f7d 100644
--- a/apps/web/src/index.css
+++ b/apps/web/src/index.css
@@ -103,7 +103,7 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
--sidebar-control-gap: 0.5rem;
--sidebar-icon-color: color-mix(
in srgb,
- var(--contrast-sidebar-muted-foreground) 60%,
+ var(--contrast-sidebar-muted-foreground) 85%,
var(--sidebar)
);
--sidebar-row-content-inset: 0.625rem;
@@ -166,7 +166,8 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
the variables and Settings -> Appearance can override them at runtime. The
default stacks are mirrored in `appearanceFonts.ts`. */
@theme {
- --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
+ --font-sans:
+ -apple-system, BlinkMacSystemFont, "Inter Variable", "Segoe UI", system-ui, sans-serif;
--font-mono:
ui-monospace, "SF Mono", "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;
}
@@ -192,7 +193,7 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
/* The composer's elevation: a soft drop pulled in under the surface, shared
by the composer, its context strip and attached banners. */
- --shadow-composer: 0 12px 28px -18px rgb(0 0 0 / 40%);
+ --shadow-composer: 0 4px 16px -8px rgb(0 0 0 / 16%);
--shadow-composer-dark: 0 14px 32px -18px rgb(0 0 0 / 75%);
/* Overlap the lower toolbar backdrop by one pixel to cover the composer seam. */
--spacing-composer-seam: calc(var(--spacing) * 4 - 1px);
@@ -1093,7 +1094,7 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
:root {
color-scheme: light;
- --radius: 0.625rem;
+ --radius: 0.5rem;
--background: var(--color-zinc-25);
--app-chrome-background: var(--background);
--toolbar-background: var(--app-chrome-background);
@@ -1103,11 +1104,11 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
--toolbar-control-foreground: var(--foreground);
--toolbar-control-hover: var(--accent);
--surface-raised: color-mix(in srgb, var(--card) 20%, transparent);
- --foreground: var(--color-zinc-800);
+ --foreground: var(--color-zinc-900);
--card: var(--color-white);
- --card-foreground: var(--color-zinc-800);
+ --card-foreground: var(--color-zinc-900);
--popover: var(--color-white);
- --popover-foreground: var(--color-zinc-800);
+ --popover-foreground: var(--color-zinc-900);
--primary: oklch(0.488 0.217 264);
--primary-foreground: var(--color-white);
--secondary: var(--color-zinc-50);
@@ -1180,15 +1181,15 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
--secondary: --alpha(var(--color-white) / 3%);
--secondary-foreground: var(--color-neutral-100);
--muted: --alpha(var(--color-white) / 3%);
- --muted-foreground: color-mix(in srgb, var(--color-neutral-500) 90%, var(--color-white));
+ --muted-foreground: var(--color-neutral-400);
--accent: --alpha(var(--color-white) / 4%);
--accent-foreground: var(--color-neutral-100);
--error: color-mix(in srgb, var(--color-red-500) 90%, var(--color-white));
--error-foreground: var(--color-red-400);
--tool-error-icon: #fca5a5;
--error-surface: color-mix(in srgb, var(--error) 16%, transparent);
- --border: --alpha(var(--color-white) / 6%);
- --input: --alpha(var(--color-white) / 8%);
+ --border: --alpha(var(--color-white) / 8%);
+ --input: --alpha(var(--color-white) / 11%);
--info-foreground: var(--color-blue-400);
--guest-foreground: var(--color-fuchsia-300);
--success-foreground: var(--color-emerald-400);
@@ -1212,9 +1213,9 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
surfaces. */
[data-app-sidebar] {
--background: var(--color-zinc-25);
- --foreground: var(--color-zinc-800);
+ --foreground: var(--color-zinc-900);
--card: var(--color-white);
- --card-foreground: var(--color-zinc-800);
+ --card-foreground: var(--color-zinc-900);
--accent: var(--color-zinc-100);
--accent-foreground: var(--color-zinc-900);
--muted: var(--color-zinc-50);
@@ -1222,7 +1223,7 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
--border: var(--color-zinc-200);
--input: var(--color-zinc-300);
--sidebar: var(--color-zinc-50);
- --sidebar-foreground: var(--color-zinc-800);
+ --sidebar-foreground: var(--color-zinc-900);
--sidebar-muted-foreground: var(--color-zinc-500);
--sidebar-control-surface: var(--color-zinc-100);
--sidebar-row-hover: var(--color-zinc-25);
@@ -1658,6 +1659,12 @@ body {
padding: 0;
}
+/* Lighter default icon stroke. Zero specificity, so stroke-* classes still win
+ over it while it still beats lucide's stroke-width="2" attribute. */
+:where(svg.lucide[stroke-width="2"]) {
+ stroke-width: 1.75;
+}
+
html,
body {
min-height: calc(100svh + env(safe-area-inset-top));
@@ -2048,21 +2055,25 @@ code {
}
.chat-markdown :not(pre) > code {
- border: 1px solid var(--contrast-border);
- border-radius: 0.375rem;
+ border: 1px solid transparent;
+ border-radius: 0.25rem;
box-decoration-break: clone;
-webkit-box-decoration-break: clone;
- background: var(--muted);
- padding: 0.1rem 0.35rem;
+ background: color-mix(in srgb, var(--contrast-foreground) 10%, transparent);
+ padding: 0.1em 0.35em;
color: var(--contrast-foreground);
- font-size: 0.75rem;
+ font-size: 0.85em;
+}
+
+.chat-markdown strong {
+ font-weight: 600;
}
.chat-markdown pre {
max-width: 100%;
overflow-x: auto;
border: 1px solid var(--contrast-border);
- border-radius: 0.75rem;
+ border-radius: 0.5rem;
background: var(--muted);
padding: 0.8rem 0.9rem;
scrollbar-width: thin;
diff --git a/apps/web/src/main.tsx b/apps/web/src/main.tsx
index 3fe1f61bd728b..48a1f7a2f1644 100644
--- a/apps/web/src/main.tsx
+++ b/apps/web/src/main.tsx
@@ -2,6 +2,7 @@ import React from "react";
import ReactDOM from "react-dom/client";
import { createHashHistory, createBrowserHistory } from "@tanstack/react-router";
+import "@fontsource-variable/inter";
import "./index.css";
import { prepareProviderAuthDelivery } from "./providerAuthDelivery";
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2cc59745d095e..dbced6539153c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1012,6 +1012,9 @@ importers:
'@effect/atom-react':
specifier: 4.0.5
version: 4.0.5(effect@4.0.5)(react@19.3.0)(scheduler@0.28.0)
+ '@fontsource-variable/inter':
+ specifier: ^5.3.0
+ version: 5.3.0
'@formkit/auto-animate':
specifier: ^0.9.0
version: 0.9.0
@@ -4183,6 +4186,9 @@ packages:
'@floating-ui/utils@0.2.11':
resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==}
+ '@fontsource-variable/inter@5.3.0':
+ resolution: {integrity: sha512-OupL48va4JNofb97w6NYeF9S7W/kHNKM0Er8Dem5nqi4jeOLrVJDoE8tZEpnMJmtkvNbB1EIPPwHcdkF6b1oUA==}
+
'@formkit/auto-animate@0.9.0':
resolution: {integrity: sha512-VhP4zEAacXS3dfTpJpJ88QdLqMTcabMg0jwpOSxZ/VzfQVfl3GkZSCZThhGC5uhq/TxPHPzW0dzr4H9Bb1OgKA==}
@@ -14473,6 +14479,8 @@ snapshots:
'@floating-ui/utils@0.2.11': {}
+ '@fontsource-variable/inter@5.3.0': {}
+
'@formkit/auto-animate@0.9.0': {}
'@hono/node-server@1.19.17(hono@4.13.7)':